在 SciKit-Learn 中使用 XGBoost 的交叉验证进行网格搜索和提前停止

Grid Search and Early Stopping Using Cross Validation with XGBoost in SciKit-Learn

我是 sci-kit learn 的新手,一直在尝试对 XGBoost 进行超参数调整。我的目标是使用早停和网格搜索来调整模型参数,并使用早停来控制树的数量并避免过度拟合。

因为我在网格搜索中使用交叉验证,所以我希望在早期停止条件中也使用交叉验证。到目前为止我的代码如下所示:

import numpy as np
import pandas as pd
from sklearn import model_selection
import xgboost as xgb

#Import training and test data
train = pd.read_csv("train.csv").fillna(value=-999.0)
test = pd.read_csv("test.csv").fillna(value=-999.0)

# Encode variables
y_train = train.price_doc
x_train = train.drop(["id", "timestamp", "price_doc"], axis=1)

# XGBoost - sklearn method
gbm = xgb.XGBRegressor()

xgb_params = {
'learning_rate': [0.01, 0.1],
'n_estimators': [2000],
'max_depth': [3, 5, 7, 9],
'gamma': [0, 1],
'subsample': [0.7, 1],
'colsample_bytree': [0.7, 1]
}

fit_params = {
'early_stopping_rounds': 30,
'eval_metric': 'mae',
'eval_set': [[x_train,y_train]]
}

grid = model_selection.GridSearchCV(gbm, xgb_params, cv=5, 
fit_params=fit_params)
grid.fit(x_train,y_train)

我遇到的问题是 'eval_set' 参数。我知道这需要预测变量和响应变量,但我不确定如何使用交叉验证数据作为提前停止标准。

有谁知道如何解决这个问题?谢谢

您可以将 early_stopping_rounds 和 eval_set 作为额外的 fit_params 传递给 GridSearchCV,这确实有效。但是,GridSearchCV 不会更改不同折叠之间的 fit_params,因此您最终会在所有折叠中使用相同的 eval_set,这可能不是您所说的 CV 的意思。

model=xgb.XGBClassifier()
clf = GridSearchCV(model, parameters,
                         fit_params={'early_stopping_rounds':20,\
                         'eval_set':[(X,y)]},cv=kfold)  

经过一些调整,我发现集成 early_stopping_rounds 和 sklearn API 的最安全方法是您自己实现 early_stopping 机制。如果您使用 n_rounds 作为要调整的参数执行 GridSearchCV,则可以做到这一点。然后,您可以观看 mean_validation_score 增加 n_rounds 的不同型号。然后您可以为提前停止定义自定义启发式。它不会节省评估所有可能 n_rounds 尽管

所需的计算时间

我认为这也是一种比使用单个拆分保留更好的方法。

使用 xgboost 原版。

根据数据 Dmatrix 制作并使用 xgboost.cv

tutorial

在 GridSearchCV 中包含提前停止没有多大意义。早停用于在train/valid情况下快速找到最好的n_rounds。如果我们不关心'quickly',我们可以直接调整n_rounds。假设 GridSearchCV 具有为每个折叠进行早期停止 n_rounds 的功能,那么我们将对每组超参数设置 N(折叠数)n_rounds。也许 n_rounds 的平均值可以用于最终的最佳超参数集,但是当 n_rounds 彼此相差太多时,它可能不是一个好的选择。因此,在 GridSearchCV 中包含提前停止可能会提高试验速度,但结果可能不是最好的。

接受的答案中建议的方法更像是调整 n_rounds 参数而不是提前停止,因为作者承认“它不会节省评估所有可能 n_rounds 所需的计算时间".