【问题标题】:Why does XGBoost not show me the correct best_iteration and ntree_limit?为什么 XGBoost 没有显示正确的 best_iteration 和 ntree_limit?
【发布时间】:2020-01-16 06:20:21
【问题描述】:

我正在使用 XGBoostClassifier 创建一个二元分类模型,但在获取 best_iteration 和 ntree_limit 的正确值时遇到了一些问题。

下面的代码是我的自定义评估指标:

def xgb_f1(y, t):
    t = t.get_label()
    y_bin = [1. if y_cont > 0.5 else 0. for y_cont in y]
    return 'f1', f1_score(t, y_bin, average='macro')

这就是我创建和安装分类器的方式:

classifier = xgb.XGBClassifier(n_estimators=10000)
classifier.fit(X_train, y_train, 
               eval_metric=xgb_f1, 
               eval_set=[(X_test, y_test)], 
               verbose=True)

这些是 XGBoost 在拟合期间显示给我的一些结果:

[1007]  validation_0-error:0.181395 validation_0-f1:0.731411
[1355]  validation_0-error:0.183721 validation_0-f1:0.735139
[1396]  validation_0-error:0.183721 validation_0-f1:0.736116
[1426]  validation_0-error:0.182558 validation_0-f1:0.737302
[3568]  validation_0-error:0.186047 validation_0-f1:0.737557
[3791]  validation_0-error:0.184884 validation_0-f1:0.7378
[9999]  validation_0-error:0.210465 validation_0-f1:0.708715

正如您所见,由于 f1 分数最高,最佳迭代是迭代编号 3791,但是当我调用 classifier.get_booster().best_iteration 时,它显示迭代编号 9999(最后一次迭代)是最好的,但不是.当我打电话给classifier.get_booster().best_ntree_limit 时,它告诉我最好的限制是 10000,但我不这么认为,因为它让我获得的 f1 分数低于更低的迭代次数。

【问题讨论】:

    标签: python validation xgboost xgbclassifier


    【解决方案1】:

    我认为你应该使用early_stopping_rounds 参数。但是,您仍将获得最后一次迭代的模型。查看 xgboost docs 的 xgboost.XGBRegressior.fit() 方法,在 early_stopping_rounds 下它说:

    该方法返回上一次迭代的模型(不是最好的)。

    解决方法是在第一轮训练后创建一个新的分类器并设置n_estimators,使其完全停止在之前的位置。

    classifier = xgb.XGBClassifier(
        n_estimators=10000,
        early_stopping_rounds=50
        )
    classifier.fit(X_train, y_train, 
                   eval_metric=xgb_f1, 
                   eval_set=[(X_test, y_test)], 
                   verbose=True)
    classifier_new = xgb.XGBClassifier(
        n_estimators=classifier.best_iteration
        )
    classifier_new.fit(X_train, y_train,
                       eval_metric=xgb_f1, 
                       eval_set=[(X_test, y_test)], 
                       verbose=True)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-07-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多