ConvergenceWarning:lbfgs 无法收敛(状态 = 1):停止:总 NO。迭代次数达到限制

ConvergenceWarning: lbfgs failed to converge (status=1): STOP: TOTAL NO. of ITERATIONS REACHED LIMIT

我有一个由数字数据和分类数据组成的数据集,我想根据患者的医学特征预测其不良后果。我像这样为我的数据集定义了一个预测管道:

X = dataset.drop(columns=['target'])
y = dataset['target']

# define categorical and numeric transformers
numeric_transformer = Pipeline(steps=[
    ('knnImputer', KNNImputer(n_neighbors=2, weights="uniform")),
    ('scaler', StandardScaler())])

categorical_transformer = Pipeline(steps=[
    ('imputer', SimpleImputer(strategy='constant', fill_value='missing')),
    ('onehot', OneHotEncoder(handle_unknown='ignore'))])

#  dispatch object columns to the categorical_transformer and remaining columns to numerical_transformer
preprocessor = ColumnTransformer(transformers=[
    ('num', numeric_transformer, selector(dtype_exclude="object")),
    ('cat', categorical_transformer, selector(dtype_include="object"))
])

# Append classifier to preprocessing pipeline.
# Now we have a full prediction pipeline.
clf = Pipeline(steps=[('preprocessor', preprocessor),
                      ('classifier', LogisticRegression())])

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)

clf.fit(X_train, y_train)
print("model score: %.3f" % clf.score(X_test, y_test))

但是,当 运行 这段代码时,我收到以下警告消息:

ConvergenceWarning: lbfgs failed to converge (status=1):
STOP: TOTAL NO. of ITERATIONS REACHED LIMIT.
Increase the number of iterations (max_iter) or scale the data as shown in:
    https://scikit-learn.org/stable/modules/preprocessing.html
Please also refer to the documentation for alternative solver options:
    https://scikit-learn.org/stable/modules/linear_model.html#logistic-regression
  extra_warning_msg=_LOGISTIC_SOLVER_CONVERGENCE_MSG)

    model score: 0.988

谁能给我解释一下这个警告是什么意思?我是机器学习的新手,所以对于我可以做些什么来改进预测模型有点迷茫。正如您从 numeric_transformer 中看到的那样,我通过标准化对数据进行了缩放。我也很困惑模型分数为什么这么高,这是好事还是坏事。

warning 的意思主要是说:建议尝试使 solver(算法)收敛。


lbfgs 代表:“有限内存 Broyden–Fletcher–Goldfarb–Shanno 算法”。它是 Scikit-Learn 库提供的求解器算法之一。

术语有限内存只是意味着它存储只有几个隐式表示梯度近似的向量。

它在相对数据集上有更好的收敛


但什么是算法收敛

简单来说。如果求解的误差在很小的范围内(即几乎没有变化),那么这意味着算法达到了解决方案(不一定是最好的解决方案,因为它可能会卡在什么地方-称为“局部最优”).

另一方面,如果误差变化明显即使误差相对较小[就像在你的情况下得分很好],而是每次迭代的错误之间的差异大于某个公差) 那么我们说算法没有收敛。

现在,您需要知道 Scikit-Learn API 有时会为用户提供选项以指定算法在以迭代方式搜索解决方案时应进行的最大迭代次数:

LogisticRegression(... solver='lbfgs', max_iter=100 ...)

可以看到,LogisticRegression中默认的求解器是'lbfgs',默认最大迭代次数是100

最后的话,请注意,增加最大迭代次数不一定保证收敛,但肯定有帮助!


更新:

根据您在下方的评论,可以尝试(在许多方面)可能有助于算法收敛的一些提示是:

  • 增加迭代次数:如本回答所述;
  • 尝试不同的优化器:看
  • 扩展数据:查看 here
  • 添加工程特征:看here
  • 数据预处理:看here - use case and here
  • 添加更多数据:看here

如果您遇到任何机器学习算法的以下错误,

ConvergenceWarning:

lbfgs failed to converge (status=1):
STOP: TOTAL NO. of ITERATIONS REACHED LIMIT.

增加迭代次数(max_iter)或按6.3. Preprocessing data

所示缩放数据

另请参阅替代求解器选项的文档:LogisticRegression()

那么在那种情况下,你可以使用像

这样的算法
from sklearn.linear_model import LogisticRegression
log_model = LogisticRegression(solver='lbfgs', max_iter=1000)

因为有时候迭代会出现这种情况

修复收敛警告LogisticRegression 中指定 max_iter 到更高的值:

from sklearn.linear_model import LogisticRegression
model=LogisticRegression(max_iter=3000)
model.fit(X_train,y_train)