如何使用多套独立验证集执行HalvingGridSearchCV超参数调优
问题根源
你用PredefinedSplit达不到需求是因为它的内置逻辑固定:对第k轮折,所有test_fold值不等于k且不等于-1的样本都会被划入训练集,没有配置项可以指定部分样本永远不进入训练集。
实现方案
Sklearn所有超参数搜索类的cv参数都支持直接传入自定义的折叠迭代器,每个元素为(训练索引列表, 测试索引列表)的元组,你完全可以手动构造符合要求的折叠,不需要依赖内置的拆分类:
- 先按固定顺序拼接所有数据集:训练集 + val_a + val_b + val_c
- 手动生成3个折叠,每个折叠的训练索引固定为原训练集的索引范围,测试索引分别对应三个验证集的索引范围
代码示例
import pandas as pd import numpy as np from sklearn.model_selection import HalvingGridSearchCV from lightgbm import LGBMRegressor # 按固定顺序拼接全量数据集 all_data = pd.concat([training_set, val_a, val_b, val_c]) # 拆分特征和目标列,需替换为你自己的目标列名 X = all_data.drop("target", axis=1) y = all_data["target"] # 计算各数据集的索引边界 train_idx_end = len(training_set) val_a_idx_end = train_idx_end + len(val_a) val_b_idx_end = val_a_idx_end + len(val_b) # 构造自定义交叉验证折叠 custom_cv = [ # 折1:训练用原训练集,测试用val_a (list(range(train_idx_end)), list(range(train_idx_end, val_a_idx_end))), # 折2:训练用原训练集,测试用val_b (list(range(train_idx_end)), list(range(val_a_idx_end, val_b_idx_end))), # 折3:训练用原训练集,测试用val_c (list(range(train_idx_end)), list(range(val_b_idx_end, len(all_data)))) ] # 初始化Halving网格搜索 gs = HalvingGridSearchCV( estimator=LGBMRegressor(), param_grid=param_grid, cv=custom_cv, scoring="r2", refit=False, # 如需自动用最优参数在全训练集拟合,可改为True min_resources="exhaust", aggr_score=np.mean # 默认取三个验证集得分的平均值,要取最低得分改为np.min即可 ) # 执行搜索 gs.fit(X, y)
注意事项
这种实现方式下,三个验证集的样本永远不会进入任何一轮的训练集,完全避免了跨时间点的信息泄露,且搜索类会自动按照你指定的聚合规则计算每组超参数的最终评分,完全符合业务需求。
内容的提问来源于stack exchange,提问作者Glandular-Email-Boss9
相关产品推荐
相关产品推荐

