news 2026/2/16 13:46:12

KernelSHAP 在预测变量相关时可能产生误导

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
KernelSHAP 在预测变量相关时可能产生误导

原文:towardsdatascience.com/kernelshap-can-be-misleading-with-correlated-predictors-9f64108f7cfb?source=collection_archive---------7-----------------------#2024-08-09

一个具体的案例研究

https://medium.com/@vanillaxiangshuyang?source=post_page---byline--9f64108f7cfb--------------------------------https://towardsdatascience.com/?source=post_page---byline--9f64108f7cfb-------------------------------- Shuyang Xiang

·发表于Towards Data Science ·阅读时长:7 分钟·2024 年 8 月 9 日

“像许多其他基于置换的解释方法一样,Shapley 值方法在特征相关时会遭遇不现实数据实例的引入。为了模拟一个特征值在一个联合体中缺失的情况,我们对该特征进行边际化处理……当特征之间存在依赖关系时,我们可能会抽取一些对于当前实例来说不合理的特征值。”—— 可解释机器学习书籍。

SHAP(Shapley 加性解释)值旨在根据合作博弈论中的 Shapley 值概念,公平地分配每个特征对机器学习模型预测的贡献。Shapley 值框架具有几个理想的理论属性,并且原则上可以处理任何预测模型。然而,SHAP 值可能会产生误导,特别是在使用 KernelSHAP 方法进行近似时。当预测变量之间存在相关性时,这些近似值可能会不准确,甚至可能有相反的符号。

在这篇博客文章中,我将展示原始的 SHAP 值如何与SHAP 框架的近似值有显著差异,尤其是 KernelSHAP,并讨论这些差异背后的原因。

案例研究:客户流失率

考虑一个场景,我们旨在预测一个办公楼租赁的流失率,基于两个关键因素:入住率和报告问题的比例。

占用率对流失率有显著影响。例如,如果占用率过低,租户可能会因为办公室未被充分利用而离开。相反,如果占用率过高,租户可能会因为拥挤而离开,寻求更好的选择。

此外,我们假设报告问题的比率与占用率高度相关,具体而言,报告问题的比率是占用率的平方。

我们将流失率函数定义如下:

https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/456107a845a24d3ffa3fb61d9ede4aa3.png

作者提供的图像:流失率函数

该函数对于这两个变量的表示可以通过以下插图表示:

https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/fac81573dd6ddaff630cd4e105c27f5c.png

作者提供的图像:关于两个变量的流失

原始 SHAP 与 Kernel SHAP 之间的差异

使用 Kernel SHAP 计算的 SHAP 值

我们将使用以下代码计算预测变量的 SHAP 值:

# Define the dataframechurn_df=pd.DataFrame({"occupancy_rate":occupancy_rates,"reported_problem_rate":reported_problem_rates,"churn_rate":churn_rates,})X=churn_df.drop(["churn_rate"],axis=1)y=churn_df["churn_rate"]X_train,X_test,y_train,y_test=train_test_split(X,y,test_size=0.2,random_state=42)# append one speical pointX_test=pd.concat(objs=[X_test,pd.DataFrame({"occupancy_rate":[0.8],"reported_problem_rate":[0.64]})])# Define the predictiondefpredict_fn(data):occupancy_rates=data[:,0]reported_problem_rates=data[:,1]churn_rate=C_base+C_churn*(C_occ*occupancy_rates-reported_problem_rates-0.6)**2+C_problem*reported_problem_ratesreturnchurn_rate# Create the SHAP KernelExplainer using the correct prediction functionbackground_data=shap.sample(X_train,100)explainer=shap.KernelExplainer(predict_fn,background_data)shap_values=explainer(X_test)

上面的代码执行以下任务:

  1. 数据准备:创建一个名为churn_df的 DataFrame,包含occupancy_ratereported_problem_ratechurn_rate列。然后从中创建变量和目标(churn_rate),并将数据拆分为训练集和测试集,训练集占 80%,测试集占 20%。注意,测试集X_test中添加了一个具有特定occupancy_ratereported_problem_rate值的数据点。

  2. 预测函数定义:定义了一个函数predict_fn,使用涉及预定义常量的特定公式计算流失率。

  3. SHAP 分析:使用预测函数和来自X_trainbackground_data样本初始化一个 SHAPKernelExplainer。然后使用explainer计算X_test的 SHAP 值。

下面,您可以看到一个总结性的 SHAP 条形图,表示X_test的平均 SHAP 值:

https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/4726e4abacf15f58d78cd540eb486327.png

作者提供的图像:平均 SHAP 值

特别地,我们看到在数据点(0.8,0.64)处,两个特征的 SHAP 值分别为 0.10 和-0.03,如下图所示的力图所示:

https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/f3be60805793ee4b29f17cadb80ce818.png

作者提供的图像:单一数据点的力图

原始定义的 SHAP 值

让我们退后一步,根据 SHAP 的原始定义逐步计算确切的 SHAP 值。SHAP 值的一般公式如下所示:

https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/506fd5f8560513877e5e88618a511382.png

其中:S 是所有特征索引的子集,排除 i,|S|是子集 S 的大小,M 是特征的总数,f(XS∪{xi})是包含 xi 的 S 的特征所评估的函数,而 f(XS)是 S 中缺少 xi 时评估的函数。

现在,让我们计算两个特征的 SHAP 值:占用率(表示为 x1)和报告问题率(表示为 x2),它们在数据点(0.8,0.64)处的值。回想一下,x1 和 x2 之间的关系是 x1 = x2²。

我们得到了数据点处占用率的 SHAP 值:

https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/745d8cfe9265145b22870e14c1902dd9.png

同样地,对于报告问题率这一特征:

https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/3ea90e76aec7a3ba8c1e59d143dc01cf.png

首先,让我们计算数据点处占用率的 SHAP 值:

  1. 第一项是当 X1 固定为 0.8 且 X2 在其分布上取平均时模型输出的期望值。由于 x1 = x2²的关系,这一期望值导致模型在特定点(0.8, 0.64)处的输出。

  2. 第二项是模型输出的无条件期望值,其中 X1 和 X2 都在其分布上取平均。可以通过对背景数据集中的所有数据点的输出进行平均来计算这一期望值。

  3. 第三项是模型在特定点(0.8, 0.64)处的输出。

  4. 最后一项是当 X1 在其分布上取平均时,给定 X2 固定在特定点 0.64 时模型输出的期望值。同样,考虑到 x1 = x2²的关系,这一期望值与模型在(0.8, 0.64)处的输出相符,类似于第一步。

因此,从原始定义计算的两个特征——占用率和报告问题率在数据点(0.8, 0.64)处的 SHAP 值分别为-0.0375 和-0.0375,这与 Kernel SHAP 给出的值有很大不同。

差异从何而来?

SHAP 值差异的原因

如你所注意到的,两种方法之间的差异主要出现在第二步和第四步,这两步需要计算条件期望。这涉及到在 X1 被固定为 0.8 时,计算模型输出的期望值。

https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/536458182b111c3c9659970702905c74.png

来自论文的截图

潜在的解决方案

不幸的是,基于原始定义直接计算 SHAP 值可能会非常耗费计算资源。以下是一些可供考虑的替代方法:

TreeSHAP

扩展 Kernel SHAP 以处理依赖特征

提升 Kernel SHAP 的准确性

通过使用这些方法,您可以解决计算 SHAP 值时遇到的挑战,并提高它们在实际应用中的准确性。然而,需要注意的是,没有一种解决方案可以在所有场景中都适用。

结论

在这篇博文中,我们探讨了尽管 SHAP 值具有强大的理论基础并且在各种预测模型中具有广泛的适用性,但当预测变量之间存在相关性时,特别是在采用类似 KernelSHAP 这样的近似方法时,SHAP 值可能会出现准确性问题。理解这些局限性对于有效地解释 SHAP 值至关重要。通过识别潜在的差异并选择最合适的近似方法,我们可以在模型中实现更准确可靠的特征归因。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/10 23:19:15

PyCharm运行日志过滤条件语音输入设置

PyCharm运行日志过滤条件语音输入设置 在调试一个复杂的微服务应用时,你是否经历过这样的场景:程序正在疯狂输出日志,屏幕上滚动着成千上万行文本,而你一边竖起耳朵听同事描述异常现象,一边手忙脚乱地在键盘上敲出“Nu…

作者头像 李华
网站建设 2026/2/10 12:24:34

CANoe平台CAPL编程操作指南:环境搭建步骤

手把手教你搭建CANoe下的CAPL开发环境:从零开始的实战指南你是不是也遇到过这种情况:刚拿到一个新项目,准备用CANoe写点CAPL脚本来仿真ECU通信,结果打开软件发现“CAPL编程”功能是灰色的?或者连接好VN1640硬件&#x…

作者头像 李华
网站建设 2026/2/15 8:38:13

APKMirror:解锁Android应用下载新体验的智能神器

APKMirror:解锁Android应用下载新体验的智能神器 【免费下载链接】APKMirror 项目地址: https://gitcode.com/gh_mirrors/ap/APKMirror 还在为找不到安全可靠的APK下载渠道而苦恼吗?🤔 APKMirror这款开源工具为你带来了全新的解决方案…

作者头像 李华
网站建设 2026/1/30 1:14:52

notepad-- macOS文本编辑器完整配置指南:新手轻松上手指南

notepad-- macOS文本编辑器完整配置指南:新手轻松上手指南 【免费下载链接】notepad-- 一个支持windows/linux/mac的文本编辑器,目标是做中国人自己的编辑器,来自中国。 项目地址: https://gitcode.com/GitHub_Trending/no/notepad-- …

作者头像 李华
网站建设 2026/2/16 10:27:43

胡桃工具箱终极指南:快速上手原神桌面管理利器

还在为原神游戏中繁杂的角色培养、材料收集和活动追踪而烦恼吗?胡桃工具箱(Snap Hutao)作为一款功能强大的开源原神桌面工具,能够彻底解决你的游戏管理难题,让游戏体验更加轻松高效。这款免费的多功能工具箱专门为新手…

作者头像 李华