34

我正在用 Python 构建一些预测模型,并且一直在使用 scikits learn 的 SVM 实现。它真的很棒,易于使用且速度相对较快。

不幸的是,我开始受到运行时的限制。我在大约 4 - 5000 个具有 650 个特征的完整数据集上运行 rbf SVM。每次运行大约需要一分钟。但是使用 5 折交叉验证 + 网格搜索(使用从粗到细的搜索),这对我手头的任务来说有点不可行。所以一般来说,人们对可以在 Python 中使用的最快的 SVM 实现有什么建议吗?那,或者有什么方法可以加快我的建模速度?

我听说过 LIBSVM 的 GPU 实现,它似乎可以工作。我不知道任何其他可在 Python 中使用的 GPU SVM 实现,但它肯定会对其他人开放。另外,使用 GPU 会显着增加运行时间吗?

我还听说有一些方法可以通过在 scikits 中使用线性 SVM + 特征图来逼近 rbf SVM。不确定人们对这种方法的看法。同样,任何使用这种方法的人,它是否显着增加了运行时间?

欢迎所有提高程序速度的想法。

4

10 回答 10

29

我所知道的最具可扩展性的内核 SVM 实现是LaSVM。如果您知道Cythonctypescffi ,它是用 C 语言编写的,因此可以在 Python 中进行包装。或者,您可以从命令行使用它。您可以使用实用程序sklearn.datasets将数据从NumPy或 CSR 格式加载到 LaSVM 可以用作训练/测试集的 svmlight 格式文件。

于 2012-02-15T20:33:39.303 回答
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 不是问题。

于 2012-02-15T20:29:17.417 回答
8

首先,根据 scikit-learn 的基准(这里),scikit-learn 已经是最快的 SVM 包之一。因此,您可能需要考虑其他加快训练速度的方法。

正如 bavaza 所建议的,您可以尝试对训练过程进行多线程处理。如果您使用的是 Scikit-learn 的 GridSearchCV 类,您可以轻松地将 n_jobs 参数设置为大于默认值 1 以并行执行训练,但代价是使用更多内存。你可以在这里找到它的文档一个如何使用这个类的例子可以在这里找到

或者,您可以在 此处查看 Shogun 机器学习库

Shogun 是为大规模机器学习而设计的,它带有许多常见 svm 包的包装器,它是用 C/C++ 实现的,并带有 python 绑定。根据上面 Scikit-learn 的基准,它的速度与 scikit-learn 相当。在其他任务上(除了他们演示的任务),它可能会更快,因此值得一试。

最后,您可以尝试执行降维,例如使用 PCA 或随机 PCA 来降低特征向量的维度。这将加快培训过程。可以在以下 2 个链接中找到各个类的文档:PCARandomized PCA。您可以在 Scikit-learn 的示例部分找到有关如何使用它们的示例。

于 2012-09-27T03:30:39.517 回答
3

如果您只对使用 RBF 内核(或任何其他二次内核)感兴趣,那么我建议在MATLABOctave上使用 LIBSVM 。我在大约 6 秒内训练了一个包含 7000 个观测值和 500 个特征的模型。

诀窍是使用 LIBSVM 提供的预计算内核,并使用一些矩阵代数一步计算内核,而不是重复两次数据。与使用 LIBSVM 自己的 RBF 内核相比,构建内核大约需要两秒钟。我认为您可以使用NumPy在 Python 中这样做,但我不确定,因为我没有尝试过。

于 2012-10-25T16:03:15.540 回答
2

无需过多比较 SVM 库,我认为您所描述的任务(交叉验证)可以受益于真正的多线程(即并行运行多个 CPU)。如果您使用的是CPython ,由于GIL,它不会利用您的(可能)多核机器。

您可以尝试其他没有此限制的 Python 实现。如果您愿意使用 .NET,请参阅PyPyIronPython 。

于 2012-02-15T18:58:22.123 回答
1

试试svm_light

它是康奈尔大学臭名昭著的 Thorsten Joachims 的一个极快的 C 实现,具有良好的 Python 绑定,您可以使用pip install pysvmlight.

于 2013-04-29T18:58:13.677 回答
1

我会考虑使用随机森林来减少您输入的特征数量。

ExtraTreesRegressor 和 ExtraTreesClassifier 有一个选项可以生成特征重要性。然后,您可以使用此信息将功能子集输入到您的 SVM 中。

于 2013-05-31T04:52:42.200 回答
1

如果您的问题存在于两个类中,那么使用 scikit-learn 包装基于 CUDA 的 SVM 很有用:

https://github.com/niitsuma/gpusvm/tree/master/python

于 2015-04-28T12:20:09.427 回答
1

我认为您可以尝试使用 GPU 的ThunderSVM 。

于 2020-07-22T10:05:29.913 回答
0

我建议查看 Scikit-Learn 的随机梯度下降实现。默认的铰链损失是线性 SVM。我发现它的速度非常快。

于 2014-11-12T23:32:59.630 回答