Python 中的 SHAP 简介

news2024/11/24 11:15:18

本文中有多篇计划文章,后期会补充相关链接。鉴于公众号内无法后期修改文章,请关注原文链接。

如何创建和解释 SHAP 图:瀑布图、力图、平均 SHAP 图、蜂群图和依赖图

可直接在橱窗里购买,或者到文末领取优惠后购买:

在这里插入图片描述

SHAP 是用于理解和调试模型的最强大的 Python 包。它可以告诉我们每个模型特征对单个预测的贡献。通过汇总 SHAP 值,我们还可以了解多个预测的趋势。只需几行代码,我们就能识别和可视化模型中的重要关系。

我们将介绍用于计算和显示 SHAP 值的代码。其中包括对以下 SHAP 图的解释:

  • Waterfall Plot
  • Force Plot
  • Mean SHAP Plot
  • Beeswarm Plot
  • Dependence Plot

我们针对预测连续目标变量的模型执行此操作。如果你需要分类的解释,日后会专门写相关文章,届时可以参阅 [[二元和多类目标变量的 SHAP]],你可以在 GitHub1 上找到完整的项目。

数据集

为了演示 SHAP 包,我们将使用包含 4,177 个观测值的「鲍鱼数据集」2。下面,你可以看到我们的数据集的快照。鲍鱼是一种贝类美食。我们想使用数据集来预测它们的年龄。更具体地说,我们的目标变量是鲍鱼壳中的环数。我们将使用shell lengthshell diameter 和鲍鱼的 whole weight 等特征。

在这里插入图片描述

在下图中,我们直观地展示了一些特征与目标变量之间的关系。 Shucked weight 是鲍鱼肉的重量(即从壳中取出后的重量)。我们可以看到,去壳重量增加时,环的数量往往会增加。这是有道理的,因为我们认为年龄较大的鲍鱼会更大,肉也更多。

在这里插入图片描述

我们还可视化了鲍鱼的性别,这是一个分类特征。在模型中使用此功能之前,我们需要使用 One-Hot 编码对其进行转换。正如你所看到的,这会导致每个生成的二进制特征都有一个单独的 SHAP 值。这使得很难理解原始分类特征的整体贡献。我们将在后面专门写一篇文章「[[分类特征的 SHAP]]」探讨一种解决方案。

对于最后一点数据探索,我们为连续特征创建一个相关矩阵。 可以看到,我们正在处理高度相关的特征。 长度和直径完全相关。 同样,全重与其他重量测量值也高度相关。 例如肉的重量(去壳重量)和除去肉的外壳重量(外壳重量)。

image-20240727212937534

我们在下面导入必要的 Python 包。我们有一些用于管理和可视化数据的标准库(第 4-9 行)。XGBoost 用于对目标变量进行建模(第 13 行),我们导入一些包来评估我们的模型(第 14 行)。最后,我们导入 SHAP 包(第 16 行)。我们初始化包(第 17 行)。这样我们就可以在笔记本中显示一些 SHAP 图。

import warnings
warnings.filterwarnings("ignore")

import pandas as pd
import numpy as np

import matplotlib.pyplot as plt
%matplotlib inline
plt.style.use('default')

import seaborn as sns

import xgboost as xgb
from sklearn.metrics import accuracy_score,confusion_matrix

import shap
shap.initjs()

import os
dp = os.environ.get('pub_data')

建模

我们使用数据探索来指导特征工程。首先,我们从 X 特征矩阵中删除长度和整体重量(第 10-11 行)。我们发现这些与其他特征完美相关。

# import dataset
df = pd.read_csv(dp + 
'Abalone dataset/abalone.data',
names=[
"sex",
"length",
"diameter",
"height",
"whole weight",
"shucked weight",
"viscera weight",
"shell weight",
"rings",
],
)

# Get features
y = df["rings"]
X = df[["sex", "length", "height", "shucked weight", "viscera weight", "shell weight"]]

我们看到性别是一个分类特征。在将其用于模型之前,我们需要将其转换为 3 个虚拟变量(第 2-4 行)。然后,我们从特征矩阵中删除原始特征(第 5 行)。

# create dummy variables
y = y.copy()
X = X.copy()

X.loc[:, 'sex.M'] = X['sex'].apply(lambda s: 1 if s == 'M' else 0)
X.loc[:, 'sex.F'] = X['sex'].apply(lambda s: 1 if s == 'F' else 0)
X.loc[:, 'sex.I'] = X['sex'].apply(lambda s: 1 if s == 'I' else 0)
X = X.drop("sex", axis=1)

我们现在有 8 个模型特征。你可以在下面看到这些特征的快照。

image-20240727211024925

现在,我们可以训练一个用于预测鲍鱼壳环数的模型。由于我们的目标变量是连续的,因此我们使用XGBRegressor(第 2 行)。我们在整个特征集上训练模型(第 3 行)。

# train model
model = xgb.XGBRegressor(objective="reg:squarederror")
model.fit(X, y)

这个模型应该足以演示 SHAP 包。我们可以通过使用图 3 中的散点图对其进行评估来看到这一点。我们正在将模型的预测(第 2 行)与实际环数进行比较。红线给出了如果我们有完美预测的值。

图 3:实际环数与预测环数的散点图

**注意:**我们没有在模型上投入太多精力。除非你使用 SHAP 进行数据探索,否则你应该始终使用最佳实践。你的模型越好,你的 SHAP 分析就越可靠。

SHAP 图

最后,我们可以使用 SHAP 值来解释这个模型。为此,我们将模型传递给 shap.Explainer 器函数(第 2 行)。这将创建一个解释器对象。我们使用它来计算特征矩阵中每个观测值的 SHAP 值(第 3 行)。

# get shap values
explainer = shap.Explainer(model)
shap_values = explainer(X)

图 1:Waterfall

特征矩阵中的 4,177 个观测值中的每一个都有 8 个 SHAP 值。也就是说,我们模型中的每个特征都有一个 SHAP 值。我们可以使用 waterfall 函数来可视化第一个观测值的 SHAP 值(第 2 行)。

# Waterfall plot for first observation
shap.plots.waterfall(shap_values[0])

E[f(x)] = 9.933 给出了所有 4,177 只鲍鱼的平均预测环数。f (x) = 12.668是这只鲍鱼的预测环数。SHAP 值是介于两者之间的所有值。例如,去壳重量使预测环数增加了1.68

图 4:第一次观察的瀑布图

我们数据集中的每个观测/鲍鱼都会有一个独特的瀑布图。它们都可以用与上述相同的方式进行解释。在每种情况下,SHAP 值告诉我们与平均预测相比,特征对预测的贡献如何。较大的正/负值表示该特征对模型的预测有显著影响。

图 2:Force Plot

另一种可视化方法是使用力图。你可以将其视为浓缩的瀑布图。我们从相同的基值9.933开始,你可以看到每个特征对最终预测 13.04 的贡献。

# Forceplot for first observation
shap.plots.force(shap_values[0])

在这里插入图片描述

图 3:叠加 Force Plot

瀑布图和力图非常适合解释单个预测。要了解我们的模型如何进行总体预测,我们需要汇总 SHAP 值。一种方法是使用堆叠力图

我们可以将多个力图组合在一起以创建堆叠力图。在这里,我们在力图函数中传递前 100 个观测值的 SHAP 值。每个单独的力图现在都是垂直的并且并排堆叠。

shap.plots.force(shap_values[0:100])

你可以在下面看到此图是交互式的。我们还可以更改图的顺序并选择要显示的特征贡献。

在这里插入图片描述

例如,在下面的图中我们有:

仅显示壳重量的 SHAP 值(y 轴 = **shell weight effects

按壳重量特征值对力图进行排序(x 轴 = **shell weight

从该图中我们可以看出,随着壳重的增加,SHAP 值也会增加。换句话说,年龄较大的鲍鱼壳往往更重。

图 7:壳体重量的堆叠力图

这是了解我们的模型所捕获关系的性质的一种方法。我们将看到蜂群图和依赖图也可以以这种方式使用。

图 4:Mean SHAP

下一个图将告诉我们哪些特征最重要。对于每个特征,我们计算所有观测值的平均 SHAP 值。具体来说,我们取绝对值的平均值,因为我们不希望正值和负值相互抵消。最后,我们得到下面的条形图。每个特征都有一个条形图。例如,我们可以看到壳重量具有最大的平均 SHAP 值。

# Mean SHAP
shap.plots.bar(shap_values)

图 8:绝对均值图

具有较大正/负贡献的特征将具有较大的平均 SHAP 值。换句话说,这些特征对模型的预测产生了重大影响。从这个意义上讲,此图的使用方式与特征重要性图相同。

图 5:Beeswarm

接下来,我们得到了最有用的图表。蜂群将所有 SHAP 值可视化。在 y 轴上,这些值按特征分组。对于每个组,点的颜色由特征值决定(即,特征值越高,颜色越红)。

# Beeswarm plot
shap.plots.beeswarm(shap_values)

图 7:蜂群图

与平均 SHAP 一样,蜂群可用于突出重要关系。事实上,上图中的特征是按平均 SHAP 排序的。

我们也可以开始理解这些关系的性质。对于壳重,请注意 SHAP 值如何随着特征值的增加而增加。我们在堆叠力图中看到了类似的关系。它告诉我们,壳重值越大,预测的环数也就越多。

你可能已经注意到,去壳重量具有相反的关系。查看蜂群图,我们可以看到此特征的较大值与较小的 SHAP 值相关。我们可以使用依赖图仔细研究这些关系。

图 6:Dependence Plot

依赖图是单个特征的 SHAP 值与特征值的散点图。如果特征与目标变量具有非线性关系,则它们特别有用。

例如,以壳重的依赖关系图为例。查看蜂群图,我们可能假设 SHAP 值随特征值线性增加。依赖关系图告诉我们,这种关系并不是完全线性的。

#Plot 1: shell weight
shap.plots.scatter(shap_values[:,"shell weight"])

图 8:壳重依赖性图

我们还可以使用第二个特征的值来为散点图着色。现在我们有了相同的图,去壳重量越大,点越红。我们可以看到,当壳重和去壳重量都很大时,SHAP 值也很大。

shap.plots.scatter(shap_values[:,"shell weight"],
color=shap_values[:,"shucked weight"])

图 9:壳重与去壳重量的关系图

这些图可用于可视化特征之间的相互作用,但要小心!在我们的例子中,该图是两个特征之间相关性的结果。

我们还有去壳重量(即鲍鱼肉的重量)的依赖关系图。使用此图,我们可以确认我们在蜂群图中看到的关系。SHAP 值确实会随着去壳重量的增加而下降。

# Plot 2: shucked weight
shap.plots.scatter(shap_values[:,"shucked weight"])

图 10:去壳重量的依赖关系图

直观地看,这种关系似乎很奇怪。我们不是希望年龄较大的鲍鱼更大、肉更多吗?事实上,这是壳重和去壳重量相互作用的结果。由于相关性,我们在依赖图中看不到它。在文章《[[分析与 SHAP 的相互作用]]》中,我们探讨了如何使用 SHAP 交互值来识别此类相互作用。

SHAP 用于分类

你会很高兴地知道,分类问题的 SHAP 图与上面的非常相似。除了二元目标变量之外,我们根据对数几率来解释 SHAP 值。对于多类目标,我们使用softmax。一个缺点是我们最终会为多类目标中的每个类绘制单独的 SHAP 图。我们将在后面一篇文章中讨论了一些更好的聚合值的方法,暂定标题为[[二元和多类目标变量的 SHAP]],当你的模型预测分类目标变量时,代码和 SHAP 图的解释指南。

我们可以看到,SHAP 值是一种有用的工具,可用于了解我们的模型如何进行预测。然而,我们只是触及了该软件包所能提供内容的表面。如果你想了解更多信息,我日后将会写一些有关 SHAP 的文章,用于更深入地探讨了 SHAP 和 Shapley 值的某些方面,包括:

[[从 Shapley 到 SHAP — 数学理解]], 如何计算 SHAP 特征贡献的概述

[[KernelSHAP 与 TreeSHAP]], 根据速度、复杂性和其他考虑因素比较 SHAP 近似方法

[[使用 SHAP 调试 PyTorch 图像回归模型]], 使用 DeepShap 理解和改进自动驾驶汽车模型

由于本人常年使用双向链接软件写文,在粘贴的时候会时常有类似[[XXX 文章名]]的样式,这只是我文章相互连接的格式,如若不能链接到别处大概率就是还未成文发布。

AI 进阶:企业项目实战3

参考

S. Lundberg, SHAP Python package (2021), https://github.com/slundberg/shap

S. Lundberg & S. Lee, A Unified Approach to Interpreting Model Predictions (2017), https://arxiv.org/pdf/1705.07874.pdf

C. Molnar, Interpretable Machine Learning (2021) https://christophm.github.io/interpretable-ml-book/shap.html


希望这篇文章对你有所帮助!你还可以阅读我的其他文章,或者查看有关企业 AI 实战项目的教程,相信会让你拥有更多收获。

「AI秘籍」系列课程:

人工智能应用数学基础

人工智能Python基础

人工智能基础核心知识

人工智能BI核心知识

人工智能CV核心知识

AI企业项目实战课优惠二维码


  1. Github, https://github.com/hivandu/public_articles/blob/main/src/SHAP/shap_tutorial.ipynb ↩︎

  2. Abalone Dataset, https://archive.ics.uci.edu/dataset/1/abalone ↩︎

  3. AI 企业项目实战, https://www.sanjieke.cn/course/detail/sjk/8005780 ↩︎

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2045992.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

iOS替代商店AltStore PAL获得EPIC的资助 即日起取消1.5欧元的年度订阅费

知名游戏开发商 EPIC 日前宣布通过 EPIC MegaGrant 计划向 iOS 替代商店 AltStore PAL 进行捐赠,该商店是在欧盟市场经过苹果批准的合规的第三方应用商店。 按苹果规定第三方替代商店需要缴纳核心技术费并且没有豁免条款,因此该商店每被一名用户安装&am…

RIP学习笔记

1.RIP简介 Rip:routing information protocol,路由信息协议。属于动态路由协议的一种。 RIP是应用较早、使用较普遍的内部网关协议(InteriorGatewayProtocol,简称IGP),适用于小型同类网络,是典型的距离向量(distance-vector)协议…

OKR 与 KPI 的区别

OKR出现后,大家经常会拿KPI与之一起比较,结果两级分化:爱KPI的一如既往KPI,把OKR说的一无是处。爱OKR的,搞起了“去KPI”化。Tita作为OKR应用软件的服务商,我们也必须对OKR和KPI有充分的理解。对此我认真做…

Ubuntu离线安装docker

查看操作系统版本: rootzyh-VMware-Virtual-Platform:~/install# lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 24.04 LTS Release: 24.04 Codename: noble rootzyh-VMware-Virtual-Platform:~/install#…

微服务架构设计中的常见的10种设计模式

微服务架构设计的概念 微服务架构(Microservices Architecture)是一种用于构建分布式系统的软件设计模式。它将大型应用程序拆分成一组小型、自治的服务,每个服务都运行在其独立的进程中,服务之间通过轻量级的通信机制&#xff08…

重塑商业生态:技术驱动下的批发供应系统开发与革新

在当今这个快速变化的商业环境中,批发供应系统作为连接生产商、分销商与零售商的关键纽带,其效率与智能化水平直接影响着整个供应链的运作效率与市场竞争力。随着信息技术的飞速发展,特别是大数据、云计算、人工智能(AI&#xff0…

D. 二进制

1.题意:给出2中操作 1):将段排序 2):将段输出为十进制数 思路: 1.考虑第一种操作。只需要查询l-r中1的个数即可。如果递增,则中为1,否则中为1,需要一个覆盖tag 2.考虑如何维护十进制的值。…

基于Java的美妆购物网站的设计与实现

TOC springboot323基于Java的美妆购物网站的设计与实现 第1章 绪论 1.1选题动因 当前的网络技术,软件技术等都具备成熟的理论基础,市场上也出现各种技术开发的软件,这些软件都被用于各个领域,包括生活和工作的领域。随着电脑和…

在 S7-1200/S7-1500 中,如何测量一个完整程序、子程序或特定组织块的运行时间?

RUNTIME"指令的第一次调用用来设置测量时间的起点,并将其保存在DB变量 "Memory"中来为第二次调用做参考。然后调用 "TestBlock" 程序块。当程序块被执行后,"RUNTIME" 指令第二次调用,第二次调用来计算 "TestBlock"程序块的运行…

电影《白蛇:浮生》观后感

上周看了电影《白蛇:浮生》,动画的特效方面,中国动画这几年确实做的非常不错了,不过整个故事,还是老的那套,并没有感觉特别新意。 (1)老套故事 《白娘子传奇》的故事,几…

NCBI批量下载序列

根据提供的accession编号批量下载 下载地址 NCBI_batch 点击选择文件,导入需要下载的accession编号文件,点击Retrieveji下载

eNSP 华为划分VLAN

SW1&#xff1a; <Huawei>system-view [Huawei]sysname SW1 [SW1]VLAN batch 10 20 //批量划分vlan [SW1]interface GigabitEthernet0/0/1 [SW1-GigabitEthernet0/0/1]port link-type access //设置为access口&#xff0c;access口允许单个vlan通过 [SW1-GigabitEth…

数据结构day02(链表)

【1】链表 Link list 链表又称单链表/链式存储结构&#xff0c;用于存储逻辑关系为“一对一”的数据 和顺序表不同&#xff0c;使用链表存储数据&#xff0c;不强制要求在内存中集中存储&#xff0c;各个元素可以分散存储在内存中。 所以在链表中&#xff0c;每个数据元素可以配…

K7系列FPGA多重启动(Multiboot)

Xilinx 家的 FPGA 支持多重启动功能&#xff08;Multiboot&#xff09;&#xff0c;即可以从多个 bin 文件中进行选择性加载&#xff0c;从而实现对系统的动态更新&#xff0c;或系统功能的动态调整。 这一过程可以通过嵌入在 bit 文件里的 IPROG 命令实现上电后的自动加载。而…

计算机网络体系结构【★★★】

&#xff08;★★&#xff09;代表非常重要的知识点&#xff0c;&#xff08;★&#xff09;代表重要的知识点。 一、计算机网络概述 1. 计算机网络的性能指标&#xff08;★★&#xff09; 1&#xff09;速率&#xff08;speed&#xff09; 指连接到计算机网络上的节点在数…

用爬虫玩转石墨文档详细操作步骤

石墨文档是一款强大的在线文档编辑和协作工具&#xff0c;它支持文字处理、表格制作、演示文稿等多种功能&#xff0c;适用于个人和团队的办公需求。以下是一些玩转石墨文档的详细步骤和技巧&#xff1a; 1. 注册和登录 注册&#xff1a;访问石墨文档官网&#xff0c;点击“注…

【漏洞复现】某骋BPM系统——Handler.ashx——sql注入

声明&#xff1a;本文档或演示材料仅供教育和教学目的使用&#xff0c;任何个人或组织使用本文档中的信息进行非法活动&#xff0c;均与本文档的作者或发布者无关。 文章目录 漏洞描述漏洞复现测试工具 漏洞描述 某骋BPM系统是一款功能全面的商业流程管理平台,旨在帮助企业实现…

车辆横向控制的参考路径估计

Reference Path Estimation for Lateral Vehicle Control 车辆横向控制的参考路径估计 Abstract Autonomous driving cars have been a hot topic in the media in recent years, with more and more tech companies and universities presenting projects with fully autom…

同态加密和SEAL库的介绍(九)CKKS 参数心得 1

写在前面&#xff1a; 前面几篇有官方的说明和示例做支撑&#xff0c;相信能给大家比较多的参考价值。但是由于没能对同态加密有更深入的了解&#xff0c;所以在我具体使用的时候出现各种问题。本篇是针对这些问题做的一些测试&#xff0c;由结论产生的了些个人的推测&#xff…

准大学生电脑应该怎么选?

随着夏日的尾声悄然临近&#xff0c;各位准大学生们是不是已经迫不及待想要翻开大学生活的崭新篇章了呢&#xff1f;作为准大学生&#xff0c;选择一台称心如意的电脑绝对是大家最近最头疼的事情&#xff0c;那我们应该怎么选择适合自己的电脑呢&#xff1f; 01 处理器&#x…