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

将自定义模型包装器传入SHAP KernelExplainer时如何保持特征名称对齐?

将自定义模型包装器传入SHAP KernelExplainer时如何保持特征名称对齐?

这个问题我之前也碰到过,核心原因是你的自定义预测函数没有给SHAP提供特征名称的元数据——SHAP对原生sklearn模型会自动读取feature_names_in_这类属性,但对普通函数就没办法自动识别特征名,所以只能默认用“Feature 1”这种占位符。下面给你两种靠谱的解决办法:

方法一:把包装器改成类,添加特征名称属性

把你的自定义预测逻辑封装成一个类,模仿sklearn模型的结构添加feature_names_in_属性,SHAP会自动识别这个属性并使用对应的特征名:

import shap
import pandas as pd
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
from sklearn.datasets import load_breast_cancer

# 加载数据
data = load_breast_cancer()
X = pd.DataFrame(data.data, columns=data.feature_names)
y = data.target
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 训练模型
model = RandomForestClassifier().fit(X_train, y_train)

# 改成类形式的包装器
class ModelWrapper:
    def __init__(self, model, feature_names):
        self.model = model
        self.feature_names_in_ = feature_names  # SHAP会自动读取这个属性
    
    def predict_proba(self, data):
        # 保持你的标准化输出逻辑
        return self.model.predict_proba(data)

# 初始化包装器并传入特征名
wrapper = ModelWrapper(model, X_train.columns)

# 初始化SHAP解释器
explainer = shap.KernelExplainer(wrapper.predict_proba, shap.sample(X_train, 10))
shap_values = explainer.shap_values(X_test.iloc[:5, :])

# 现在summary_plot会显示正确的特征名
shap.summary_plot(shap_values[1], X_test.iloc[:5, :])

方法二:在summary_plot中手动指定特征名

如果不想修改包装器结构,可以直接在绘制SHAP图的时候通过feature_names参数手动传入列名,这种方式更直接:

# 沿用你原来的代码,只修改绘图部分
shap.summary_plot(shap_values[1], X_test.iloc[:5, :], feature_names=X_test.columns)

额外注意点

  • 确保你传入SHAP的背景数据(shap.sample(X_train, 10))是带列名的DataFrame,而不是numpy数组,这样能避免SHAP在处理过程中丢失特征名关联。
  • 如果你后续还要用其他SHAP绘图函数(比如force_plot),方法一的类包装器会更省心,因为它能让你的包装器和原生sklearn模型有一致的接口,适配更多SHAP功能。

备注:内容来源于stack exchange,提问作者Zümra Arslanhan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.13 18:13:01