多分类模型的 SHAP 特征贡献图及其衍生可视化绘制

机器学习关系型数据库微服务

picture.image

背景

在机器学习中,SHAP是一种用于解释模型输出的重要工具,它为每个特征分配一个贡献值,表示该特征对模型输出的影响程度,然而,对于多分类模型与二分类模型的SHAP分析,存在一些重要区别——多分类模型的 SHAP 分析为每个类别单独计算一组特征贡献值,而二分类模型通常只计算正类或目标类的贡献(并不是绝对如RF模型也会计算二分类各类别的shap值),由于多分类模型需要为每个类别单独计算一组 SHAP 值,而二分类模型通常只关注正类(或目标类)的特征贡献,因此两者的可视化方式有所不同。以下展示将展示多分类模型下的shap特征贡献图绘制

代码实现

数据处理


          
import pandas as pd
          
import numpy as np
          
import matplotlib.pyplot as plt
          
from sklearn.model_selection import train_test_split
          
plt.rcParams['font.family'] = 'Times New Roman'
          
plt.rcParams['axes.unicode_minus'] = False
          
import warnings
          
warnings.filterwarnings("ignore")
          
df = pd.read_excel('2024-10-30-公众号Python机器学习AI.xlsx')
          
from sklearn.model_selection import train_test_split
          
# 分割数据集
          
X = df.drop(['Type'], axis = 1)
          
y = df['Type']
          
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.3,
          
                                            stratify=df['Type']) #分离训练集和测试集
      

加载数据,并将数据集中特征与标签分离后,将其按7:3比例分为训练集和测试集,确保测试集按标签类别进行分层抽样

模型构建


          
from sklearn.ensemble import RandomForestClassifier
          
# 创建随机森林分类器实例,并设置参数
          
rf = RandomForestClassifier(
          
    n_estimators=100,         # 森林中树的数量。默认是100。
          
    criterion='gini',          # 指定用于拆分的质量指标。可选'gini'或'entropy'。
          
    max_depth=None,           # 每棵树的最大深度。'None'表示不限制。
          
    min_samples_split=2,      # 节点分裂所需的最小样本数。默认是2。
          
    min_samples_leaf=1,       # 叶子节点所需的最小样本数。默认是1。
          
    min_weight_fraction_leaf=0.0, # 类似'min_samples_leaf',但基于样本权重。默认0.0。
          
    random_state=42,          # 控制随机数生成,以便结果可复现。
          
    max_leaf_nodes=None,      # 限制每棵树的最大叶子节点数。'None'表示不限制。
          
    min_impurity_decrease=0.0 # 节点分裂时要求的最小不纯度减少量。默认0.0。
          
)
          
# 训练分类器
          
rf.fit(X_train, y_train)
      

创建并配置了一个多分类随机森林分类器,并使用训练数据对其进行模型训练

shap值计算整理


          
import shap
          
explainer = shap.TreeExplainer(rf)
          
# 计算shap值为numpy.array数组
          
shap_values = explainer.shap_values(X_test)
          
# 提取每个类别的 SHAP 值
          
shap_values_class_0 = shap_values[:, :, 0]
          
shap_values_class_1 = shap_values[:, :, 1]
          
shap_values_class_2 = shap_values[:, :, 2]
          
shap_values_class_3 = shap_values[:, :, 3]
          
shap_values_class_4 = shap_values[:, :, 4]
          
# 计算每个类别的特征贡献度
          
importance_class_0 = np.abs(shap_values_class_0).mean(axis=0)
          
importance_class_1 = np.abs(shap_values_class_1).mean(axis=0)
          
importance_class_2 = np.abs(shap_values_class_2).mean(axis=0)
          
importance_class_3 = np.abs(shap_values_class_3).mean(axis=0)
          
importance_class_4 = np.abs(shap_values_class_4).mean(axis=0)
          
importance_df = pd.DataFrame({
          
    'Class_0': importance_class_0,
          
    'Class_1': importance_class_1,
          
    'Class_2': importance_class_2,
          
    'Class_3': importance_class_3,
          
    'Class_4': importance_class_4
          
}, index=X_train.columns)
          
type_mapping = {
          
    0: 'Type_A',
          
    1: 'Type_B',
          
    2: 'Type_C',
          
    3: 'Type_D',
          
    4: 'Type_E'
          
}
          
importance_df.columns = [type_mapping[int(col.split('_')[1])] for col in importance_df.columns]
          
importance_df
      

picture.image

使用SHAP计算训练好的多分类随机森林模型对测试数据的特征贡献度,首先,TreeExplainer 用于解释模型,并生成每个类别的 SHAP 值,接着,提取每个类别(Class_0 到 Class_4)的 SHAP值,并计算了各类别下每个特征的平均贡献度(取 SHAP 值绝对值的均值),最终,这些贡献度被存储在一个 DataFrame 中,并将类别索引映射为具体的类别名称(Type_A 到 Type_E),为后续分析提供可解释的特征重要性表

不同类别下特征重要性的堆叠柱状图展示


          
import seaborn as sns
          
importance_df['row_sum'] = importance_df.sum(axis=1)
          
sorted_importance_df = importance_df.sort_values(by='row_sum', ascending=True)
          
sorted_importance_df = sorted_importance_df.drop(columns=['row_sum'])
          
elements = sorted_importance_df.index
          
colors = sns.color_palette("Set2", n_colors=len(sorted_importance_df.columns))
          
fig, ax = plt.subplots(figsize=(12, 6), dpi=1200)
          
bottom = np.zeros(len(elements))
          
for i, column in enumerate(sorted_importance_df.columns):
          
    ax.barh(
          
        sorted_importance_df.index,    
          
        sorted_importance_df[column],  
          
        left=bottom,                   
          
        color=colors[i],               
          
        label=column                   
          
)
          
    bottom += sorted_importance_df[column]
          
ax.set_xlabel('mean(|SHAP value|) (average impact on model output magnitude)', fontsize=12)
          
ax.set_ylabel('Features', fontsize=12)
          
ax.set_title('Feature Importance by Class', fontsize=15)
          
ax.set_yticks(np.arange(len(elements)))
          
ax.set_yticklabels(elements, fontsize=10)
          
for i, el in enumerate(elements):
          
    ax.text(bottom[i], i, ' ' + str(el), va='center', fontsize=9)
          
ax.legend(title='Class', fontsize=10, title_fontsize=12)
          
ax.set_yticks([])
          
ax.set_yticklabels([])
          
ax.set_ylabel('')
          
ax.spines['top'].set_visible(False)
          
ax.spines['right'].set_visible(False)
          
plt.savefig('1.pdf', format='pdf', bbox_inches='tight')
          
plt.show()
      

picture.image

使用 Seaborn 和 Matplotlib 绘制一个 堆叠水平柱状图,展示多分类模型中各特征在不同类别下的平均 SHAP 值的重要性,首先,将每个特征在所有类别中的 SHAP 值求和排序,以确定特征的重要性顺序,接着,依次为每个类别绘制水平条形,并通过堆叠方式展示每个类别对特征的重要性贡献,图例用于标明不同类别的颜色对应关系,最终图形美化去除了多余的坐标轴刻度,下面为一个二分类模型的shap特征贡献图

picture.image

通过这两张图的直观对比,我们可以发现:二分类模型的 SHAP 特征贡献图(第一张图)展示的是特征对整体目标类预测的影响,而多分类模型的 SHAP 特征贡献图(第二张图)将每个特征在不同类别中的贡献分开显示,更详细地揭示了特征在各类别间的差异性,也就是前面所说的由于任务不同导致其可视化也存在差异

多分类模型特征贡献图其它绘制方法

picture.image

与之前的堆叠柱状图相比,采用3D 柱状图来展示特征在不同类别中的贡献度,提供更立体的视觉效果,使我们能够从不同视角分析特征在各类别中的影响,相比之下,3D 图更直观,但在特征和类别较多时可能增加视觉复杂度,而堆叠柱状图更适合快速比较各类别的相对贡献,代码获取:如果您希望获取本文展示的改进版代码,请添加作者微信联系获取

🎁 赠书活动来啦! 🎁

picture.image

picture.image

支持知识分享,畅享学习乐趣!即日起,只需 点赞在看转发 此文章,作者将从后台随机抽取一位幸运儿,免费包邮赠送《细说机器学习:从理论到实践》这本精彩书籍📚!

💡 赶快参与,一键三连,说不定你就是那位幸运读者哦!

往期推荐

SCI图表复现:整合数据分布与相关系数的高级可视化策略

SCI图表:基于相关性和标准差的多模型评价——泰勒图解析

SCI图表复现:利用小提琴图折线图综合展示训练集、验证集、测试集模型性能对比

复现SCI文章 SHAP 依赖图可视化以增强机器学习模型的可解释性

SCI图表复现:优化SHAP特征贡献图展示更多模型细节

复现 Nature 图表——基于PCA的高维数据降维与可视化实践及其扩展

复现 Nature 图表可视化——基于模型残差分析与显著性检验的模型解释

SCI图表复现:特征相关性气泡热图展示

期刊文章配图:斯皮尔曼相关系数热图反应非线性变量相关性

picture.image

picture.image

picture.image

微信号|deep_ML

欢迎添加作者微信进入Python、ChatGPT群

进群请备注Python或AI进入相关群

无需科学上网、同步官网所有功能、使用无限制

如果你对类似于这样的文章感兴趣。

欢迎关注、点赞、转发~

个人观点,仅供参考

0
0
0
0
评论
未登录
看完啦,登录分享一下感受吧~
暂无评论