使用 scikit learn 的 SVM 无休止地运行并且永远不会完成执行

数据挖掘 Python 支持向量机 scikit-学习
2021-10-01 19:37:47

我正在尝试使用 scikit-learn (python) 在具有 595605 行和 5 列(特征)的训练数据集上运行 SVR,而测试数据集有 397070 行。数据已经过预处理和正则化。

我能够成功运行测试示例,但是在使用我的数据集执行并让它运行一个多小时后,我仍然看不到任何输出或程序终止。我尝试使用不同的 IDE 甚至从终端执行,但这似乎不是问题。我还尝试将“C”参数值从 1 更改为 1e3。

我在使用 scikit 的所有 SVM 实现中都面临着类似的问题。

我是不是等待它完成的时间不够长?这个执行需要多长时间?

根据我的经验,它应该不会超过几分钟。

这是我的系统配置:Ubuntu 14.04、8GB RAM、大量可用内存、第四代 i7 处理器

4个回答

核化 SVM 需要计算数据集中每个点之间的距离函数,这是 O(nfeatures×nobservations2). 距离的存储是内存的负担,因此它们会在运行中重新计算。值得庆幸的是,大多数时候只需要最接近决策边界的点。经常计算的距离存储在缓存中。如果缓存被颠簸,那么运行时间会增加到O(nfeatures×nobservations3).

您可以通过调用 SVR 来增加此缓存

model = SVR(cache_size=7000)

一般来说,这是行不通的。但一切都没有丢失。您可以对数据进行二次抽样并将其余数据用作验证集,或者您可以选择不同的模型。在 200,000 观察范围以上,选择线性学习器是明智的。

可以通过近似内核矩阵并将其馈送到线性 SVM 来近似内核 SVM。这使您可以在线性时间内在准确性和性能之间进行权衡。

实现此目的的一种流行方法是使用 kmeans/kmeans++ 找到的 100 个左右的集群中心作为内核函数的基础。然后将新的派生特征输入线性模型。这在实践中非常有效。sophia-mlvowpal wabbit这样的工具是谷歌、雅虎和微软的做法。输入/输出成为简单线性学习器的主要成本。

在大量数据中,非参数模型对大多数问题的表现大致相同。结构化输入例外,如文本、图像、时间序列、音频。

进一步阅读

SVM 解决了二次阶的优化问题。

我没有什么要补充的,这里没有说。我只想在 sklearn 页面上发布一个关于SVC的链接,以阐明正在发生的事情:

该实现基于 libsvm。拟合时间复杂度超过样本数量的二次方,这使得很难扩展到具有超过 10000 个样本的数据集。

如果您不想使用内核,并且线性 SVM 就足够了,那么可以使用 LinearSVC但是,您必须对数据进行标准化,以防您还没有这样做,因为它将正则化应用于截距系数,这可能不是您想要的。这意味着如果您的数据平均值远非零,它将无法令人满意地解决它。

您还可以使用随机梯度下降来解决优化问题。Sklearn 具有SGDClassifier您必须使用loss='epsilon_insensitive'与线性 SVM 相似的结果。请参阅文档。我只会将梯度下降作为最后的手段,因为它意味着对超参数进行大量调整,以避免陷入局部最小值。LinearSVC如果可以,请使用。

您是否在预处理步骤中包括缩放?我在运行我的 SVM 时遇到了这个问题。我的数据集是约 780,000 个样本(行),具有 20 个特征(列)。我的训练集是 ~235k 样本。原来我只是忘了扩展我的数据!如果是这种情况,请尝试将此位添加到您的代码中:

将数据缩放到 [-1,1] ;提高 SVM 速度:

from sklearn.preprocessing import MinMaxScaler
scaling = MinMaxScaler(feature_range=(-1,1)).fit(X_train)
X_train = scaling.transform(X_train)
X_test = scaling.transform(X_test)

拥有如此庞大的数据集,我认为您最好使用神经网络、深度学习、随机森林(它们非常好)等。

前面的回复中提到,所花费的时间与训练样本数的三次方成正比。就测试向量的数量而言,甚至预测时间也是多项式的。

如果您真的必须使用 SVM,那么我建议您使用 GPU 加速或减少训练数据集的大小。首先尝试使用数据样本(可能是 10,000 行),看看它是否不是数据格式或分布的问题。

正如其他回复中提到的,线性内核更快。