Kaggle泰坦尼克任务相同Pipeline处理后特征数不匹配报错排查
Titanic预处理Pipeline特征维度不匹配问题
现有实现
当前基于sklearn搭建数据预处理Pipeline,用于Kaggle入门级Titanic竞赛的数据标准化加工,相关代码如下:
字段定义
dropColumns = ['PassengerId','Name','Ticket','Cabin'] numColumns = ['Age','SibSp','Parch','Fare'] catColumns = ['Sex','Embarked']
数值特征处理Pipeline
num_pipeline = Pipeline([ ('imputer', SimpleImputer(strategy="median")), ('std_scaler', StandardScaler()), ])
全量数据预处理Pipeline
DataPreperationPipeline = ColumnTransformer([ ("num", num_pipeline, numColumns), ("cat", OneHotEncoder(), catColumns), ])
问题现象
使用上述pipeline处理数据后,调用model.predict(test_prepared)执行预测操作时稳定触发报错,所有训练的模型均可复现该问题:
X has 9 features, but model is expecting 10 features as input.
已确认预处理转换前,训练集与测试集的原始特征字段完全一致。
根因分析
问题出在分类特征的缺失值处理逻辑缺失:
- 数值特征通过
num_pipeline中的SimpleImputer做了中位数缺失值填充,但分类特征Embarked没有配置对应的缺失值处理逻辑,直接传入OneHotEncoder做编码。 - Titanic训练集的
Embarked字段存在2条缺失值,pipeline在训练集上做fit_transform时,低版本sklearn的OneHotEncoder会将NaN值识别为一个独立类别,编码后生成4个哑变量列;加上4个数值特征、Sex字段编码生成的2个哑变量列,训练集转换后总特征数为10,模型基于该维度的特征完成训练。 - Titanic测试集的
Embarked字段无缺失值,pipeline转换测试集时,Embarked仅能生成3个哑变量列,最终输出总特征数为9,与模型预期的10个特征维度不匹配,触发报错。
解决方案
可选择以下任意一种方案修复问题:
- 方案1:补全分类特征的缺失值填充逻辑
为分类特征单独构建处理Pipeline,增加众数填充缺失值的步骤,保证训练、测试集的类别数完全一致,代码示例:
# 构建分类特征处理Pipeline cat_pipeline = Pipeline([ ('imputer', SimpleImputer(strategy="most_frequent")), ('onehot', OneHotEncoder()) ]) # 重构全量预处理Pipeline DataPreperationPipeline = ColumnTransformer([ ("num", num_pipeline, numColumns), ("cat", cat_pipeline, catColumns), ])
修改完成后需要在训练集上重新fit整个预处理Pipeline和下游模型,禁止在测试集上fit预处理逻辑,避免数据泄露,保证特征维度统一。
- 方案2:配置OneHotEncoder原生缺失值处理参数
若使用sklearn 1.1及以上版本,可直接通过OneHotEncoder的参数配置缺失值、未知值处理逻辑,无需单独加填充步骤:
DataPreperationPipeline = ColumnTransformer([ ("num", num_pipeline, numColumns), ("cat", OneHotEncoder(handle_unknown='infrequent_if_exist', handle_missing='ignore'), catColumns), ])
- 额外排查项
检查ColumnTransformer的remainder参数配置,确认没有遗漏需要纳入处理的特征(如Titanic数据集常见的Pclass字段);如果配置为remainder='passthrough',需保证训练、推理阶段传入pipeline的原始字段完全一致,无多列、漏列情况。
内容的提问来源于stack exchange,提问作者Sandeep
相关产品推荐
相关产品推荐

