如何确保GridSearchCV先执行交叉划分再进行缺失值填充?
结论
你当前的代码配置已经默认实现了「先完成数据集交叉拆分,再在对应子集内执行众数缺失值填充」的要求,不需要额外修改参数或调整结构。
执行逻辑说明
当你将包含预处理步骤的完整Pipeline传入GridSearchCV时,框架会自动按折做数据隔离,不会出现数据泄露,每一轮交叉验证的执行顺序为:
- 第一步:将全量数据集拆分为当前轮的训练折、验证折,该步骤在所有预处理操作之前完成
- 第二步:仅使用当前轮训练折的数据拟合Pipeline里的所有组件:
- 计算训练折数值特征的众数,拟合
SimpleImputer - 基于填充后的训练折数据计算均值、标准差,拟合
StandardScaler - 基于预处理后的训练折数据拟合逻辑回归分类器
- 计算训练折数值特征的众数,拟合
- 第三步:用训练折上拟合好的预处理器、分类器,处理验证折数据并计算ROC-AUC得分
整个过程中验证折的数据不会参与众数、标准化统计量的计算,完全符合你要的拆分后再做子集内填充的要求。
会导致泄露的错误写法参考
只有当你把预处理步骤放到Pipeline外侧,在传入GridSearchCV之前就对全量数据集完成填充、标准化操作时,才会出现验证折信息提前泄露的问题,错误示例如下:
# 错误写法:提前在全量数据上做预处理,会引入数据泄露 imputer = SimpleImputer(strategy="most_frequent") scaler = StandardScaler() # 这里fit的时候用到了全量数据(包括后续拆分出的验证折)的统计信息 X_processed = scaler.fit_transform(imputer.fit_transform(X)) clf = LogisticRegression(solver='lbfgs') search = GridSearchCV(clf, param_grid, cv=5, scoring="roc_auc", error_score=0.0) search.fit(X_processed, y)
可选验证方式
如果需要确认流程符合预期,可以手动拆分一折数据,单独计算该折训练集的众数做填充,和Pipeline在对应折输出的填充结果做比对,两者结果完全一致,不会混入全量数据的统计值。
内容的提问来源于stack exchange,提问作者wel
相关产品推荐
相关产品推荐

