Sklearn管道输出多余列及归一化列含空值问题排查
一、空值问题根源
原数据缺失值未转为标准NaN
UCI的processed.cleveland.data里缺失值用?表示,pandas默认会把这类值识别为字符串而非空值。如果你的中位数填充用的是SimpleImputer(strategy='median'),它只处理np.nan类型的空值,对?无效,导致填充后仍有缺失值。
解决:读取数据时指定na_values='?',或者手动替换:df.replace('?', np.nan, inplace=True)数值变量与分类变量划分错误
你手动将某些数值列转为字符串,如果转的过程中遗漏了部分含?的数值列,这些列会被误归为分类变量,而真正的数值变量里仍有未处理的缺失值;反之,若本应是数值的列被错误划为分类变量,中位数填充不会作用于它,后续归一化自然会有空值。
验证:打印numerical_features和categorical_features列表,确认划分完全正确。
二、多余列问题根源
ColumnTransformer的remainder参数未设置
ColumnTransformer默认remainder='warn',即未被任何转换器匹配的列会被直接保留在输出结果中。如果你的特征列没有被完全覆盖在numerical_features和categorical_features里,这些未处理的原列会被追加到输出,造成多余列。
解决:明确设置remainder='drop',丢弃未处理的列:ColumnTransformer( transformers=[ ('cat', cat_pipeline, categorical_features), ('num', num_pipeline, numerical_features) ], remainder='drop' # 关键设置 )独热编码生成了额外类别列
如果分类变量里原本包含?(未提前处理为NaN),众数填充后?会被当成一个有效类别,OneHotEncoder会为其生成额外列。另外,OneHotEncoder默认drop=None,会保留所有类别列,若不需要全类别,可设置drop='first'避免多重共线性,但这会减少一列,需根据需求调整。
验证:查看独热编码后的列名(用get_feature_names_out()),确认是否包含意外的类别(比如?对应的列)。重复处理同一列
若numerical_features和categorical_features有重叠列,ColumnTransformer会对同一列执行两次转换,最终输出里会同时存在数值处理后的列和独热编码后的列,造成多余。
验证:检查两个特征列表是否有交集:print(set(numerical_features) & set(categorical_features))
三、管道顺序验证
确保数值变量的管道顺序是先填充再归一化,如果反过来,先归一化再填充,归一化时的空值会导致后续填充无效:
num_pipeline = Pipeline([ ('imputer', SimpleImputer(strategy='median')), ('scaler', MinMaxScaler()) ])
内容的提问来源于stack exchange,提问作者EngineerP

