我有用于文本分类的大型SVC模型(〜50Mb cPickles),并且我正在尝试各种在生产环境中使用它们的方法。对一批文档进行分类非常有效(使用predict
和,每分钟约1k个文档predict_proba
)。但是,对单个文档的预测是另一回事,对此问题的评论中对此进行了解释:
您是否正在分批进行预测?不幸的是,SVC.predict方法会产生大量开销,因为它必须重建与训练算法生成的LibSVM数据结构类似的LibSVM数据结构,在支持向量中进行浅表复制,并将测试样本转换为LibSVM格式,可能与NumPy / SciPy格式不同。因此,对单个样本的预测必然很慢。–拉尔曼斯
我已经将SVC模型用作Flask Web应用程序了,所以一部分开销已经消失(取消分配),但是单个文档的预测时间仍然偏高(0.25s)。我已经看过方法中的代码,predict
但无法弄清楚是否有一种方法可以“预热”它们,并在服务器启动时提前重建LibSVM数据结构...有什么想法吗?
def predict(self, X):
"""Perform classification on samples in X.
For an one-class model, +1 or -1 is returned.
Parameters
----------
X : {array-like, sparse matrix}, shape = [n_samples, n_features]
Returns
-------
y_pred : array, shape = [n_samples]
Class labels for samples in X.
"""
y = super(BaseSVC, self).predict(X)
return self.classes_.take(y.astype(np.int))
我可以看到三种可能的解决方案。
这不是“预热”任何东西的问题。简单来说-libSVM是C库,您需要将数据打包/解压缩为正确的格式。此过程在整个矩阵上比在单独的每一行上都更有效。克服此问题的唯一方法是在生产环境和libSVM之间编写更有效的包装器(您可以编写基于libsvm的服务器,该服务器将在您的服务中使用某种共享内存)。不幸的是,这是自定义问题,可以通过现有实现解决。
诸如缓冲查询之类的天真方法是一种选择(如果它是具有成千上万个查询的“高性能”系统,则可以简单地将它们存储在N个元素批次中,然后以此类包的形式发送给libSVM)。
最后,使用SVM进行分类确实是一项简单的任务。您不需要libSVM来执行分类。仅培训是一个复杂的问题。一旦获得所有支持向量(SV_i),内核(K),拉格朗日乘数(alpha_i)和截距项(b),就可以使用以下方法进行分类:
cl(x) = sgn( SUM_i y_i alpha_i K(SV_i, x) + b)
您可以直接在您的应用程序中编写此操作的代码,而无需实际打包/解包/发送任何内容到libsvm。这可以使速度加快一个数量级。显然-检索概率更加复杂,因为它需要进行普拉特定标,但是仍然可行。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句