我曾尝试使用SVM分类器对大约10万个样本的数据进行训练,但我发现它非常缓慢,即使过了两个小时也没有响应。当数据集大约有1k个样本时,我可以立即得到结果。我还尝试了SGDClassifier和朴素贝叶斯,这两种方法都非常快速,我可以在几分钟内得到结果。您能解释一下这种现象吗?
我曾尝试使用SVM分类器对大约10万个样本的数据进行训练,但我发现它非常缓慢,即使过了两个小时也没有响应。当数据集大约有1k个样本时,我可以立即得到结果。我还尝试了SGDClassifier和朴素贝叶斯,这两种方法都非常快速,我可以在几分钟内得到结果。您能解释一下这种现象吗?
sklearn中SVC默认使用非线性核进行SVM训练,其复杂度大约为O(n_samples^2 * n_features)
由sklearn开发人员之一给出的这个近似值的问题链接。 这适用于libsvm内部使用的SMO算法,该算法是解决此类问题的sklearn核心求解器。
1k = 1000^2 = 1.000.000 steps = Time X
100k = 100.000^2 = 10.000.000.000 steps = Time X * 10000 !!!
这只是一个近似值,可能会更糟或更好(例如,设置缓存大小; 把内存与速度之间进行权衡)!
由于scikit-learn在幕后为我们做了很多好事,所以情况也可能更加复杂。上述内容适用于经典的两类支持向量机。如果你正在尝试学习一些多类数据,则scikit-learn将自动使用OneVsRest或OneVsAll方法来完成此任务(因为核心SVM算法不支持此功能)。请阅读scikit-learn文档以了解此部分。
同样的警告适用于生成概率:SVM不会自然地为最终预测产生概率。因此,为了使用这些概率(通过参数激活),scikit-learn使用了一个称为Platt scaling的重型交叉验证过程,这也需要很长时间!
由于sklearn有最好的文档之一,因此通常在这些文档中有很好的部分来解释这样的问题(link):
pip install scikit-learn-intelex
from sklearnex import patch_sklearn
patch_sklearn()
现在运行程序,速度比以前快得多。
您可以从以下链接了解更多信息: https://intel.github.io/scikit-learn-intelex/