You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用permutation_importance时获取特征名报错及特征重要性顺序异常

问题解决:特征名称获取错误与重要性顺序异常

核心问题分析

  1. StandardScaler无get_feature_names_out方法:StandardScaler本身不提供该方法,你错误地直接调用了数值转换器的该方法,正确方式是通过ColumnTransformer统一获取特征名。
  2. 数据泄露导致重要性异常:你先对全量数据做预处理再拆分训练/测试集,测试集的缩放引入了训练集之外的信息,会干扰模型训练和特征重要性评估。
  3. 特征名与预处理后特征不匹配:手动拼接特征名容易出错,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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 15:03:19