解决机器学习中训练集与测试集特征维度不匹配的常见错误

4次阅读

本文详解因独热编码(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 的标准化范式——它不仅解决当前报错,更是构建鲁棒、可维护、可上线模型的基础保障。

text=ZqhQzanResources