机器学习模型训练时特征名称不匹配报错求助
KNeighborsClassifier训练后score报错:特征名不匹配问题解决
问题现象
训练KNeighborsClassifier模型时,执行fit后调用score传入x_test和y_test,触发ValueError:
The feature names should match those that were passed during fit. Feature names seen at fit time, yet now missing:
错误原因分析
- 缺失值处理未生效:定义了
fill_missing_values函数,但实际处理的是原始train数据集,而非拆分后的x_train和x_test,导致后续建模用的特征数据仍存在缺失。 - 独热编码不一致:分别对
x_train和x_test执行pd.get_dummies,两个数据集的类别特征取值可能存在差异,生成的特征列数量、名称无法匹配,这是特征不匹配的核心原因。 - 任务类型与模型不匹配:
SalePrice是连续型房价数据,属于回归任务,但使用了分类模型KNeighborsClassifier,还错误地对目标变量y_train、y_test做了独热编码,完全偏离任务需求。
修正方案与代码
修正思路
- 回归任务改用
KNeighborsRegressor模型 - 基于训练集统计量填充缺失值,避免数据泄露
- 合并训练/测试集后做独热编码,保证特征一致性
修正后代码
## 首个个人机器学习项目 import pandas as pd import numpy as np import matplotlib.pyplot as plt import sklearn from sklearn.linear_model import LogisticRegression from sklearn.neighbors import KNeighborsRegressor # 替换为回归模型 from sklearn.ensemble import RandomForestClassifier from sklearn.model_selection import train_test_split, cross_val_score from sklearn.model_selection import RandomizedSearchCV, GridSearchCV from sklearn.metrics import confusion_matrix, classification_report from sklearn.metrics import precision_score, recall_score, f1_score from sklearn.metrics import mean_absolute_error, mean_squared_error # 回归评估指标 # 读取数据 train = pd.read_csv("/Users/ahmeteminguney/Desktop/house/train.csv") home_test = pd.read_csv("/Users/ahmeteminguney/Desktop/house/test.csv") home_result = pd.read_csv("/Users/ahmeteminguney/Desktop/house/sample_submission.csv") # 拆分特征与目标变量 x = train.drop("SalePrice", axis=1) y = train["SalePrice"] # 划分训练集与测试集 x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2) # 识别所有存在缺失值的特征列(基于合并后的特征集) all_features = pd.concat([x_train, x_test]) missing_columns = all_features.columns[all_features.isnull().any()].tolist() def fill_missing_values(data, train_data): data_copy = data.copy() # 避免修改原数据 for column in missing_columns: if data_copy[column].dtype in ['float64', 'int64']: # 用训练集均值填充,防止数据泄露 data_copy[column].fillna(train_data[column].mean(), inplace=True) else: # 用训练集众数填充 data_copy[column].fillna(train_data[column].mode()[0], inplace=True) return data_copy # 填充训练集与测试集的缺失值 x_train_filled = fill_missing_values(x_train, x_train) x_test_filled = fill_missing_values(x_test, x_train) # 合并后做独热编码,保证特征一致 all_encoded = pd.get_dummies(pd.concat([x_train_filled, x_test_filled]), drop_first=True) # 拆分回训练集与测试集编码后的数据 x_train_encoded = all_encoded[:len(x_train_filled)] x_test_encoded = all_encoded[len(x_train_filled):] # 初始化回归模型并训练 model3 = KNeighborsRegressor() model3.fit(x_train_encoded, y_train) # 评估模型 r2_score = model3.score(x_test_encoded, y_test) print(f"模型R²分数: {r2_score}") # 可选:计算回归任务常用评估指标 y_pred = model3.predict(x_test_encoded) mae = mean_absolute_error(y_test, y_pred) mse = mean_squared_error(y_test, y_pred) rmse = np.sqrt(mse) print(f"平均绝对误差(MAE): {mae}") print(f"均方误差(MSE): {mse}") print(f"均方根误差(RMSE): {rmse}")
关键修正说明
- 模型适配任务:回归任务使用
KNeighborsRegressor,无需对连续型目标变量做独热编码。 - 缺失值填充规范:用训练集的统计量填充测试集,避免测试集信息泄露到训练流程中。
- 特征一致性保障:合并训练/测试集后执行独热编码,确保两者特征列完全匹配,彻底解决特征名不匹配的问题。
内容的提问来源于stack exchange,提问作者Emin
相关产品推荐
相关产品推荐

