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

DeepSHAP蜂群图仅显蓝色点无颜色梯度的问题求助

问题描述

我参考SHAP Deep Explainer示例,使用泰坦尼克数据集开展实验,自行用shap.summary_plot(shap_values[0], feature_names = test_data.columns)生成蜂群图时,图中仅显示蓝色点,无侧边梯度标尺,和官方示例的蓝红梯度着色效果不符。实验代码如下:

# import package
import shap
import numpy as np 
import pandas as pd 
import matplotlib.pyplot as plt
from sklearn.preprocessing import StandardScaler
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Dropout
from tensorflow.keras import optimizers
import warnings 
warnings.filterwarnings('ignore')
%matplotlib inline
import os
# load data
os.chdir('/titanic/')
train_data = pd.read_csv('./train.csv', index_col=0)
test_data = pd.read_csv('./test.csv', index_col=0)
train_data.head()

def data_preprocessing(df):
    df = df.drop(columns=['Name', 'Ticket', 'Cabin'])
    
    # fill na
    df[['Age']] = df[['Age']].fillna(value=df[['Age']].mean())
    df[['Embarked']] = df[['Embarked']].fillna(value=df['Embarked'].value_counts().idxmax())
    df[['Fare']] = df[['Fare']].fillna(value=df[['Fare']].mean())
    
    # categorical features into numeric
    df['Sex'] = df['Sex'].map( {'female': 1, 'male': 0} ).astype(int)
    
    # one-hot encoding
    embarked_one_hot = pd.get_dummies(df['Embarked'], prefix='Embarked')
    df = df.drop('Embarked', axis=1)
    df = df.join(embarked_one_hot)
    
    return df

# train data processing
train_data = data_preprocessing(train_data)
train_data.isnull().sum()
# create data for training
x_train = train_data.drop(['Survived'], axis=1).values
# Check test data
test_data.isnull().sum()
# scale
scale = StandardScaler()
x_train = scale.fit_transform(x_train)
# prepare y_train
y_train = train_data['Survived'].values
test_data = data_preprocessing(test_data)
x_test = test_data.values.astype(float)
# scaling
x_test = scale.transform(x_test)
# Check test data
test_data.isnull().sum()

# build mlp
model = Sequential()
model.add(Dense(32, input_dim=x_train.shape[1], activation='relu'))
model.add(Dropout(0.25))
model.add(Dense(128, activation='relu'))
model.add(Dropout(0.25))
model.add(Dense(32, activation='relu'))
model.add(Dropout(0.25))
model.add(Dense(8, activation='relu'))
model.add(Dropout(0.25))
model.add(Dense(2, activation='softmax'))
# compile model
model.compile(loss='sparse_categorical_crossentropy', optimizer = 'adam', metrics = ['accuracy'])
# fit model
model.fit(x_train, y_train, epochs=10, batch_size=64)

# compute SHAP values
explainer = shap.DeepExplainer(model, x_train)
shap_values = explainer.shap_values(x_test)

shap.summary_plot(shap_values[0], plot_type = 'bar', feature_names = test_data.columns)

shap.initjs()
shap.force_plot(explainer.expected_value[0].numpy(), shap_values[0][0], features = test_data.columns)

shap.decision_plot(explainer.expected_value[0].numpy(), shap_values[0][0], features = test_data.iloc[0,:], feature_names = test_data.columns.tolist())

shap.plots._waterfall.waterfall_legacy(explainer.expected_value[0].numpy(), shap_values[0][0], feature_names = test_data.columns)
原因分析

出现该问题的核心原因是未向shap.summary_plot()传入用于着色的原始特征值:

  • 官方示例中,summary_plot默认用原始特征值给点着色,以此展示特征值高低对SHAP值的影响;
  • 仅传入SHAP值和特征名时,SHAP无法获取原始特征的数值分布,只能默认用SHAP值本身作为着色依据。而二分类任务的SHAP值分布可能集中在某一区间,导致视觉上呈现单一蓝色,且缺失对应特征值的梯度标尺;
  • 另外,你使用标准化后的x_test计算SHAP值,但着色需要的是预处理后未标准化的原始特征数值,标准化后的数据分布被压缩,也会影响着色效果。
解决办法

修改shap.summary_plot()的调用代码,传入未标准化的原始特征数据作为features参数:

# 使用预处理后未标准化的test_data作为features传入
shap.summary_plot(shap_values[0], features=test_data, feature_names=test_data.columns)

补充说明:

  • test_data是经过data_preprocessing()处理后的数据集(包含编码后的分类特征、填充后的数值特征,但未做StandardScaler标准化),保留了特征的原始数值分布,能让SHAP根据特征值高低生成蓝红梯度的着色;
  • 需确保传入的features和计算SHAP值时的x_test样本一一对应,避免样本顺序错乱;
  • 若想指定特定特征用于着色,可以额外添加feature_index参数,默认使用所有特征的数值分布即可。

内容的提问来源于stack exchange,提问作者natnicha teja

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 10:55:15