XGBRegressor结合EarlyStopping在cross_val_predict中报错的问题咨询
问题解答
一、validation_0与eval_set的关联逻辑
在XGBoost的fit方法中,当你传入eval_set=[(X, y)]时,XGBoost会自动为每个传入的验证集分配默认命名:第一个验证集叫validation_0,第二个叫validation_1,以此类推。
官方示例里的EarlyStopping设置data_name="validation_0",就是明确指定要监控第一个验证集的指标(这里是mlogloss),当该指标在连续rounds=2轮迭代中没有达到min_delta的提升时,触发早停逻辑。两者的关联完全依赖这个默认命名规则。
二、交叉验证中EarlyStopping报错的问题分析与解决
错误原因
你使用cross_val_predict时,这个函数默认只会把当前折的训练数据传给模型fit,不会自动将折内的测试集作为验证集传入eval_set。而EarlyStopping必须依赖至少一个验证集来监控指标,因此抛出ValueError: Must have at least 1 validation dataset for early stopping。
解决方法
放弃使用cross_val_predict,手动实现交叉验证循环,在每个折内明确拆分训练集和验证集,并将验证集传入模型的fit方法的eval_set参数中。
修改后的代码示例:
import xgboost as xgb from sklearn.model_selection import KFold import numpy as np class CustomEarlyStopping(xgb.callback.EarlyStopping): def __init__(self, rounds=2, min_delta=1e-3, save_best=True, maximize=False, data_name="validation_0", metric_name="rmse"): super().__init__(rounds=rounds, min_delta=min_delta, save_best=save_best, maximize=maximize, data_name=data_name, metric_name=metric_name) # 10次10折交叉验证 cvx = KFold(n_splits=10, shuffle=True, random_state=239) es = CustomEarlyStopping() model_base = xgb.XGBRegressor(colsample_bytree=0.3, learning_rate=0.1, max_depth=10, alpha=10, n_estimators=500, n_jobs=-1, random_state=239, callbacks=[es]) model_base.set_params(tree_method='approx', device="cpu") cv_preds = [] # 外层10次循环 for _ in range(10): fold_preds = [] # 内层10折拆分 for train_idx, val_idx in cvx.split(X_train, y_train): X_tr, y_tr = np.asarray(X_train)[train_idx], np.asarray(y_train)[train_idx] X_val, y_val = np.asarray(X_train)[val_idx], np.asarray(y_train)[val_idx] # 初始化新模型(避免跨折的状态污染) model = xgb.XGBRegressor(**model_base.get_params()) # 传入验证集,让EarlyStopping生效 model.fit(X_tr, y_tr, eval_set=[(X_val, y_val)], verbose=False) # 预测当前折的验证集 fold_preds.append(model.predict(X_val)) # 将当前10折的预测结果合并为一个数组 cv_preds.append(np.concatenate(fold_preds))
关键注意点
- 每次折训练都要初始化新的模型实例,避免上一轮折的早停状态影响当前折。
- 必须在
fit时传入eval_set,确保EarlyStopping能拿到验证集指标。 - 最后将每个折的预测结果拼接成完整的数组,和
cross_val_predict的输出格式一致。
内容的提问来源于stack exchange,提问作者kenshin uesugi
相关产品推荐
相关产品推荐

