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