我目前正在Kaggle参加一场In Class竞赛。 我已经阅读了官方的python API参考,我对这两种接口感到困惑,特别是在网格搜索,交叉验证和早期停止方面。
在XGBoost API中,我可以使用xgb.cv()
,将其数据集拆分为两部分进行交叉验证,调整好的超参数,然后获取best_iteration
。
因此,我可以将num_boost_round
调整为best_iteration
。为了最大限度地利用数据,我使用经过良好调整的超参数再次训练整个数据集,然后使用它进行分类。唯一的缺点是我必须自己编写GridSearch
代码。
注意:此交叉验证集在每次折叠时都会更改,因此训练结果对数据的任何部分都没有特定的倾向。
但是在sklearn中,我似乎无法像在xgb模型中那样使用best_iteration
获取clf.fit()
。实际上,fit()
方法有early_stopping_rounds
和eval_set
来实现早期停止部分。许多人实现了这样的代码:
X_train, X_test, y_train, y_test = train_test_split(train, target_label, test_size=0.2, random_state=0)
clf = GridSearchCV(xgb_model, para_grid, scoring='roc_auc', cv=5, \
verbose=True, refit=True, return_train_score=False)
clf.fit(X_train, y_train, early_stopping_rounds=30, eval_set=[(X_test, y_test)])
....
clf.predict(something)
但问题是我首先将数据分成两部分。交叉验证集在每次折叠时都不会更改。因此,结果可能会倾向于整个数据集的这个随机部分。在网格搜索中也会出现同样的问题,最终的参数可能会适合
X_test
和y_test
更多。
我非常喜欢sklearn中的GridSearchCV
,但我也想在每次折叠时更改eval_set
,就像xgb.cv
一样。我相信它可以利用数据,同时防止过度拟合。
我该怎么办? 我想到了两种方法:
eval_set
。
还有更方便的方法吗?答案 0 :(得分:-1)
如您所总结的,这两种方法都有优点和缺点。
xgb.cv
将使用左侧折叠进行提前停止,因此您不需要额外拆分为验证/训练样本,以确定何时触发提前停止。GridSearchCV
(或者你可能尝试RandomizedSearchCV
)将为您处理参数网格和最佳选择。请注意,使用固定的子样本在所有CV折叠中提前停止不是问题。所以我认为你不必做任何事情,比如" 每次手动更改eval_set
"。早期停止中使用的评估样本不会直接影响模型参数 - 它用于确定何时停留样本的评估指标停止改进。对于最终模型,您可以提前停止 - 您可以使用上述拆分查看模型何时使用最佳超参数停止,然后在最终模型拟合中使用该数量的树作为固定参数。
所以最后这是一个品味问题,因为在这两种情况下你都需要妥协。 IMO,sklearn API是最佳选择,因为它允许在CV中的管道中以自然的方式使用其余的sklearn工具(例如,用于数据预处理),并且它允许均匀的接口来为各种方法建模训练。但最后由你决定