通常,当优化算法不收敛时,通常是因为问题条件不佳,可能是由于决策变量的缩放不良。您可以尝试几件事。
- 规范化你的训练数据,这样问题就有可能变得更好,这反过来又可以加速收敛。一种可能性是使用
Scikit-Learn 的 StandardScaler将您的数据缩放为 0 均值、单位标准差
。请注意,您必须将适用于训练数据的 StandardScaler 应用于测试数据。此外,如果您有离散特征,请确保它们被正确转换,以便缩放它们是有意义的。
- 与 1) 相关,确保
C
正确设置其他参数,例如正则化权重 , 。C
必须> 0。通常,C
在以更精细的粒度对其进行微调之前,会尝试以对数刻度(1e-5、1e-4、1e-3、...、1、10、100、...)的各种值在特定的时间间隔内。如今,使用诸如Scikit-Optimize 之类的包来调整参数可能更有意义,例如使用贝叶斯优化。
- 设置
max_iter
为更大的值。默认值为 1000。这应该是您最后的手段。如果优化过程在前 1000 次迭代中没有收敛,则通过设置更大的值使其收敛max_iter
通常会掩盖其他问题,例如 1) 和 2) 中描述的问题。它甚至可能表明您有一些适当的特征或特征中的强相关性。在采取这种简单的方法之前先调试它们。
- 设置
dual = True
特征数 > 示例数,反之亦然。这使用对偶公式解决了 SVM 优化问题。感谢@Nino van Hooff指出这一点,感谢@JamesKo 发现我的错误。
- 如果您使用逻辑回归,请使用不同的求解器,例如 L-BFGS 求解器。请参阅@5ervant的回答。
注意:不应忽略此警告。
出现此警告是因为
求解线性 SVM 只是求解二次优化问题。求解器通常是一种迭代算法,它保持对解决方案的运行估计(即,SVM 的权重和偏差)。当解决方案对应于该凸优化问题的最佳目标值时,或者当它达到最大迭代次数集时,它会停止运行。
如果算法不收敛,则不能保证 SVM 参数的当前估计是好的,因此预测也可能是完全垃圾。
编辑
此外,请考虑@Nino van Hooff和@5ervant的评论,以使用 SVM 的对偶公式。如果您拥有的特征数量 D 多于训练示例的数量 N,这一点尤其重要。这就是 SVM 的对偶公式专门设计的用途,有助于调节优化问题。感谢@5ervant注意到并指出了这一点。
此外,@5ervant还指出了更改求解器的可能性,特别是使用 L-BFGS 求解器。归功于他(即,赞成他的回答,而不是我的)。
我想为那些感兴趣的人提供一个快速粗略的解释(我是:))为什么这在这种情况下很重要。二阶方法,尤其是近似二阶方法,如 L-BFGS 求解器,将有助于解决病态问题,因为它在每次迭代时都逼近 Hessian 矩阵并使用它来缩放梯度方向。这允许它获得更好的收敛速度,但每次迭代的计算成本可能更高。也就是说,它需要更少的迭代来完成,但每次迭代都会比典型的一阶方法(如梯度下降或其变体)慢。
例如,典型的一阶方法可能会在每次迭代时更新解决方案,例如
x(k + 1) = x(k) - alpha(k) * 梯度(f(x(k)))
其中 alpha(k) 是迭代 k 的步长,取决于算法或学习率计划的特定选择。
二阶方法,例如牛顿法,将有一个更新方程
x(k + 1) = x(k) - alpha(k) * Hessian(x(k))^(-1) * 梯度(f(x(k)))
也就是说,它使用 Hessian 编码的局部曲率信息来相应地缩放梯度。如果问题是病态的,梯度将指向不太理想的方向,逆 Hessian 缩放将有助于纠正这一点。
特别是,@ 5ervant的答案中提到的 L-BFGS 是一种近似 Hessian 逆矩阵的方法,因为计算它可能是一项昂贵的操作。
然而,二阶方法的收敛速度可能比一阶方法(如通常的基于梯度下降的求解器)快得多(即,需要更少的迭代),正如你们现在所知,有时甚至无法收敛。这可以补偿每次迭代所花费的时间。
总之,如果你有一个条件良好的问题,或者如果你可以通过其他方式使其条件良好,例如使用正则化和/或特征缩放和/或确保你有比特征更多的例子,你可能不会必须使用二阶方法。但如今,随着许多模型优化非凸问题(例如,DL 模型中的模型),二阶方法(例如 L-BFGS 方法)在其中发挥了不同的作用,并且有证据表明,与一阶方法相比,它们有时可以找到更好的解决方案 -订购方法。不过那是另一回事了。