本文详解因独热编码(One-Hot Encoding)未统一处理训练集与测试集,导致 model.score() 报错“feature names mismatch”的根本原因及专业解决方案。
本文详解因独热编码(one-hot encoding)未统一处理训练集与测试集,导致 `model.score()` 报错“feature names mismatch”的根本原因及专业解决方案。
在使用 pd.get_dummies() 对分类变量进行独热编码时,一个极易被忽视却高频出现的问题是:对训练集和测试集分别独立调用 get_dummies,会导致二者生成的列名(即特征维度)不一致。正如你在代码中所做:
x_train = pd.get_dummies(x_train) x_test = pd.get_dummies(x_test)
当 x_test 中存在 x_train 未曾出现过的类别值(例如某列 Neighborhood 在测试集中含新区域 "Griffin",而训练集中无此值),pd.get_dummies(x_test) 就会额外生成一列 Neighborhood_Griffin;反之,若某类别仅存在于训练集,则该列在 x_test 中彻底缺失。最终,x_train 和 x_test 的列数与列名无法对齐——这正是 model3.score(x_test, y_test) 抛出 ValueError: The feature names should match those that were passed during fit 的直接原因。
✅ 正确做法是:使用 sklearn.preprocessing.OneHotEncoder 进行可复现、可部署的编码流程,严格遵循「先在训练集上 fit_transform,再用同一编码器对测试集 transform」的原则。该方式能确保:
- 所有类别映射关系仅由训练集决定;
- 测试集中新增类别被自动忽略(默认 handle_unknown='ignore');
- 缺失类别对应位置补零,保持特征空间完全一致。
以下是修正后的关键代码段(精简整合,保留核心逻辑):
from sklearn.preprocessing import OneHotEncoder
from sklearn.compose import ColumnTransformer
from sklearn.pipeline import Pipeline
# 步骤1:识别需编码的类别列(排除数值型目标y及已处理列)
categorical_cols = x_train.select_dtypes(include=['object']).columns.tolist()
# 步骤2:构建预处理器 —— 仅对类别列OneHot编码,其余列保持原样
preprocessor = ColumnTransformer(
transformers=[
('cat', OneHotEncoder(drop='first', handle_unknown='ignore'), categorical_cols)
],
remainder='passthrough', # 数值列直接保留
verbose_feature_names_out=False
)
# 步骤3:将预处理与模型封装为Pipeline(推荐!避免数据泄漏与维度错配)
pipeline = Pipeline([
('preprocessor', preprocessor),
('classifier', KNeighborsClassifier())
])
# 步骤4:拟合 & 评估(x_test 自动完成一致编码)
pipeline.fit(x_train, y_train)
score = pipeline.score(x_test, y_test) # ✅ 不再报错
print(f"Test Accuracy: {score:.4f}")⚠️ 重要注意事项:
- 切勿对 y_train / y_test 使用 pd.get_dummies:你代码中 y_train = pd.get_dummies(y_train) 是严重错误——SalePrice 是连续型回归目标,不是分类标签,独热编码毫无意义且会破坏数据结构;
- 缺失值填充需在编码前完成:你当前先 concat([x_train, home_test]) 再填缺失值,虽可缓解分布偏移,但更稳健的做法是:仅基于 x_train 统计量(均值/众数)填充 x_train 和 x_test,避免测试集信息泄露;
-
始终验证特征对齐:调试阶段可添加断言:
assert list(x_train.columns) == list(x_test.columns), "Feature columns mismatch!"
总结而言,特征工程必须具备「确定性」与「可复现性」。pd.get_dummies() 适用于探索分析,而生产级建模务必采用 OneHotEncoder + Pipeline 的标准化范式——它不仅解决当前报错,更是构建鲁棒、可维护、可上线模型的基础保障。










