我尝试使用SVM分类器来训练大约100k样本的数据,但我发现它非常慢,即使在两小时后也没有响应。当数据集有大约1k个样本时,我可以立即得到结果。我也尝试过SGDClassifier和naïvebayes,速度非常快,我在几分钟内得到了结果。你能解释一下这个现象吗?
答案 0 :(得分:33)
使用非线性内核的SVM训练(默认情况下是sklearn的SVC)的复杂性近似为:O(n_samples^2 * n_features)
link to some question with this approximation given by one of sklearn's devs。这适用于SMO-algorithm中使用的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 !!!
这只是一个近似值,甚至可能更糟或更差(例如设置缓存大小;权衡内存以获得速度增益)!
情况也可能要复杂得多,因为scikit-learn在酒吧后面为我们做的所有好事。以上内容适用于经典的2级SVM。如果你有机会尝试学习一些多类数据; scikit-learn将自动使用OneVsRest或OneVsAll方法来执行此操作(因为核心SVM算法不支持此操作)。阅读scikit-learnns docs以了解这一部分。
同样的警告适用于生成概率:SVM不会自然地产生最终预测的概率。因此,要使用这些(通过参数激活),scikit-learn使用称为Platt scaling的繁重交叉验证程序,这将花费大量时间!
因为sklearn拥有最好的文档之一,所以在这些文档中通常有很好的部分来解释类似的内容(link):