【发布时间】:2019-04-28 05:56:53
【问题描述】:
下面是一个关于 xgboost 提前停止轮次参数的问题,以及当它是拟合结束的原因时,它如何提供或不提供最佳迭代。
在 xgboost 文档中,可以在 scikit learn api 部分 (link) 中看到,当由于提前停止轮数参数而导致拟合停止时:
激活提前停止。验证错误至少需要每“early_stopping_rounds”轮减少一次才能继续训练。在 evals 中至少需要一项。如果有多个,将使用最后一个。返回上一次迭代的模型(不是最好的)。
reeding 时,返回的模型似乎不是最好的,而是最后一个。它说,要在预测时访问最好的,可以使用 ntree_limit 参数调用预测,并在拟合结束时给出 bst.best_ntree_limit。
从这个意义上说,它应该与 xgboost 的 train 以相同的方式工作,因为 scikitlearn api 的拟合似乎只是 train 和其他的嵌入。
在这里stack overflow discussion 或这里another discussion 进行了热烈的讨论
但是当我试图解决这个问题并检查它如何处理我的数据时,我没有找到我认为应该有的行为。事实上,我遇到的行为根本不是那些讨论和文档中描述的行为。
我这样称呼合适:
reg = xgb.XGBRegressor(n_jobs=6, n_estimators = 100, max_depth= 5)
reg.fit(
X_train,
y_train,
eval_metric='rmse',
eval_set=[(X_train, y_train), (X_valid, y_valid)],
verbose=True,
early_stopping_rounds = 6)
这是我最后得到的:
[71] validation_0-rmse:1.70071 validation_1-rmse:1.9382
[72] validation_0-rmse:1.69806 validation_1-rmse:1.93825
[73] validation_0-rmse:1.69732 validation_1-rmse:1.93803
Stopping. Best iteration:
[67] validation_0-rmse:1.70768 validation_1-rmse:1.93734
当我检查我使用的验证值时:
y_pred_valid = reg.predict(X_valid)
y_pred_valid_df = pd.DataFrame(y_pred_valid)
sqrt(mse(y_valid, y_pred_valid_df[0]))
我明白了
1.9373418403889535
如果拟合返回最后一次迭代而不是最好的迭代,它应该给出一个 1.93803 左右的 rmse,但它给出了一个 1.93734 的 rmse,这正是最好的分数。
我通过两种方式再次检查: [编辑] 我根据@Eran Moshe 的回答编辑了下面的代码
y_pred_valid = reg.predict(X_valid, ntree_limit=reg.best_ntree_limit)
y_pred_valid_df = pd.DataFrame(y_pred_valid)
sqrt(mse(y_valid, y_pred_valid_df[0]))
1.9373418403889535
即使我只用 68 个估算器调用合适的(知道最好的迭代器是第 67 个),所以我确信最后一个是最好的:
reg = xgb.XGBRegressor(n_jobs=6, n_estimators = 68, max_depth= 5)
reg.fit(
X_train,
y_train,
eval_metric='rmse',
eval_set=[(X_train, y_train), (X_valid, y_valid)],
verbose=True,
early_stopping_rounds = 6)
结果是一样的:
1.9373418403889535
因此,这似乎导致了这样一种想法,即,与文档以及关于它的众多讨论不同,xgboost 的适合性在被早期停止轮参数停止时,确实给出了最好的迭代器,而不是最后一个.
我错了吗,如果是,你在哪里以及如何解释我遇到的行为?
感谢关注
【问题讨论】:
标签: python machine-learning scikit-learn xgboost