以下是有关xgboost早期停止回合参数的问题,当它是拟合结束的原因时,它如何执行或不执行最佳迭代。
在xgboost文档中,您可以在scikit学习api部分(link)中看到由于提前停止回合参数而使拟合停止时:
激活提前停止。验证错误至少需要减少每个“ early_stopping_rounds”回合才能继续训练。评估中至少需要一项。如果有多个,则使用最后一个。返回上一次迭代的模型(不是最佳迭代)。
在进行此操作时,返回的模型似乎不是最好的模型,而是最后一个模型。它表示,要在预测时获得最佳预测,可以使用ntree_limit参数并在拟合结束时给出bst.best_ntree_limit来调用预测。
从这个意义上讲,它应该与xgboost火车的工作方式相同,因为scikitlearn api的合适性似乎只是火车和其他火车的嵌入。
这里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,但均方根值为1.93734,恰好是最佳分数。
我通过两种方式再次检查: [编辑]我已经根据@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的拟合在被早期停止回合参数停止时确实给出了最佳迭代,而不是最后一个
我错了吗?如果错了,那么在哪里以及如何解释我遇到的行为?
感谢您的关注
答案 0 :(得分:1)
我认为,这没错,但是不一致。
predict
方法的文档是正确的(例如,参见here)。要百分百确定,最好查看以下代码:xgb github,因此predict
的行为与文档中所述相同,但是fit
文档已过时。请把它作为问题发布到XGB github上,或者他们将修复文档,或者您将成为XGB贡献者:)
答案 1 :(得分:0)
您那里有一个代码错误。
注意如何
reg.predict(X_valid, ntree_limit=reg.best_ntree_limit)
应该是
y_pred_valid = reg.predict(X_valid, ntree_limit=reg.best_ntree_limit)
实际上,您在进行计算时会进行相同的比较
sqrt(mse(y_valid, y_pred_valid_df[0]))
Xgboost的运行方式与您阅读的相同。 early_stopping_round = x
将继续训练,直到连续x
为止没有改善。
使用ntree_limit=y
进行预测时,只会使用前y
个增强器。
答案 2 :(得分:0)
更准确地说,与@Mykhailo Lisovyi相对应,该文档在scikit-learn api部分中非常不一致,因为fit段落告诉您,当发生早期停止回合时,返回的不是最佳迭代,而是返回最佳迭代。预测段告诉您,在未指定ntree_limit的情况下调用预测时,ntree_limit等于best_ntree_limit。
因此,当阅读拟合部分时,可能会认为需要在调用预测时指定最佳迭代,但是在阅读预测部分时,默认情况下会给出最佳迭代,它是最后一个您必须指定是否需要这样做。
我在xgboost的github上发布了一个问题。...等等,看
[UPDATE]:拉取请求已被接受:link