xgboost文档是错误的吗?(早期停止轮次以及最佳和最后一次迭代)

Lyx*_*xos 6 python machine-learning scikit-learn xgboost

下面是一个关于xgboost早期停止轮次参数的问题,以及它是如何做到的,或者当它是合适结束的原因时给出最好的迭代.

在xgboost文档中,可以在scikit中看到api部分(链接),当由于早期停止舍入参数而导致拟合停止时:

激活提前停止.验证错误需要至少减少每个"early_stopping_rounds"回合以继续训练.在evals中至少需要一个项目.如果有多个,将使用最后一个.返回上一次迭代的模型(不是最好的).

当重新使用它时,似乎返回的模型,在这种情况下,不是最好的,而是最后一个.为了在预测时访问最好的一个,它说,可以使用ntree_limit参数调用预测,并在拟合结束时给出bst.best_ntree_limit.

从这个意义上讲,它应该与xgboost系列的工作方式相同,因为scikitlearn api的拟合似乎只是火车和其他人的嵌入.

这里讨论堆栈溢出讨论或这里另一个讨论

但是当我试图解决这个问题并检查它是如何处理我的数据的时候,我没有找到我认为我应该拥有的行为.实际上,我遇到的行为根本不是那些讨论和文档中描述的行为.

我这样称呼:

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)
Run Code Online (Sandbox Code Playgroud)

这就是我最终得到的:

[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
Run Code Online (Sandbox Code Playgroud)

当我检查我使用的验证值时:

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]))
Run Code Online (Sandbox Code Playgroud)

我明白了

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]))
Run Code Online (Sandbox Code Playgroud)

1.9373418403889535

即使我称之为拟合(知道最好的是第67位)只有68个估算器,所以我确定最后一个是最好的:

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)
Run Code Online (Sandbox Code Playgroud)

结果是一样的:

1.9373418403889535

所以这似乎导致了这样的想法:与文档不同,以及那些关于它的大量讨论,告诉我们,xgboost在早期停止循环参数停止时的适用性确实给出了最好的,而不是最后一个.

我错了,如果是的话,在哪里,你如何解释我遇到的行为?

感谢您的关注

Myk*_*vyi 5

我认为,没有错,但不一致

predict方法的文档是正确的(例如,请参阅此处)。为了 100% 确定最好查看代码:xgb github,因此predict其行为如其文档中所述,但fit文档已过时。请把它作为一个问题发布在 XGB github 上,他们要么修复文档,要么你将成为 XGB 贡献者:)

  • 仅供参考,我提出了一个 pullrequest 来更正文档,它被接受了。请参阅拉取请求 #3967:https://github.com/dmlc/xgboost/pull/3967 (2认同)