【问题标题】:ConvergenceWarning: lbfgs failed to converge (status=1): STOP: TOTAL NO. of ITERATIONS REACHED LIMITConvergenceWarning:lbfgs 未能收敛(状态 = 1):停止:TOTAL NO。迭代次数达到极限
【发布时间】:2020-10-20 19:15:04
【问题描述】:

我有一个包含数字和分类数据的数据集,我想根据患者的医学特征预测患者的不良后果。我为我的数据集定义了一个预测管道,如下所示:

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 中可以看出,我通过标准化对数据进行了缩放。我也很困惑模型分数如何相当高以及这是好事还是坏事。

【问题讨论】:

    标签: python machine-learning scikit-learn logistic-regression


    【解决方案1】:

    警告的意思主要是:建议尝试使求解器(算法)收敛。


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

    limited-memory 一词仅表示它只存储几个隐式表示梯度近似的向量。

    它在相对小型数据集上具有更好的收敛性


    但是什么是算法收敛

    简单来说。如果求解的误差在非常小的范围内(即几乎没有变化),那么这意味着算法达到了解决方案(不一定是最佳解决方案,因为它可能会停留在所谓的“局部最优”)。

    另一方面,如果误差变化显着即使误差相对较小 [就像你的情况一样,分数很好],而是每次迭代的误差之间的差异大于某个容差)然后我们说算法没有收敛。

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

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

    如您所见,LogisticRegression 中的默认求解器为 'lbfgs',默认最大迭代次数为 100。

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


    更新:

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

    • 增加迭代次数:如this answer;
    • 尝试不同的优化器:看看here;
    • 扩展您的数据:看here;
    • 添加工程功能:看here
    • 数据预处理:看here - use casehere
    • 添加更多数据:查看here

    【讨论】:

    • 我将最大迭代次数增加到 400 LogisticRegression(solver='lbfgs', max_iter=400),这已经解决了警告。谢谢你的解释。
    • 回到这个问题,我可以尝试帮助算法收敛的其他方面的任何提示?
    • 我将最大迭代次数增加到 1000 以使其正常工作。
    【解决方案2】:

    如果任何机器学习算法出现以下错误,

    收敛警告:

    lbfgs 未能收敛(状态=1):
    停止:总数迭代次数达到限制。

    增加迭代次数(max_iter)或缩放数据如6.3. Preprocessing data

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

    那么在这种情况下,您使用类似的算法

    from sklearn.linear_model import LogisticRegression
    log_model = LogisticRegression(solver='lbfgs', max_iter=1000)
    

    因为有时候会因为迭代而发生。

    【讨论】:

    • 这个答案已经在最近的Stack Overflow blog post 中提到过,因此今天很快就获得了一些支持。
    • 是的,但这仍然是一个糟糕的答案。 “因为有时候会因为迭代而发生。”是一个相当没有意义的回应......
    • 引自博文:“最被复制的被否决的答案”
    • @GuilhermeGarnier 确定接受的答案很冗长,但原始发帖人似乎相当幼稚,可能需要评论者提供的一些额外背景。
    • 这个答案已经在StackOverflow Blog 2021-04-19再次提到,一定会引起更多关注:)
    【解决方案3】:

    修复收敛警告LogisticRegression中的ma​​x_iter指定为更高的值:

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

    【讨论】:

      猜你喜欢
      • 2020-08-31
      • 1970-01-01
      • 1970-01-01
      • 2023-03-13
      • 2021-09-08
      • 2021-08-08
      • 2018-11-16
      • 2019-12-04
      • 1970-01-01
      相关资源
      最近更新 更多