PyTorch 的 SHAP 值 - KernelExplainer 与 DeepExplainer

Cos*_*net 7 python pytorch shap

我还没有找到太多有关 PyTorch 的 SHAP 值的示例。我使用了两种技术来生成 SHAP 值,但是它们的结果似乎彼此不一致。

SHAP KernelExplainer 与 PyTorch

import torch
from torch.autograd import Variable
import shap
import numpy
import pandas

torch.set_grad_enabled(False)

# Get features
train_features_df = ... # pandas dataframe
test_features_df = ... # pandas dataframe

# Define function to wrap model to transform data to tensor
f = lambda x: model_list[0]( Variable( torch.from_numpy(x) ) ).detach().numpy()

# Convert my pandas dataframe to numpy
data = test_features_df.to_numpy(dtype=np.float32)

# The explainer doesn't like tensors, hence the f function
explainer = shap.KernelExplainer(f, data)

# Get the shap values from my test data
shap_values = explainer.shap_values(data)

# Enable the plots in jupyter
shap.initjs()

feature_names = test_features_df.columns
# Plots
#shap.force_plot(explainer.expected_value, shap_values[0], feature_names)
#shap.dependence_plot("b1_price_avg", shap_values[0], data, feature_names)
shap.summary_plot(shap_values[0], data, feature_names)
Run Code Online (Sandbox Code Playgroud)

来自 KernelExplainer 和 PyTorch 的 SHAP 摘要图

SHAP DeepExplainer 与 PyTorch

# It wants gradients enabled, and uses the training set
torch.set_grad_enabled(True)
e = shap.DeepExplainer(model, Variable( torch.from_numpy( train_features_df.to_numpy(dtype=np.float32) ) ) )

# Get the shap values from my test data (this explainer likes tensors)
shap_values = e.shap_values( Variable( torch.from_numpy(data) ) )

# Plots
#shap.force_plot(explainer.expected_value, shap_values, feature_names)
#shap.dependence_plot("b1_price_avg", shap_values, data, feature_names)
shap.summary_plot(shap_values, data, feature_names)
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

比较结果

从汇总图中可以看出,具有相同测试数据的同一 PyTorch 模型的特征值明显不同。

例如,特征 b1_addresses_avg 的 KernelExplainer 的值为倒数第一。但 DeepExplainer 却排名倒数第三。

我不知道从这里该去哪里。

小智 5

Shapley 值很难精确计算。内核 SHAP 和深度 SHAP 是有效计算 Shapley 值的两种不同的近似方法,因此不应期望它们一定一致。

您可以阅读作者的论文以了解更多详细信息。

虽然 Kernel SHAP 可用于任何模型(包括深度模型),但人们很自然地会问是否有一种方法可以利用有关深度网络组成性质的额外知识来提高计算性能。[...] 这促使我们将 DeepLIFT 改造为 SHAP 值的组合近似,从而产生 Deep SHAP。

在第 5 节中,他们比较了 Kernel SHAP 和 Deep SHAP 的性能。从他们的示例来看,Kernel SHAP 的性能似乎比 Deep SHAP 更好。所以我想如果你没有遇到计算问题,你可以坚持使用 Kernel SHAP。

图5B

ps 只是为了确保,您将完全相同的训练模型输入到 SHAP 对吗?您不应该训练单独的模型,因为它们会学习不同的权重。