python - xgboost的两种界面工作方式完全一样吗?
问题描述
我目前正在参加 Kaggle 的一场课堂竞赛。我已经阅读了官方的 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
。
我喜欢GridSearchCV
sklearn 中的,但我也想eval_set
在每一折处得到改变,就像xgb.cv
做一样。我相信它可以在防止过度拟合的同时利用数据。
我应该怎么做?我想到了两种方法:
- 使用 XGB API,并自己编写 GridSearch。
- 使用 sklean API,并
eval_set
在每个折叠处手动更改。有没有更方便的方法?
解决方案
正如您所总结的,这两种方法都有优点和缺点。
xgb.cv
将使用左侧折叠进行提前停止,因此您不需要额外拆分为验证/训练样本来确定何时触发提前停止。GridSearchCV
(或者也许您尝试一下RandomizedSearchCV
)将为您处理参数网格和最佳选择。
请注意,在所有 CV 折叠中使用固定子样本提前停止不是问题。所以我认为你不必做任何“在每次折叠时手动更改”之eval_set
类的事情。早期停止中使用的评估样本不会直接影响模型参数 - 它用于决定保留样本的评估指标何时停止改进。对于最终模型,您可以放弃提前停止 - 您可以使用上述拆分查看模型何时以最佳超参数停止,然后使用该树数作为最终模型拟合中的固定参数。
所以最后这是一个品味问题,因为在这两种情况下,你都需要在某些事情上妥协。IMO,sklearn API 是最佳选择,因为它允许在 CV 的管道中以自然的方式使用其余的 sklearn 工具(例如用于数据预处理),并且它允许为各种方法的模型训练提供同质接口。但最终取决于你
推荐阅读
- java - Java OOP - 打印组合 bean 信息的问题
- wordpress - 如何重新排列 WooCommerce 的“我的帐户”页面中的菜单?
- autohotkey - 在具有多个显示器的任务栏上使用鼠标滚轮更改音量
- python - 从现有值中为新的值列创建循环
- amazon-web-services - 这种 AWS SSO 会话到期体验是否正常,是否可以更改?
- google-sheets - 谷歌表格摘要图表在表格中截断/重新创建
- java - 将 CardView 实现上的 NullPointerException 转换为 RecycleView
- c# - 从 NetworkStream 读取时偏移量有什么用?
- raspberry-pi - How to convert a plug into a GPIO pin
- r - R data.frame 到像 facet_grid 这样的矩阵