scikit-learn SVM.SVC()非常慢

C. *_*ary 23 python svm scikit-learn

我尝试使用SVM分类器训练大约100k样本的数据,但我发现它非常慢,即使两小时后也没有响应.当数据集有大约1k个样本时,我可以立即得到结果.我也尝试过SGDClassifier和naïvebayes,速度非常快,我在几分钟内得到了结果.你能解释一下这种现象吗?

sas*_*cha 36

关于SVM学习的一般评论

非线性内核的SVM训练(在sklearn的SVC中是默认的)近似于复杂性:O(n_samples^2 * n_features) 通过sklearn的开发者给出的这种近似值链接到某个问题.这适用于libsvm中使用的SMO算法,libsvm是sklearn中针对此类问题的核心求解器.

当没有使用内核并且使用sklearn.svm.LinearSVC(基于liblinear)或sklearn.linear_model.SGDClassifier时,这会发生很大变化.

所以我们可以做一些数学计算来估算1k到100k样本之间的时差:

1k = 1000^2 = 1.000.000 steps = Time X
100k = 100.000^2 = 10.000.000.000 steps = Time X * 10000 !!!
Run Code Online (Sandbox Code Playgroud)

这只是一个近似值,甚至可能更糟或更差(例如设置缓存大小;权衡内存以获得速度增益)!

Scikit-学习具体的评论

这种情况也可能要复杂得多,因为scikit-learn正在为我们在酒吧后面做的所有好事.以上内容适用于经典的2级SVM.如果你有机会尝试学习一些多类数据; scikit-learn将自动使用OneVsRest或OneVsAll方法来执行此操作(因为核心SVM算法不支持此操作).阅读scikit-learnns文档以了解这一部分.

同样的警告适用于生成概率:SVM不会自然地产生最终预测的概率.因此,要使用这些(通过参数激活)scikit-learn使用称为Platt缩放的重交叉验证程序,这将花费大量时间!

Scikit-学习文档

因为sklearn拥有最好的文档之一,所以在这些文档中经常有一个很好的部分来解释类似的东西(链接):

在此输入图像描述

  • @GoingMyWay 我认为这是对答案的误解。带核的 SVM 算法的时间复杂度是一个普遍事实,与您使用的包无关。它是使用 SVM 模型所固有的,无论是来自 sklearn 还是 R 中的其他模型。除非您知道一种用于优化 SVM 参数的算法,该算法可以神奇地改进这一点,并且该算法尚未在 sklearn 中实现,否则您将不会获得任何收益使用另一个包。关于 SVC,再次强调,“one-vs-rest”或替代方案本质上是使用具有多个类的 SVM 所需要做的事情。 (3认同)
  • 因此,对于拥有大量数据的用户而言,scikit-learn不是最佳选择。我也遇到了这个问题。80万个示例,这花了我2个小时。 (2认同)
  • @GoingMyWay,那么是否存在更快的替代方案? (2认同)

小智 5

如果您使用的是英特尔CPU,那么英特尔已经提供了解决方案。英特尔 Scikit-learn 扩展为您提供了一种加速现有 scikit-learn 代码的方法。加速是通过修补实现的:用扩展提供的优化版本替换现有的 scikit-learn 算法。您应该按照以下步骤操作:

首先安装 sklearn 的 intelex 包

pip install scikit-learn-intelex
Run Code Online (Sandbox Code Playgroud)

现在只需在程序顶部添加以下行

from sklearnex import patch_sklearn 

patch_sklearn()
Run Code Online (Sandbox Code Playgroud)

现在运行程序会比以前快很多。

您可以通过以下链接了解更多信息: https://intel.github.io/scikit-learn-intelex/