SVM 实现,scikit learn 减少运行时间,最快的 svm

Posted

技术标签:

【中文标题】SVM 实现,scikit learn 减少运行时间,最快的 svm【英文标题】:SVM implmentation, scikits learn reducing runtime, fastest svm 【发布时间】:2012-02-28 02:56:24 【问题描述】:

我正在与 scikit-learn 合作,使用 SVM 构建一些预测模型。我有一个包含大约 5000 个示例和大约 700 个特征的数据集。我在训练集上使用 18x17 网格搜索进行 5 折交叉验证,然后使用测试集的最佳参数。运行时间比我预期的要长得多,我注意到以下几点:

1) 一些单独的 SVM 训练迭代似乎只需要一分钟,而另一些则可能需要长达 15 分钟。这是否预期具有不同的数据和参数(C 和 gamma,我使用的是rbf 内核)?

2) 我正在尝试在 Windows 上使用 64 位 python 来利用额外的内存,但是我的所有 python 进程似乎在我的任务管理器中都达到了 1 gig,我不知道这是否有什么需要使用运行时。

3) 我之前使用的是 32 位并在大约相同的数据集上运行,我记得(虽然我没有保存结果)它要快得多。我为 64 位 Windows 使用了第三方构建的 scikit-learn,所以我不知道在 32 位 python 上尝试这个是否更好? (来源http://www.lfd.uci.edu/~gohlke/pythonlibs/)

任何关于如何减少运行时间的建议将不胜感激。我想减少我的网格搜索的搜索空间会有所帮助,但由于我甚至不确定最佳参数的范围,我想尽可能地保持它的大小。如果还有更快的 SVM 实现,请告诉我,我可能会尝试。

附录:我回去尝试再次运行 32 位版本。由于某种原因,它要快得多。 64位版本用了16个小时,大概花了3个小时。为什么会有这样的差异?

【问题讨论】:

【参考方案1】:

1) 这是意料之中的:小 gamma 和小的正则化会选择更多的支持向量,因此模型会更复杂且拟合时间更长。

2) 有一个cache_size 参数将被传递给底层的 libsvm 库。但是,根据您的数据,libsvm 可能会也可能不会使用所有可用的缓存。

3) 不知道。如果您在两个平台上进行了更多定时实验,请在项目邮件列表中报告您的发现。这可能值得进一步调查。

首先检查您是否对特征进行了归一化(例如,如果您的数据是密集的 numpy 数组,则通过方差删除均值和尺度特征)。对于稀疏数据,只需缩放特征(例如,对文本数据使用 TF-IDF 转换)。请参阅文档的preprocessing section。

然后您应该从一个粗略的网格(具有较大的对数步长)开始,比如说一个 3x3 网格,然后通过在该区域上重新运行一个 3x3 网格来关注感兴趣的区域。一般来说,C x gamma SVM 参数网格是quite smooth。

【讨论】:

感谢奥格里塞尔的回答。他们很有意义。我也不确定 32 位与 64 位的问题,但如果有机会,我会尝试多做几次定时运行。我的数据经过预处理(标准化为 0-1),我将 scikits 的 cache_size 增加到 4000(可能过度杀伤)。我肯定会考虑修改我的代码,使其从粗网格变为更小的区域,这肯定有助于加快我的代码速度。再次感谢。 @OGrisel,一般的粗然后细网格搜索器怎么样? 我想还有一个问题,如果你在做交叉验证+网格搜索,你怎么能使用粗略然后精细的网格搜索?当您尝试对多次交叉验证运行进行平均或任何操作时,当您使用粗略然后精细时,搜索空间将不匹配。我确定有一个我不知道/失踪的好方法。 是的,我理解,但是在交叉验证时,您将运行五次网格搜索。对于每个交叉验证,更精细的 5x5 搜索空间可能会有所不同。如何对交叉验证运行的拟合进行平均以找到最佳测试集参数 “可能不同”:那就不要那样做。最初的说 5x5 粗网格 -> ncross不同的 C, gamma -> one 3x3 subgrid -> one 说 5x5 更细的网格 ...【参考方案2】:

如果您负担得起,请考虑使用 LinearSVC:基于 libsvm 的 SVC 的训练复杂度介于 O(n_features * n_samples^2)O(n_features * n_samples^3) 之间,而 LinearSVC(基于 liblinear)的训练复杂度为 O(n_features*n_samples)O(n_features) 测试复杂度。

【讨论】:

在实践中,SGDClassifier 在 scikit-learn 中拟合线性 SVM 模型的速度更快。而且我们还没有实现平均:) 我们可以要求 LinearSVC 输出概率吗?它没有像 SVC 这样的参数来控制输出是否是概率。人们通常会为此做什么?【参考方案3】:

SGD 非常快,但是 1) 仅线性,而非 rbf, 2)参数 alpha eta0 ...我不知道如何改变: 交给专家 O. Grisel。

在 32 位与 64 位 python 上(什么硬件,什么 py 版本?), 我不知道,但这可能值得一个关于 SO 的一般性问题—— 必须有基准套件。 你能看到 CPU 使用率 > 90 %,计算垃圾回收吗?

【讨论】:

可以使用explicit feature maps 和线性分类器(如 SGDClassifier)以可扩展的方式逼近非线性 RBF 内核。 我从不尝试调整eta0(也许我应该)。对于alpha,我只使用GridSearchCV,就像在LinearSVC 中使用C

以上是关于SVM 实现,scikit learn 减少运行时间,最快的 svm的主要内容,如果未能解决你的问题,请参考以下文章

无法运行适合 svm 的方法(通过 scikit-learn)

在手写数字示例中使用 scikit-learn 实现 SVM 的特征提取器

使用 scikit-learn 训练数据时,SVM 多类分类停止

将 scikit-learn SVM 模型转换为 LibSVM

目标的缩放导致 Scikit-learn SVM 回归崩溃

使用 scikit-learn python 的线性 SVM 时出现 ValueError