【问题标题】:Fastest SVM implementation usable in Python [closed]可在 Python 中使用的最快 SVM 实现 [关闭]
【发布时间】:2012-03-07 03:31:12
【问题描述】:

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

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

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

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

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

【问题讨论】:

    标签: python machine-learning gpu svm scikit-learn


    【解决方案1】:

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

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

    【讨论】:

    • 谢谢 bavaza 我会看看它。假设我确实利用了我的多核计算机,还有其他关于加快程序速度的建议吗?无论如何,我正在想办法跨多个线程进行交叉验证。但是,我认为我仍然需要加快速度。
    • @bavaza ,我多年来一直在多核中运行 Python,它运行良好。请研究标准 CPython 的多处理库。
    • @V3ss0n,谢谢。看起来像一个不错的库。由于它使用进程而不是线程,您是否熟悉任何上下文切换惩罚(例如,在使用大型工作池时)?
    • PyPy 也有一个 GIL(即使他们有一个实验项目来实现替代的内存管理策略);正如一些人所说,要避免 GIL,最简单的方法仍然是多处理而不是使用线程。我真的不确定使用 IronPython 是否会提供更好的性能(所有 .NET 开销)
    【解决方案2】:

    或者,您可以对 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 不是问题。

    【讨论】:

      【解决方案3】:

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

      【讨论】:

      • 谢谢 ogrisel。我会看看这个。绝对看起来很有趣。 sklearn可以导出成svm light格式吗?那肯定会有用。不幸的是,为了回应您之前的回答,我正在处理时间序列,因此随机抽样 + 吐出训练/测试变得相当复杂。不确定训练我的模型的子采样是否会这么简单。谢谢!
      • Sorry quick addendum ogrisel,你知道sklearn中有哪些实用函数可以导出为SVM light格式吗?
      • @thomas 如果您的样本不是(松散地)iid,那么具有 RBF 等通用内核的 SVM 很可能不会产生良好的结果。如果您有时间序列数据(在连续测量之间具有时间依赖性),您应该提取更高级别的特征(例如滑动窗口上的卷积或STFT)或预先计算时间序列专用内核。
      • 嗯...有趣。你介意扩大你所说的吗?我听说过相关数据会导致交叉验证过程出现问题,但并非专门针对 rbf SVM。会出现什么问题?以及关于提取更高级别特征意味着什么的任何参考或指针?不知道评论部分是否是最好的地方,但很想听到更多关于这个的信息。谢谢。
      • 如果样本间的时间依赖性阻止您进行任意的子采样和交叉验证,我看不出 SVM RBF 模型将如何学习一般的东西:该模型使其一次对每个单独的样本进行预测,独立于过去的预测(无记忆),因此如果您希望输入特征足够泛化以对以前看不见的数据做出有趣的预测,则输入特征应该编码某种高级“上下文”。跨度>
      【解决方案4】:

      首先,根据 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 来减少特征向量的维度。这将加快培训过程。可以在以下 2 个链接中找到各个类的文档:PCA、Randomized PCA。您可以在 Scikit-learn 的示例部分找到有关如何使用它们的示例。

      【讨论】:

        【解决方案5】:

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

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

        【讨论】:

        • 一般来说 LibSVM 是一个不错的成熟库,但我认为它不是最快的,而且 7000 x 500 是一个很小的测试问题。
        【解决方案6】:

        试试svm_light!

        它是来自infamous Thorsten Joachims at Cornell 的快速 C 实现,具有良好的 Python 绑定,您可以使用 pip install pysvmlight 安装它。

        【讨论】:

          【解决方案7】:

          我会考虑使用random forest 来减少您输入的特征数量。

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

          【讨论】:

            【解决方案8】:

            我建议查看 Scikit-Learn 的 Stochastic Gradient Descent 实现。默认的铰链损失是线性 SVM。我发现它的速度非常快。

            【讨论】:

              【解决方案9】:

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

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

              【讨论】:

                【解决方案10】:

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

                【讨论】:

                  猜你喜欢
                  • 2018-08-21
                  • 1970-01-01
                  • 1970-01-01
                  • 2012-02-28
                  • 2013-10-05
                  • 1970-01-01
                  • 1970-01-01
                  • 2012-01-31
                  • 2020-12-07
                  相关资源
                  最近更新 更多