使用permutation_importance时获取特征名报错及特征重要性顺序异常
问题解决:特征名称获取错误与重要性顺序异常
核心问题分析
StandardScaler无get_feature_names_out方法:StandardScaler本身不提供该方法,你错误地直接调用了数值转换器的该方法,正确方式是通过ColumnTransformer统一获取特征名。- 数据泄露导致重要性异常:你先对全量数据做预处理再拆分训练/测试集,测试集的缩放引入了训练集之外的信息,会干扰模型训练和特征重要性评估。
- 特征名与预处理后特征不匹配:手动拼接特征名容易出错,
ColumnTransformer的get_feature_names_out能保证特征名顺序与预处理后数据完全对应。
修正后的代码
import numpy as np import pandas as pd from sklearn.compose import ColumnTransformer from sklearn.preprocessing import OneHotEncoder, StandardScaler from sklearn.neighbors import KNeighborsRegressor from sklearn.model_selection import train_test_split from sklearn.inspection import permutation_importance # 准备数据(假设df已加载) X = df[['age', 'bmi', 'sex', 'smoker']] y = df['charges'] # 1. 先拆分数据,避免泄露 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) # 定义预处理管道 categorical_transformer = OneHotEncoder(drop='first', sparse_output=False) # 新版sklearn用sparse_output替代sparse numerical_transformer = StandardScaler() preprocessor = ColumnTransformer( transformers=[ ('num', numerical_transformer, ['age', 'bmi']), ('cat', categorical_transformer, ['sex', 'smoker']) ] ) # 2. 仅用训练集拟合预处理,转换训练/测试集 X_train_preprocessed = preprocessor.fit_transform(X_train) X_test_preprocessed = preprocessor.transform(X_test) # 3. 通过ColumnTransformer直接获取正确的特征名 feature_names = preprocessor.get_feature_names_out() # 训练模型 knn_regressor = KNeighborsRegressor(n_neighbors=5) # 可调整n_neighbors优化性能 reg_model = knn_regressor.fit(X_train_preprocessed, y_train) # 计算置换重要性 results = permutation_importance( reg_model, X_test_preprocessed, y_test, n_repeats=20, # 增加重复次数提升稳定性 random_state=42, scoring='neg_mean_squared_error' ) # 按重要性排序输出 sorted_indices = np.argsort(results.importances_mean)[::-1] for i in sorted_indices: print(f"Feature '{feature_names[i]}': Importance: {results.importances_mean[i]:.4f}")
关键修正点说明
- 数据拆分顺序调整:先拆分再预处理,确保测试集的缩放仅基于训练集的均值和标准差,彻底避免数据泄露。
- 特征名获取方式修正:用
preprocessor.get_feature_names_out()直接获取所有预处理后的特征名,自动对应数值特征(如num__age、num__bmi)和编码后的分类特征(如cat__sex_male、cat__smoker_yes),完全匹配预处理后数据的列顺序。 - 参数优化:
- 将
OneHotEncoder的sparse参数改为sparse_output(新版sklearn已弃用sparse)。 - 增加
permutation_importance的n_repeats到20,让重要性结果更稳定。 - 显式指定
KNeighborsRegressor的n_neighbors,方便后续调优。
- 将
关于重要性顺序的补充说明
如果修正后仍与预期顺序有差异,可从以下方向排查:
- KNN的特性:KNN是基于距离的模型,特征的缩放会影响距离计算,虽然已经做了标准化,但如果特征的分布差异大,仍可能影响重要性。
- 特征编码方式:
OneHotEncoder(drop='first')会丢弃一个分类特征的水平,比如sex特征会只剩一个编码列(如sex_male),该列的重要性代表的是该分类水平相对于基准水平的影响。 - 评估指标:你使用的是
neg_mean_squared_error,置换重要性的数值代表打乱该特征后模型MSE的上升幅度(数值越大,特征越重要),确认你手动绘图时是否用了相同的评估逻辑。
内容的提问来源于stack exchange,提问作者statsbeginner
相关产品推荐
相关产品推荐

