我正在用Python构建一些预测模型,并且一直在使用scikits learn的SVM实现。它真的很棒,易于使用,而且速度相对较快。
不幸的是,我开始受到运行时的限制。我在一个大约4 - 5000的完整数据集上运行一个rbf SVM,具有650个功能。每次运行大约需要一分钟。但是通过5倍交叉验证+网格搜索(使用粗到细搜索),对于我手头的任务来说,它有点不可行。那么一般来说,人们对可以在Python中使用的最快SVM实现方面有什么建议吗?那或者任何加速我建模的方法?
我听说过LIBSVM的GPU实现,看起来它可以工作。我不知道Python中可用的任何其他GPU SVM实现,但它肯定会对其他人开放。另外,使用GPU会显着增加运行时间吗?
我还听说有一些方法可以通过在scikits中使用线性SVM +特征映射来近似rbf SVM。不确定人们对这种方法的看法。同样,使用这种方法的任何人都是运行时间的显着增加吗?
欢迎所有提高计划速度的想法。
答案 0 :(得分:29)
我所知道的最具可伸缩性的内核SVM实现是LaSVM。如果你知道Cython,ctypes或cffi,它是用C编写的,因此可以用Python包装。或者,您可以从命令行使用它。您可以使用sklearn.datasets
中的实用程序将数据从NumPy或CSR格式转换为svmlight格式的文件,LaSVM可以将其用作培训/测试集。
答案 1 :(得分:23)
或者,您可以在1000个随机样本而不是完整数据集上运行网格搜索:
>>> from sklearn.cross_validation import ShuffleSplit
>>> cv = ShuffleSplit(3, test_fraction=0.2, train_fraction=0.2, random_state=0)
>>> gs = GridSeachCV(clf, params_grid, cv=cv, n_jobs=-1, verbose=2)
>>> gs.fit(X, y)
5000个样本的最佳参数很可能非常接近1000个样本的最佳参数。这是开始粗网格搜索的好方法。
n_jobs=-1
可以使用所有CPU并行运行各个CV。它正在使用多处理,因此python GIL不是问题。
答案 2 :(得分:8)
首先,根据scikit-learn的基准测试(here),scikit-learn已经是速度最快但速度最快的SVM软件包之一。因此,您可能需要考虑其他加速培训的方法。
正如bavaza所建议的,您可以尝试多线程培训过程。如果您使用的是Scikit-learn的GridSearchCV类,则可以轻松地将n_jobs参数设置为大于默认值1,以便以使用更多内存为代价并行执行训练。 您可以找到它的文档here可以找到如何使用该类的示例here
或者,您可以查看Shogun机器学习库 here
Shogun专为大规模机器学习而设计,包含许多常见的svm包,它是用C / C ++实现的,带有python绑定。根据上面的Scikit-learn的基准测试,它的速度可与scikit-learn相媲美。在其他任务(除了他们演示的任务)之外,它可能更快,因此值得一试。
最后,您可以尝试执行降维,例如使用PCA或随机PCA来减少特征向量的维数。这将加快培训进程。可以在以下两个链接中找到相应课程的文档:PCA,Randomized PCA。您可以在Scikit-learn的示例部分找到有关如何使用它们的示例。
答案 3 :(得分:4)
如果您只对使用RBF内核(或任何其他二次内核)感兴趣,那么我建议在MATLAB或Octave上使用LIBSVM。我在大约6秒钟内训练了7000个观测模型和500个特征。
诀窍是使用LIBSVM提供的预先计算的内核,并使用一些矩阵代数一步计算内核,而不是两次删除数据。内核需要大约两秒钟来构建,而不是使用LIBSVM自己的RBF内核。我认为你可以使用NumPy在Python中这样做,但我不确定,因为我没有尝试过。
答案 4 :(得分:2)
在没有太多比较SVM库的情况下,我认为您描述的任务(交叉验证)可以从真正的多线程(即并行运行多个CPU)中受益。如果您使用CPython,由于GIL,它不会利用您的(可能)多核机器。
您可以尝试其他没有此限制的Python实现。如果您愿意使用.NET,请参阅PyPy或IronPython。
答案 5 :(得分:1)
试试svm_light!
这是来自infamous Thorsten Joachims at Cornell的快速C实现,具有良好的Python绑定,您可以使用pip install pysvmlight
进行安装。
答案 6 :(得分:1)
如果您的问题在两个类中,那么使用scikit-learn包装基于CUDA的SVM非常有用:
答案 7 :(得分:1)
我认为您可以尝试使用GPU的ThunderSVM。
答案 8 :(得分:0)
我会考虑使用random forest来减少您输入的功能数量。
ExtraTreesRegressor和ExtraTreesClassifier有一个选项可以生成要素重要性。然后,您可以使用此信息将特征的子集输入SVM。
答案 9 :(得分:0)
我建议查看Scikit-Learn的Stochastic Gradient Descent实施。默认铰链损耗是线性SVM。我发现它非常快。