SHAP(一):具有 Shapley 值的可解释 AI 简介

SHAP(一):具有 Shapley 值的可解释 AI 简介

这是用 Shapley 值解释机器学习模型的介绍。 沙普利值是合作博弈论中广泛使用的方法,具有理想的特性。 本教程旨在帮助您深入了解如何计算和解释基于 Shapley 的机器学习模型解释。 我们将采取实用的实践方法,使用“shap”Python 包来逐步解释更复杂的模型。 这是一个动态文档,作为“shap” Python 包的介绍。 因此,如果您有反馈或贡献,请提出问题或拉取请求,以使本教程变得更好!

大纲

  • 解释线性回归模型
  • 解释广义加性回归模型
  • 解释非加性提升树模型
  • 解释线性逻辑回归模型
  • 解释非加性提升树逻辑回归模型
  • 处理相关输入特征

1.解释线性回归模型

在使用 Shapley 值解释复杂模型之前,了解它们如何适用于简单模型会很有帮助。 最简单的模型类型之一是标准线性回归,因此下面我们在[加州住房数据集](https://www.dcc.fc.up.pt/~ltorgo/Regression/cal_housing.html )。 该数据集由 1990 年加利福尼亚州的 20,640 个房屋区块组成,我们的目标是根据 8 个不同的特征预测房价中位数的自然对数:

  1. MedInc - 区块组收入中位数
  2. HouseAge - 街区组中的房屋年龄中位数
  3. AveRooms——每户平均房间数
  4. AveBedrms——每户平均卧室数量
    5.人口-区块组人口
  5. AveOccup - 家庭成员的平均数量
  6. Latitude——块组纬度
  7. Longitude——块组经度
import sklearn

import shap

# a classic housing price dataset
X, y = shap.datasets.california(n_points=1000)

X100 = shap.utils.sample(X, 100)  # 100 instances for use as the background distribution

# a simple linear model
model = sklearn.linear_model.LinearRegression()
model.fit(X, y)
LinearRegression()

1.1 检查模型系数

理解线性模型的最常见方法是检查为每个特征学习的系数。 这些系数告诉我们当我们改变每个输入特征时模型输出会发生多少变化:

print("Model coefficients:\n")
for i in range(X.shape[1]):
    print(X.columns[i], "=", model.coef_[i].round(5))
Model coefficients:

MedInc = 0.45769
HouseAge = 0.01153
AveRooms = -0.12529
AveBedrms = 1.04053
Population = 5e-05
AveOccup = -0.29795
Latitude = -0.41204
Longitude = -0.40125

虽然系数非常适合告诉我们当我们改变输入特征的值时会发生什么,但它们本身并不是衡量特征整体重要性的好方法。 这是因为每个系数的值取决于输入特征的规模。 例如,如果我们以分钟而不是年为单位来测量房屋的年龄,那么 HouseAge 特征的系数将变为 0.0115 / (3652460) = 2.18e-8。 显然,房屋建成后的年数并不比分钟数更重要,但其系数值要大得多。 这意味着系数的大小不一定能很好地衡量线性模型中特征的重要性。

1.2 使用部分依赖图更完整的图片

要了解模型中特征的重要性,有必要了解更改该特征如何影响模型的输出,以及该特征值的分布。 为了将其可视化为线性模型,我们可以构建经典的部分依赖图,并将特征值的分布显示为 x 轴上的直方图:

shap.partial_dependence_plot(
    "MedInc",
    model.predict,
    X100,
    ice=False,
    model_expected_value=True,
    feature_expected_value=True,
)

在这里插入图片描述

上图中的灰色水平线表示模型应用于加州住房数据集时的预期值。 垂直灰线表示中位收入特征的平均值。 请注意,蓝色部分依赖图线(即我们将中位收入特征固定为给定值时模型输出的平均值)始终穿过两条灰色期望值线的交点。 我们可以将该交点视为数据分布的部分依赖图的“中心”。 当我们接下来讨论SHAP值时,这种中心化的影响就会变得清晰。

1.3 从部分相关图中读取 SHAP 值

基于 Shapley 值的机器学习模型解释背后的核心思想是使用合作博弈论的公平分配结果,在模型的输入特征中为模型的输出 f ( x ) f(x) f(x) 分配信用 。 为了将博弈论与机器学习模型联系起来,既需要将模型的输入特征与游戏中的玩家进行匹配,又需要将模型函数与游戏规则进行匹配。 由于在博弈论中玩家可以加入或不加入游戏,因此我们需要一种方法来让功能“加入”或“不加入”模型。 定义某个特征“加入”模型的含义的最常见方法是,当我们知道该特征的值时,就说该特征已“加入模型”;而当我们不知道该特征的值时,就说该特征尚未加入模型。 知道该功能的价值。 当只有特征子集 S S S 是模型的一部分时,为了评估现有模型 f f f,我们使用条件期望值公式整合其他特征。 这个公式可以有两种形式:

E [ f ( X ) ∣ X S = x S ] E[f(X) \mid X_S = x_S] E[f(X)XS=xS]

or

E [ f ( X ) ∣ d o ( X S = x S ) ] E[f(X) \mid do(X_S = x_S)] E[f(X)do(XS=xS)]

在第一种形式中,我们知道 S 中特征的值,因为我们“观察”它们。 在第二种形式中,我们知道 S 中特征的值,因为我们“设置”了它们。 一般来说,第二种形式通常更可取,因为它告诉我们如果我们干预并更改其输入,模型将如何表现,而且因为它更容易计算。 在本教程中,我们将完全关注第二种表述 。 我们还将使用更具体的术语“SHAP 值”来指代应用于机器学习模型的条件期望函数的 Shapley 值。

SHAP 值的计算可能非常复杂(它们通常是 NP 困难的),但线性模型非常简单,我们可以立即从部分依赖图读取 SHAP 值。 当我们解释预测 f ( x ) f(x) f(x) 时,特定特征 i i i 的 SHAP 值只是预期模型输出与特征值 x i x_i xi 处的部分依赖图之间的差异:

# compute the SHAP values for the linear model
explainer = shap.Explainer(model.predict, X100)
shap_values = explainer(X)

# make a standard partial dependence plot
sample_ind = 20
shap.partial_dependence_plot(
    "MedInc",
    model.predict,
    X100,
    model_expected_value=True,
    feature_expected_value=True,
    ice=False,
    shap_values=shap_values[sample_ind : sample_ind + 1, :],
)

在这里插入图片描述

经典的部分依赖图和 SHAP 值之间的紧密对应意味着,如果我们在整个数据集中绘制特定特征的 SHAP 值,我们将准确地绘制出该特征的部分依赖图的平均中心版本:

shap.plots.scatter(shap_values[:, "MedInc"])

在这里插入图片描述

1.4 Shapley 值的加性

Shapley 值的基本属性之一是,它们总是总结所有玩家在场时的游戏结果与没有玩家在场时的游戏结果之间的差异。 对于机器学习模型,这意味着所有输入特征的 SHAP 值将始终等于基线(预期)模型输出与所解释的预测的当前模型输出之间的差异。 最简单的方法是通过瀑布图,该图从我们对房价 E [ f ( X ) ] E[f(X)] E[f(X)] 的背景先验期望开始,然后一次添加一个特征,直到达到当前模型输出 f ( x ) f( x) f(x):

# the waterfall_plot shows how we get from shap_values.base_values to model.predict(X)[sample_ind]
shap.plots.waterfall(shap_values[sample_ind], max_display=14)

在这里插入图片描述

2.解释加性回归模型

线性模型的部分依赖图与 SHAP 值具有如此密切的联系的原因是,模型中的每个特征都是独立于其他每个特征进行处理的(效果只是相加在一起)。 我们可以保持这种可加性,同时放宽直线的线性要求。 这就产生了众所周知的广义加性模型 (GAM)。 虽然有很多方法可以训练这些类型的模型(例如将 XGBoost 模型设置为深度 1),但我们将使用专门为此设计的 InterpretML 可解释的 boosting 机器。

# fit a GAM model to the data
import interpret.glassbox

model_ebm = interpret.glassbox.ExplainableBoostingRegressor(interactions=0)
model_ebm.fit(X, y)

# explain the GAM model with SHAP
explainer_ebm = shap.Explainer(model_ebm.predict, X100)
shap_values_ebm = explainer_ebm(X)

# make a standard partial dependence plot with a single SHAP value overlaid
fig, ax = shap.partial_dependence_plot(
    "MedInc",
    model_ebm.predict,
    X100,
    model_expected_value=True,
    feature_expected_value=True,
    show=False,
    ice=False,
    shap_values=shap_values_ebm[sample_ind : sample_ind + 1, :],
)

在这里插入图片描述

shap.plots.scatter(shap_values_ebm[:, "MedInc"])

在这里插入图片描述

# the waterfall_plot shows how we get from explainer.expected_value to model.predict(X)[sample_ind]
shap.plots.waterfall(shap_values_ebm[sample_ind])

在这里插入图片描述

# the waterfall_plot shows how we get from explainer.expected_value to model.predict(X)[sample_ind]
shap.plots.beeswarm(shap_values_ebm)

在这里插入图片描述

3.解释非加性提升树模型

# train XGBoost model
import xgboost

model_xgb = xgboost.XGBRegressor(n_estimators=100, max_depth=2).fit(X, y)

# explain the GAM model with SHAP
explainer_xgb = shap.Explainer(model_xgb, X100)
shap_values_xgb = explainer_xgb(X)

# make a standard partial dependence plot with a single SHAP value overlaid
fig, ax = shap.partial_dependence_plot(
    "MedInc",
    model_xgb.predict,
    X100,
    model_expected_value=True,
    feature_expected_value=True,
    show=False,
    ice=False,
    shap_values=shap_values_xgb[sample_ind : sample_ind + 1, :],
)

在这里插入图片描述

shap.plots.scatter(shap_values_xgb[:, "MedInc"])

在这里插入图片描述

shap.plots.scatter(shap_values_xgb[:, "MedInc"], color=shap_values)

在这里插入图片描述

4.解释线性逻辑回归模型

# a classic adult census dataset price dataset
X_adult, y_adult = shap.datasets.adult()

# a simple linear logistic model
model_adult = sklearn.linear_model.LogisticRegression(max_iter=10000)
model_adult.fit(X_adult, y_adult)


def model_adult_proba(x):
    return model_adult.predict_proba(x)[:, 1]


def model_adult_log_odds(x):
    p = model_adult.predict_log_proba(x)
    return p[:, 1] - p[:, 0]

请注意,解释线性逻辑回归模型的概率在输入中不是线性的。

# make a standard partial dependence plot
sample_ind = 18
fig, ax = shap.partial_dependence_plot(
    "Capital Gain",
    model_adult_proba,
    X_adult,
    model_expected_value=True,
    feature_expected_value=True,
    show=False,
    ice=False,
)

在这里插入图片描述

如果我们使用 SHAP 来解释线性逻辑回归模型的概率,我们会看到很强的交互效应。 这是因为线性逻辑回归模型在概率空间中不是可加的。

# compute the SHAP values for the linear model
background_adult = shap.maskers.Independent(X_adult, max_samples=100)
explainer = shap.Explainer(model_adult_proba, background_adult)
shap_values_adult = explainer(X_adult[:1000])
Permutation explainer: 1001it [00:58, 14.39it/s]                                  
shap.plots.scatter(shap_values_adult[:, "Age"])

在这里插入图片描述

如果我们解释模型的对数赔率输出,我们会看到模型输入和模型输出之间存在完美的线性关系。 重要的是要记住您正在解释的模型的单位是什么,并且解释不同的模型输出可能会导致对模型行为的截然不同的看法。

# compute the SHAP values for the linear model
explainer_log_odds = shap.Explainer(model_adult_log_odds, background_adult)
shap_values_adult_log_odds = explainer_log_odds(X_adult[:1000])
Permutation explainer: 1001it [01:01, 13.61it/s]                                  
shap.plots.scatter(shap_values_adult_log_odds[:, "Age"])

在这里插入图片描述

# make a standard partial dependence plot
sample_ind = 18
fig, ax = shap.partial_dependence_plot(
    "Age",
    model_adult_log_odds,
    X_adult,
    model_expected_value=True,
    feature_expected_value=True,
    show=False,
    ice=False,
)

在这里插入图片描述

5.解释非加性提升树逻辑回归模型

# train XGBoost model
model = xgboost.XGBClassifier(n_estimators=100, max_depth=2).fit(
    X_adult, y_adult * 1, eval_metric="logloss"
)

# compute SHAP values
explainer = shap.Explainer(model, background_adult)
shap_values = explainer(X_adult)

# set a display version of the data to use for plotting (has string values)
shap_values.display_data = shap.datasets.adult(display=True)[0].values
The use of label encoder in XGBClassifier is deprecated and will be removed in a future release. To remove this warning, do the following: 1) Pass option use_label_encoder=False when constructing XGBClassifier object; and 2) Encode your labels (y) as integers starting with 0, i.e. 0, 1, 2, ..., [num_class - 1].
 98%|===================| 31839/32561 [00:12<00:00]        

默认情况下,SHAP 条形图将采用数据集所有实例(行)上每个特征的平均绝对值。

shap.plots.bar(shap_values)

在这里插入图片描述

但平均绝对值并不是创建特征重要性全局度量的唯一方法,我们可以使用任意数量的变换。 在这里,我们展示了如何使用最大绝对值来突出资本收益和资本损失特征,因为它们具有罕见但高强度的影响。

shap.plots.bar(shap_values.abs.max(0))

在这里插入图片描述

如果我们愿意处理更复杂的情况,我们可以使用蜂群图来总结每个特征的 SHAP 值的整个分布。

shap.plots.beeswarm(shap_values)

在这里插入图片描述

通过取绝对值并使用纯色,我们在条形图和完整蜂群图的复杂性之间取得了折衷。 请注意,上面的条形图只是下面蜂群图中显示的值的汇总统计数据。

shap.plots.beeswarm(shap_values.abs, color="shap_red")

在这里插入图片描述

shap.plots.heatmap(shap_values[:1000])

在这里插入图片描述

shap.plots.scatter(shap_values[:, "Age"])

在这里插入图片描述

shap.plots.scatter(shap_values[:, "Age"], color=shap_values)

在这里插入图片描述

shap.plots.scatter(shap_values[:, "Age"], color=shap_values[:, "Capital Gain"])

在这里插入图片描述

shap.plots.scatter(shap_values[:, "Relationship"], color=shap_values)

在这里插入图片描述

6.处理相关特征

clustering = shap.utils.hclust(X_adult, y_adult)
shap.plots.bar(shap_values, clustering=clustering)

在这里插入图片描述

shap.plots.bar(shap_values, clustering=clustering, clustering_cutoff=0.8)

在这里插入图片描述

shap.plots.bar(shap_values, clustering=clustering, clustering_cutoff=1.8)

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

从零开始的c语言日记day39——指针进阶-函数指针

复习上节内容 什么是指针数组什么是数组指针 取地址函数名和函数名都是打印函数地址 Pf指向的参数和函数的参数类型要一至。三种写法都可以实现调用 练习&#xff1a;如何解释图中代码作用 首先看&#xff08;void&#xff08;*&#xff09;&#xff08;&#xff09;&#xff…

FPGA程序执行相关知识点

1.目前&#xff0c;大多数FPGA芯片是基于 SRAM 的结构的&#xff0c; 而 SRAM 单元中的数据掉电就会丢失&#xff0c;因此系统上电后&#xff0c;必须要由配置电路将正确的配置数据加载到 SRAM 中&#xff0c;此后 FPGA 才能够正常的运行。 常见的配置芯片有EPCS 芯片 &#x…

Java微服务框架 HP-SOA 1.0.5 — 完整支持 Spring Cloud 和 Dubbo

HP-SOA 功能完备&#xff0c;简单易用&#xff0c;高度可扩展的Java微服务框架。 项目主页 : https://www.oschina.net/p/hp-soa下载地址 : https://github.com/ldcsaa/hp-soa开发文档 : https://gitee.com/ldcsaa/hp-soa/blob/master/README.mdQQ Group: 44636872, 66390394…

佳易王羽毛球馆计时计费软件操作教程,软件可以自动计算费用,支持会员管理

一、前言&#xff08;编程应用实例系列&#xff09;&#xff1a; 佳易王羽毛球馆计时计费软件操作教程&#xff0c;软件可以自动计算费用&#xff0c;支持会员管理 软件有试用版&#xff0c;可以下载试用&#xff0c;了解软件操作和软件功能。 软件试用版下载可以点击最下方…

37.从0到上线三天搭建个人网站(第一天)

点赞收藏加关注&#xff0c;你也能住大别墅&#xff01; 挑战三天搭建个人网站 从0到上线 一、项目的主要功能 1.作为自己在网上的一个工作室。 2.发帖 3.展示个人项目连接 4.介绍自己&#xff08;没准儿还能接点活儿&#xff09; 二、UI风格参考 三、技术选型 1.前端&a…

【C++高阶(六)】哈希的应用--位图布隆过滤器

&#x1f493;博主CSDN主页:杭电码农-NEO&#x1f493;   ⏩专栏分类:C从入门到精通⏪   &#x1f69a;代码仓库:NEO的学习日记&#x1f69a;   &#x1f339;关注我&#x1faf5;带你学习C   &#x1f51d;&#x1f51d; 哈希的应用 1. 前言2. 位图的概念以及定义3. 位…

深度学习——Loss汇总

深度学习——Loss汇总 一、IOU Loss二、L1 Loss 一、IOU Loss 公式&#xff1a; 参考资料: 目标检测回归损失函数——IOU、GIOU、DIOU、CIOU、EIOU 二、L1 Loss 公式&#xff1a; 参考资料: PyTorch中的损失函数–L1Loss /L2Loss/SmoothL1Loss

【FMC140】 基于VITA57.4标准的双通道5.2GSPS(或单通道10.4GSPS)射频采样FMC+子卡模块

板卡概述 FMC140是一款具有缓冲模拟输入的低功耗、12位、双通道&#xff08;5.2GSPS/通道&#xff09;、单通道10.4GSPS、射频采样ADC模块&#xff0c;该板卡为FMC标准&#xff0c;符合VITA57.1规范&#xff0c;该模块可以作为一个理想的IO单元耦合至FPGA前端&#xff0c;8通道…

<avue-crud/>,二级表头,children下字典项的dicUrl失效问题

目录 1.提出问题&#xff1a; 1.1 代码&#xff1a; 1.2 效果图&#xff1a;会发现处在children下的dicUrl失效了 2. 解决思路 3. 解决代码&#xff08;你要的都在这&#xff0c;看这里&#xff09; 1.提出问题&#xff1a; 在使用<avue-crud/>组件实现二级表头时&…

Leetcode2336 无限集中的最小数字

题目&#xff1a; 现有一个包含所有正整数的集合 [1, 2, 3, 4, 5, ...] 。 实现 SmallestInfiniteSet 类&#xff1a; SmallestInfiniteSet() 初始化 SmallestInfiniteSet 对象以包含 所有 正整数。int popSmallest() 移除 并返回该无限集中的最小整数。void addBack(int nu…

Linux | Ubuntu设置 netstat(网络状态)

netstat命令用于显示与IP、TCP、UDP和ICMP协议相关的统计数据&#xff0c;一般用于检验本机各端口的网络连接情况。netstat是在内核中访问网络及相关信息的程序&#xff0c;它能提供TCP连接&#xff0c;TCP和UDP监听&#xff0c;进程内存管理的相关报告。 1.netstat的安装 搜…

nodejs最新电商jd m端h5st 4.2签名算法4.2版本逆向,jd API接口,jd商品数据采集

前言&#xff1a; jd m端使用最新的h5st 4.2签名算法&#xff0c;与h5st 4.1版本有很大的不同。在这儿分析一下&#xff0c;供大家参考。 一、目标地址(Base64解码) aHR0cHM6Ly9zby5tLmpkLmNvbS93YXJlL3NlYXJjaC5hY3Rpb24/a2V5d29yZD0lRTklOTklQTQlRTYlQjklQkYlRTYlOUMlQkEmc2…

c++基本常见错误总结

我们无论是在学习中还是在工作当中&#xff0c;总是会遇到各种各样的c编译错误问题&#xff0c;经常会有一种情况就是上一次好像遇到过这种问题&#xff0c;但是就是想不起来了&#xff08;我就是这样&#xff09;所以下面这一篇文章就是总结自己遇到的编译以及运行错误。 注意…

药食同源的食物哪些适合冬季吃?

药食同源的食物是指在中医理论指导下&#xff0c;既是药物又是食物的天然植物和动物&#xff0c;具有营养和药效双重作用。在冬季&#xff0c;由于气候寒冷&#xff0c;人体需要更多的热量和营养来保持温暖和健康&#xff0c;因此药食同源的食物在冬季特别适合食用。以下是几种…

(5h)Unity3D快速入门之Roll-A-Ball游戏开发

DAY1&#xff1a;Unity3D安装 链接 DAY2&#xff1a;构建场景&#xff0c;编写代码 链接 内容&#xff1a;WASD前后左右移动、摄像机跟随 DAY3&#xff1a;待更新 DAY4&#xff1a;待更新 DAY5&#xff1a;待更新

UG\NX二次开发 设置是否允许通过NXOpen锁定属性

文章作者:里海 来源网站:里海NX二次开发3000例专栏 感谢粉丝订阅 感谢 2301_80939425 订阅本专栏,非常感谢。 简介 在使用UF_ATTR_set_locked函数锁定属性前,需要先设置是否允许通过NXOpen锁定属性。使用下面的代码可以修改“用户默认设置”当 NX 启动时,客户默认值将读取…

TA-Lib学习研究笔记(三)——Volatility Indicator

TA-Lib学习研究笔记&#xff08;三&#xff09;——Volatility Indicator 波动率指标函数组 Volatility Indicators: [‘ATR’, ‘NATR’, ‘TRANGE’] 1.ATR Average True Range 函数名&#xff1a;ATR 名称&#xff1a;真实波动幅度均值 简介&#xff1a;真实波动幅度均值…

第二十章多线程总结

20.1 线程简介 世间有很多工作都是可以同时完成的。例如&#xff0c;人体可以同时进行呼吸、血液循环、思考问题等活用户既可以使用计算机听歌&#xff0c;也可以使用它打印文件。同样&#xff0c;计算机完全可以将多种活动同时进这种思想放在 Java 中被称为并发&#xff0c;而…

深度学习框架:Pytorch与Keras的区别与使用方法

☁️主页 Nowl &#x1f525;专栏《机器学习实战》 《机器学习》 &#x1f4d1;君子坐而论道&#xff0c;少年起而行之 文章目录 Pytorch与Keras介绍 Pytorch 模型定义 模型编译 模型训练 输入格式 完整代码 Keras 模型定义 模型编译 模型训练 输入格式 完整代…