sklearn Pipeline执行score时报数据集列数与fit时不匹配错误如何解决?
问题原因
- 核心原因是你自定义的
BrandTransformer、NumberOfOwnersTransformer、EnginePropertiesTransformer等转换器,在fit方法中使用了inplace修改逻辑,直接改动了传入的原始X_trainDataFrame。pipeline.fit执行完成后,你代码里的X_train变量已经被修改为转换后的列结构,因此第一次调用pipeline.score(X_train, y_train)时,传入的是已经适配转换规则的数据,可以正常返回结果。 - 而
X_test、X_train.head(10)这类数据都是未被修改过的原始列结构,传入pipeline后经过转换得到的列数,和fit阶段转换器记录的列数不一致,就触发了列数不匹配的报错。 - 额外需要注意:你使用的带
variables参数的OneHotEncoder属于Feature-engine库的实现,请确认没有开启drop_last等会动态修改列数的参数,同时确认所有自定义转换器的transform方法没有意外删除必要列。
解决方案
- 修改所有自定义转换器的
fit和transform方法,禁止inplace修改输入数据,处理前先对输入做拷贝:
- 修改所有自定义转换器的
def fit(self, X, y=None): X = X.copy() # 新增拷贝逻辑,不改动原始输入 # 原有fit统计逻辑保留
transform方法也同样先做输入拷贝再处理,避免修改原始传入的数据。
- 修复变量名笔误:你代码中定义的pipeline变量名为
pipeline,但调用score时用的是car_pipeline,请确认变量名统一,避免调用了错误的pipeline实例。
- 修复变量名笔误:你代码中定义的pipeline变量名为
- 验证转换列数一致性:可以单独调用pipeline除模型外的前置步骤,对比不同输入转换后的列数:
# 输出全量训练集转换后的形状 print(pipeline[:-1].transform(X_train.copy()).shape) # 输出测试集转换后的形状 print(pipeline[:-1].transform(X_test.copy()).shape)
两者列数必须完全一致,如果存在差异可以逐步定位出是哪个转换器步骤导致的列数变化。
内容的提问来源于stack exchange,提问作者Robin
相关产品推荐
相关产品推荐

