Python 提高单样本SVC预测性能

Python 提高单样本SVC预测性能,python,svm,scikit-learn,svc,Python,Svm,Scikit Learn,Svc,我有用于文本分类的大型ish SVC模型(~50Mb cPickles),我正在尝试各种方法在生产环境中使用它们。对成批文档进行分类效果非常好(使用predict和predict\u proba,每分钟大约1k个文档)。 但是,对单个文档的预测是另一回事,如以下评论中所述: 你在分批做预测吗?不幸的是,SVC.predict方法会产生大量开销,因为它必须重建一个类似于训练算法生成的LibSVM数据结构,在支持向量中进行浅拷贝,并将测试样本转换为可能不同于NumPy/SciPy格式的LibSVM格

我有用于文本分类的大型ish SVC模型(~50Mb cPickles),我正在尝试各种方法在生产环境中使用它们。对成批文档进行分类效果非常好(使用
predict
predict\u proba
,每分钟大约1k个文档)。 但是,对单个文档的预测是另一回事,如以下评论中所述:

你在分批做预测吗?不幸的是,SVC.predict方法会产生大量开销,因为它必须重建一个类似于训练算法生成的LibSVM数据结构,在支持向量中进行浅拷贝,并将测试样本转换为可能不同于NumPy/SciPy格式的LibSVM格式。因此,对单个样本的预测必然是缓慢的

我已经将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数据结构。当对文档进行分类的请求到达时,您将获得文档的文本,从if和only中生成一个向量,然后转换为LibSVM格式,这样您就可以做出决定


LinearSVC
应该比具有线性内核的
SVC
快得多,因为它使用
liblinear
。如果不太降低性能,您可以尝试使用不同的分类器。

我可以看到三种可能的解决方案

自定义服务器 这不是“热身”的问题。简单-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发送任何内容。这可以将速度提高一个数量级。显然,检索概率更为复杂,因为它需要Platt的缩放,但仍然是可能的。

当然,您无法避免处理您请求的一个文档。然而,性能上的差异取决于样本数量,这是如此之大,以至于我仍然怀疑是否可以提前做些什么。例如,对每个文档调用
predict
predict_proba
:100个文档5.6157s、10个文档0.9705s、2个文档0.4969s、1个文档0.4551sChanging分类器不是问题的一部分。
LinearSVC
只是
SVC
的优化版本,因此您并没有真正更改分类器。您是否意识到
LinearSVC
SVC
选项之间的差异(阅读:非线性内核)???我重复一遍:这不是我问题的一部分,不需要建议更改分类器。非常有用,谢谢。我认为批次将是目前的解决方案,但我会尽快尝试分类:-)不要使用
SVC
进行文本分类,这不值得。嗨,我明白你的意思,但我应该指定它是一个多类情感分类(非常不同的类大小)。目前,我正在努力达到最高的准确度。到目前为止,带有RBF核的SVC比其他任何分类器都要好,尽管差距很小(例如SVC 0.898、被动梯度分类器0.868、多项式NB 0.837)。然而,SVC在很大程度上优于最小级别的竞争对手(例如F1 SVC 0.84、PAC 0.76、MNB 0.68)。如果SVC在使用单个文档时速度稍微快一点,我看不出有任何理由不在当前数据中使用它。