ConvergenceWarning: Liblinear 收敛失败,增加迭代次数
Posted
技术标签:
【中文标题】ConvergenceWarning: Liblinear 收敛失败,增加迭代次数【英文标题】:ConvergenceWarning: Liblinear failed to converge, increase the number of iterations 【发布时间】:2019-03-11 05:17:49 【问题描述】:为 Adrian 运行线性二进制模式的代码。该程序运行但给出以下警告:
C:\Python27\lib\site-packages\sklearn\svm\base.py:922: ConvergenceWarning: Liblinear failed to converge, increase the number of iterations.
"the number of iterations.", ConvergenceWarning
我用opencv3.7运行python2.7,我该怎么办?
【问题讨论】:
在 LogisticRegression 算法中默认迭代为 100。如果您的数据集样本超过 100,则增加它。 【参考方案1】:通常,当优化算法不收敛时,通常是因为问题条件不佳,可能是由于决策变量的缩放不良。您可以尝试一些方法。
-
标准化您的训练数据,以便问题变得更好
有条件的,这反过来又可以加速收敛。一
可能性是将您的数据缩放到 0 均值,单位标准偏差使用
Scikit-Learn's
StandardScaler
例如。请注意,您必须将适用于训练数据的 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 方法)在其中发挥了不同的作用,并且有证据表明,与一阶方法相比,它们有时可以找到更好的解决方案 -订购方法。但那是另一回事了。
【讨论】:
我在这个笔记本中看到了警告:kaggle.com/ninovanhooff/svm-for-fraud-detection 请注意,似乎所有用于训练和测试的变量都已标准化,但我没有设置任何分类器参数,但不确定是什么值的 C 使用。我应该根据对系数的调查来设置 C 吗? (请参阅该笔记本中的条形图) 回答我之前的评论:根据 scikit 文档的建议,我将 dual 设置为 false。这消除了警告,似乎对分类性能没有影响 @PJRobot 欢迎您。但也要考虑我的其他关于设置正则化参数和标准化变量的 cmets。通常优化算法不应该花费太多的迭代来收敛。如果是这样,则表明优化问题是病态的。设置正则化参数并适当缩放数据,或解决 Nino van Hooff 建议的优化问题的对偶,是“修复”此问题的更好方法,您应该在尝试更改max_iter
之前考虑这一点。
我很困惑,根据上面写着Prefer dual=False when n_samples > n_features.
的文档,你把它弄反了吗?
@JamesKo 是的,我犯了一个错误。如果特征数 > 样本数,我应该写 set dual = True
。原因是在 SVM 的对偶公式中,参数的数量与样本的数量相同,而在原始公式中,参数的数量是特征数 + 1。因此,如果样本数比特征,那么对偶公式将解决“更小”的优化问题。【参考方案2】:
请将 max_iter 增加到 10000,因为默认值是 1000。可能,增加 no。迭代次数将有助于算法收敛。对我来说,它收敛了,求解器是 -'lbfgs'
log_reg = LogisticRegression(solver='lbfgs',class_weight='balanced', max_iter=10000)
【讨论】:
【参考方案3】:显式指定max_iter
可解决警告,因为默认max_iter
为100。[对于逻辑回归]。
logreg = LogisticRegression(max_iter=1000)
【讨论】:
【参考方案4】:我达到了我设置的点,在我的 LinearSVC
分类器上达到了 max_iter=1200000
,但仍然存在 “ConvergenceWarning”。我通过设置dual=False
并将max_iter
保留为默认值来解决此问题。
使用LogisticRegression(solver='lbfgs')
分类器,您应该增加max_iter
。在使用大型数据集的特征进行训练时,在 "ConvergenceWarning" 消失之前,我的已达到 max_iter=7600
。
【讨论】:
根据我的数据形状设置dual
对我的情况有帮助。
LinearSVC dual=True 正确收敛 根据 sklearn LinearSVC 文档。 “选择算法来解决对偶或原始优化问题。当 n_samples > n_features 时首选 dual=False。” scikit-learn.org/stable/modules/generated/…以上是关于ConvergenceWarning: Liblinear 收敛失败,增加迭代次数的主要内容,如果未能解决你的问题,请参考以下文章
多层感知器:ConvergenceWarning:随机优化器:达到最大迭代次数,优化尚未收敛。警告?
[NN] Stochastic Gradient Descent - SAG & SVRG