如何在含ColumnTransformer的sklearn Pipeline中正确实现LightGBM早停验证
如何在Pipeline中正确配置带早停验证的LightGBM模型
问题背景
需要搭建集成早停验证的LightGBM模型,并用Pipeline整合预处理与模型拟合、预测流程,但运行代码时触发数据类型错误。
原始代码
coltransformer = ColumnTransformer([ ('cat', OneHotEncoder(sparse_output = False), cat_invar), ('num', 'passthrough', num_invar)]) lgbPipe = Pipeline([ ('preprocess', coltransformer), ('lgb', LGBMClassifier())]) X_learn, X_val, Y_learn, Y_val = train_test_split(X, y, test_size = 0.2) lgbPipe.fit(X_learn, Y_learn, lgb__eval_set = (X_val, Y_val))
错误信息
ValueError: DataFrame.dtypes for data must be int, float or bool. Did not expect the data types in the following fields: Geography, Gender, Surname
问题根源
直接将原始验证集X_val传入lgb__eval_set时,LightGBM会读取未经过Pipeline预处理的原始数据——其中的分类特征未完成编码,不符合模型对输入数据类型的要求。
解决方案
必须先用Pipeline中已拟合的预处理组件转换验证集,再传入早停验证参数,以下是两种规范实现方式:
方式一:分步处理验证集(直观易懂)
coltransformer = ColumnTransformer([ ('cat', OneHotEncoder(sparse_output = False), cat_invar), ('num', 'passthrough', num_invar)]) lgbPipe = Pipeline([ ('preprocess', coltransformer), ('lgb', LGBMClassifier())]) X_learn, X_val, Y_learn, Y_val = train_test_split(X, y, test_size = 0.2) # 先拟合预处理组件,转换训练集和验证集 lgbPipe.named_steps['preprocess'].fit(X_learn) X_learn_proc = lgbPipe.named_steps['preprocess'].transform(X_learn) X_val_proc = lgbPipe.named_steps['preprocess'].transform(X_val) # 传入处理后的验证集开启早停训练 lgbPipe.named_steps['lgb'].fit( X_learn_proc, Y_learn, eval_set=[(X_val_proc, Y_val)], early_stopping_rounds=50, # 连续50轮无提升则停止训练,可按需调整 verbose=10 # 可选,打印训练进度 )
方式二:保留Pipeline完整性(更符合工程规范)
from sklearn.pipeline import Pipeline from sklearn.compose import ColumnTransformer from sklearn.preprocessing import OneHotEncoder from sklearn.model_selection import train_test_split import lightgbm as lgb coltransformer = ColumnTransformer([ ('cat', OneHotEncoder(sparse_output = False), cat_invar), ('num', 'passthrough', num_invar)]) lgbPipe = Pipeline([ ('preprocess', coltransformer), ('lgb', LGBMClassifier())]) X_learn, X_val, Y_learn, Y_val = train_test_split(X, y, test_size = 0.2) # 先拟合预处理组件 lgbPipe.named_steps['preprocess'].fit(X_learn) # 转换验证集 X_val_proc = lgbPipe.named_steps['preprocess'].transform(X_val) # 拟合整个Pipeline,传入处理后的验证集 lgbPipe.fit( X_learn, Y_learn, lgb__eval_set=[(X_val_proc, Y_val)], lgb__early_stopping_rounds=50, lgb__verbose=10 )
关键注意事项
early_stopping_rounds是早停功能的核心参数,需根据任务需求调整阈值;- 确保
cat_invar和num_invar分别准确对应分类特征、数值特征的列名列表,避免预处理漏项或错项。
内容的提问来源于stack exchange,提问作者PingPong
相关产品推荐
相关产品推荐

