shap值用法汇总

SHAP 值计算公式与代码示例

1. 经典 SHAP 计算(Shapley 值)

SHAP 值基于 Shapley 值的定义,用于衡量每个特征对模型预测的贡献。

公式:
ϕ i = ∑ S ⊆ { 1 , . . . , n } ∖ { i } ∣ S ∣ ! ( n − ∣ S ∣ − 1 ) ! n ! [ f ( S ∪ { i } ) − f ( S ) ] \phi_i = \sum_{S \subseteq \{1, ..., n\} \setminus \{i\}} \frac{|S|! (n - |S| - 1)!}{n!} \Big[ f(S \cup \{i\}) - f(S) \Big] ϕi=S{1,...,n}{i}n!S!(nS1)![f(S{i})f(S)]

其中:

  • ϕ i \phi_i ϕi:特征 i i i 的 SHAP 值。
  • S S S:包含除 i i i 之外的特征子集。
  • f ( S ) f(S) f(S):仅使用子集 S S S 进行预测的模型输出。
  • f ( S ∪ { i } ) f(S \cup \{i\}) f(S{i}):加入 i i i 之后的预测值。
  • 组合系数 ∣ S ∣ ! ( n − ∣ S ∣ − 1 ) ! n ! \frac{|S|! (n - |S| - 1)!}{n!} n!S!(nS1)! 确保所有子集的贡献被公平分配。

代码示例

import itertools
import numpy as np

def shap_value(model, X, i):
    """ 计算特征 i 的 SHAP 值 """
    n = X.shape[1]  # 特征总数
    phi_i = 0  # 初始化 SHAP 值

    for S in itertools.combinations([j for j in range(n) if j != i], r=None):
        S = list(S)
        weight = np.math.factorial(len(S)) * np.math.factorial(n - len(S) - 1) / np.math.factorial(n)
        f_S = model.predict(X[:, S].mean(axis=0, keepdims=True))  # 仅用 S 预测
        f_Si = model.predict(X[:, S + [i]].mean(axis=0, keepdims=True))  # S + i 预测
        phi_i += weight * (f_Si - f_S)

    return phi_i

shap_values = [shap_value(model, X, i) for i in range(X.shape[1])]

注意:此方法计算复杂度为 O(2^n),高维数据不适用。

  1. Deep SHAP(深度学习 SHAP)

Deep SHAP 结合 DeepLIFT,通过基线输入(baseline)计算输入特征相对于基线的贡献。

公式:
ϕ i = ( x i − x ’ i ) ⋅ ∂ f ( x ) ∂ x i ∣ x ’ \phi_i = (x_i - x’i) \cdot \frac{\partial f(x)}{\partial x_i} \Big|{x’} ϕi=(xixi)xif(x) x

期望 SHAP 计算:
ϕ i = E x ’ ∼ P ( x ’ ) [ ( x i − x ’ i ) ⋅ ∂ f ( x ) ∂ x i ∣ x ’ ] \phi_i = \mathbb{E}_{x’ \sim P(x’)} \Big[ (x_i - x’i) \cdot \frac{\partial f(x)}{\partial x_i} \Big|{x’} \Big] ϕi=ExP(x)[(xixi)xif(x) x]

其中:
x ’ x’ x 是基线输入(如零输入、均值输入)。
P ( x ’ ) P(x’) P(x) 是基线输入的分布,用多个样本求期望。
• 计算输入 x i x_i xi 相对于基线 x ’ i x’_i xi 的贡献,结合梯度信息衡量 SHAP 值。

代码示例

import shap
import torch

X_baseline = X_train.mean(axis=0, keepdims=True)  # 均值作为基线输入
explainer = shap.DeepExplainer(model, torch.tensor(X_baseline, dtype=torch.float32))
shap_values = explainer.shap_values(torch.tensor(X_test, dtype=torch.float32))

适用场景:深度学习(如 CNN、RNN、Transformer)。

  1. Kernel SHAP(通用模型)

Kernel SHAP 采用加权线性回归近似 SHAP 值。

公式:
ϕ = arg ⁡ min ⁡ ϕ ∑ S ⊆ N w ( S ) ( f ( S ) − ∑ i ∈ S ϕ i ) 2 \phi = \arg\min_{\phi} \sum_{S \subseteq N} w(S) \Big( f(S) - \sum_{i \in S} \phi_i \Big)^2 ϕ=argϕminSNw(S)(f(S)iSϕi)2

其中:
w ( S ) w(S) w(S) 是加权因子,近似 Shapley 值。

代码示例

import shap
explainer = shap.KernelExplainer(model.predict, X_train)
shap_values = explainer.shap_values(X_test)

适用场景:适用于任何黑盒模型,但计算较慢。

  1. Tree SHAP(决策树)

Tree SHAP 针对 决策树(XGBoost, LightGBM) 进行了优化,计算复杂度降低:

复杂度:
O ( T L ) O(TL) O(TL)
其中:
T T T 是树的数量。
L L L 是树的最大深度。

代码示例

explainer = shap.TreeExplainer(model)
shap_values = explainer.shap_values(X_test)

适用场景:梯度提升树(GBDT、XGBoost、LightGBM)。

  1. 处理 Embedding 特征的 SHAP 计算

当特征经过 Embedding 层 变成 多维向量,每个 SHAP 计算都会返回多个 SHAP 值,例如:

X_category → Embedding → (d_embedding × SHAP values)

如何衡量整个特征的影响?

  1. 绝对值均值: 1 d ∑ i = 1 d ϕ i \frac{1}{d} \sum_{i=1}^{d} \phi_i d1i=1dϕi
  2. L2 范数: ∑ i = 1 d ϕ i 2 \sqrt{\sum_{i=1}^{d} \phi_i^2} i=1dϕi2
  3. 最大 SHAP 值: max ⁡ ( ϕ 1 ) \max( \phi_1) max(ϕ1)

  1. 计算 SHAP 重要性示例

计算 L2 范数作为整体特征贡献

shap_feature_importance = np.linalg.norm(shap_values, axis=1)

计算特征的绝对 SHAP 均值

shap_feature_importance = np.mean(np.abs(shap_values), axis=1)

找出贡献最大的维度

top_k_dims = np.argsort(np.abs(shap_values), axis=1)[:, -3:]

  1. 总结

7. 总结

SHAP 方法适用模型计算复杂度优点缺点
经典 SHAP 计算任何模型( O(2^n) )精确计算 Shapley 值,理论最优计算量指数级增长,无法用于高维数据
Deep SHAP深度学习(CNN, RNN, Transformer)( O(n) )适用于神经网络,支持梯度计算依赖于选定的基线数据,解释可能受基线选择影响
Kernel SHAP任何模型(黑盒)( O(n^2) )适用于任何模型,无需访问模型内部计算较慢,高维数据开销大
Tree SHAP决策树(XGBoost, LightGBM)( O(TL) )计算高效,支持任意树模型仅适用于树模型,无法用于 DNN
L2 范数聚合处理嵌入特征( O(d) )适用于高维嵌入特征,衡量整体贡献不能解释具体维度贡献,仅提供整体影响
最大 SHAP 绝对值处理嵌入特征( O(d) )捕捉最重要维度贡献可能忽略次要维度的影响

这篇 Markdown 代码 适用于 CSDN、Jupyter Notebook、GitHub Markdown 编辑器,确保公式和代码格式正确展示!🚀

随机森林作为一种集成学习算法,其模型解释性相对复杂。SHAP的引入可以帮助我们量化特征对模型预测结果的贡献,从而提供直观的解释。以下是如何结合TensorFlow或Keras实现随机森林模型,并使用SHAP解释单个预测特征贡献的步骤: 参考资源链接:[理解SHAP:机器学习模型解释工具的实践指南](https://wenku.csdn.net/doc/2gdskp05ui?spm=1055.2569.3001.10343) 1. **训练随机森林模型**:首先,你需要使用TensorFlow或Keras训练好一个随机森林模型。例如,如果你使用Keras,可以利用`keras.RandomForestClassifier`来训练模型。 2. **安装并导入SHAP库**:确保你已经安装了SHAP库,可以使用pip进行安装:`pip install shap`。随后,在你的脚本中导入SHAP库:`import shap`。 3. **计算SHAP**:使用SHAP提供的接口来计算模型的SHAP。如果你的模型已经训练好并保存为一个变量`model`,你可以使用以下代码来计算测试数据集上每个样本的SHAP: ```python import shap # 假设X_test是你的测试数据集 explainer = shap.TreeExplainer(model) shap_values = explainer.shap_values(X_test) ``` 4. **可视化特征贡献**:SHAP库提供了一种简单的方法来可视化特征对预测结果的贡献。例如,你可以使用`shap.summary_plot`来显示一个汇总的特征重要性图: ```python shap.summary_plot(shap_values[1], X_test, feature_names=feature_names) ``` 其中`shap_values[1]`表示选择第一个预测的SHAP进行可视化,`feature_names`是你的特征名称列表。 5. **解释单个预测**:最后,你可以选择一个特定的预测实例来查看每个特征是如何影响模型输出的: ```python shap.initjs() shap.force_plot(explainer.expected_value, shap_values[1][0,:], X_test.iloc[0,:], feature_names=feature_names) ``` 这将展示一个力导向图,可视化解释了第一个样本的预测结果。 通过上述步骤,你可以清晰地看到随机森林模型中单个预测的特征贡献,并以直观的形式展现出来。这有助于你更好地理解模型是如何作出决策的,从而提高模型的透明度和可信度。 如需进一步深入学习SHAP的理论和实践细节,建议参考这份资源:《理解SHAP:机器学习模型解释工具的实践指南》。这份文档详细介绍了SHAP的原理及其在机器学习模型解释中的应用,提供实战案例,帮助你全面掌握这一技术。 参考资源链接:[理解SHAP:机器学习模型解释工具的实践指南](https://wenku.csdn.net/doc/2gdskp05ui?spm=1055.2569.3001.10343)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值