在单一样本上提高支持向量机(SVC)预测性能

3
我有大型的SVC模型(约50MB的cPickles)用于文本分类,我正在尝试各种方法将它们用于生产环境。对一批文档进行分类效果非常好(使用predict和predict_proba每分钟可处理约1k个文档)。然而,对单个文档进行预测则不同,正如this question中的评论所述:
“你是在批量进行预测吗?不幸的是,SVC.predict方法会产生很多开销,因为它必须重构类似于训练算法产生的LibSVM数据结构,浅拷贝支持向量,并将测试样本转换为可能与NumPy / SciPy格式不同的LibSVM格式。因此,对单个样本的预测注定会很慢。” - larsmans 我已经将SVC模型作为Flask Web应用程序提供,因此一部分开销已经消失了(反序列化),但是单个文档的预测时间仍然较长(0.25秒)。我查看了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))

1
不要使用SVC进行文本分类,这样做没有意义。 - Fred Foo
嗨,我明白你的意思,但我应该指出这是多类情感分类(非常不同的类大小)。目前,我正在尝试达到最高的准确性。 到目前为止,使用RBF内核的SVC优于其他所有分类器,尽管差距很小(例如,SVC 0.898,PassiveAggressiveClassifier 0.868,MultinomialNB 0.837)。然而,SVC在最小的类别中远远超过竞争对手(例如,F1 SVC 0.84,PAC 0.76,MNB 0.68)。 如果SVC在单个文档上速度稍快一些,我将没有理由不使用它来处理我的当前数据。 - emiguevara
2个回答

3

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

自定义服务器

这不是“热身”任何东西的问题。简单来说 - 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 缩放,但这仍然是可能的。

非常有帮助,谢谢。我认为批处理现在是解决方案,但我一有时间就会尝试分类 :-) - emiguevara

1

你不能提前构造LibSVM数据结构。 当收到对文档进行分类的请求时,获取文档的文本,将其转换为向量,然后再转换为LibSVM格式,以便获得决策。

LinearSVC应该比使用线性核的SVC更快,因为它使用liblinear。如果这样做不会降低性能,可以尝试使用其他分类器。


当然,您无法避免处理请求中获得的一个文档。但是,根据样本数量的不同,性能差异非常大,以至于我仍然想知道是否可以提前做些什么。例如,在每个文档上调用predictpredict_proba: 100个文档5.6157秒, 10个文档0.9705秒, 2个文档0.4969秒, 1个文档0.4551秒 - emiguevara
更改分类器不是问题的一部分。 - emiguevara
LinearSVC只是SVC的优化版本,因此您并没有真正改变分类器。https://dev59.com/oWgu5IYBdhLWcg3wMkQm - mbatchkarov
你是否了解LinearSVCSVC(即非线性核)选项之间的区别?我再说一遍:这不是我的问题的一部分,不需要建议更改分类器。 - emiguevara

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接