跳到主要内容

分类模型的 SHAP 值归因分析

一、直观理解:把一次预测的“功劳”公平分给各个特征​

模型给出“该客户违约概率 0.82”,业务要问:是负债率太高,还是近期待还款过多?SHAP(SHapley Additive exPlanations)借用合作博弈论中的 Shapley 值:把特征当作玩家,把预测相对基线的变化当作联盟收益,按“边际贡献的加权平均”给每个特征打分。

对单次预测:

f(x)=ϕ0+∑j=1pϕjf(x)=\phi_0+\sum_{j=1}^{p}\phi_j
  • ϕ0\phi_0:基线(通常是训练集预测均值);
  • ϕj\phi_j:特征 jj 把预测从基线推高或推低了多少。

全局解释则汇总许多样本的 ∣ϕj∣|\phi_j| 或画蜂群图。SHAP 满足局部准确性、缺失性、一致性等理想性质,是当前表格模型解释的主流工具之一。

二、适用场景与优缺点​

类型说明
适用场景黑箱/集成模型上线或写论文需要解释;要同时做局部(个案)与全局(特征排序)说明;对比不同模型的驱动因素;检查模型是否用了“泄漏特征”。
核心优点有公理化基础;加性分解清晰;TreeSHAP 对树模型高效一致;可视化体系成熟。
局限与缺点相关特征时归因会分摊、解读需谨慎;计算对模型无关法可能很慢;解释的是模型而非世界因果;实现依赖工具版本。

使用前:固定训练好的模型与背景数据;明确解释的是对数几率还是概率;相关特征成组解读。

三、核心原理​

1. Shapley 值​

特征集合 FF,模型对特征子集 SS 的预测期望为 v(S)v(S)。特征 jj 的 Shapley 值:

ϕj=∑S⊆F∖{j}∣S∣!(∣F∣−∣S∣−1)!∣F∣!(v(S∪{j})−v(S))\phi_j=\sum_{S\subseteq F\setminus\{j\}}\frac{|S|!(|F|-|S|-1)!}{|F|!}\big(v(S\cup\{j\})-v(S)\big)

即:在所有加入顺序下,特征 jj 带来的平均边际贡献。

2. 与模型结合​

  • KernelSHAP:模型无关,加权回归近似,较慢;
  • TreeSHAP:针对树/森林/GBDT 的多项式时间精确算法;
  • 线性模型:SHAP 与“系数 × 特征偏离”密切相关。

3. 依赖与相关​

若特征相关,边缘期望与条件期望两种路径会导致不同归因哲学(interventional vs conditional)。论文中应说明工具默认行为,避免把相关特征的 SHAP 读成独立因果效应。

四、关键决策​

决策点建议
背景集从训练集抽样 50–200 点作期望基线
解释尺度树模型常在 log-odds;展示时说明
全局图mean(
局部图waterfall / force plot 讲个案
相关特征合并讨论或分层分析
工具MATLAB 可手写线性 SHAP;复杂树模型可导出到 Python shap

五、MATLAB 示例​

下面给出线性模型闭式 SHAP 风格分解(标准化特征下,ϕj=βjxj\phi_j=\beta_j x_j,ϕ0\phi_0 为截距/均值项),以及树模型的排列重要性对照。完整 TreeSHAP 可在外部用 Python 计算后读回表格。

% ---- 1) 线性 Logistic / 线性得分的加性归因 ----
X = [
25 4.5 0.45;
40 9.0 0.20;
33 6.2 0.38;
50 12.0 0.15;
29 5.0 0.50;
45 10.5 0.22
];
y = [1;0;1;0;1;0];
names = ["年龄","收入","负债率"];

[Xz, mu, sig] = zscore(X);
mdl = fitclinear(Xz, y, "Learner", "logistic", ...
"Regularization", "ridge", "Lambda", 1e-2, "Solver", "lbfgs");

beta = mdl.Beta; % p x 1
b0 = mdl.Bias; % 截距
% 对样本 i: f = b0 + sum beta_j * Xz_ij
% 线性模型在独立特征假设下的 Shapley 即各维贡献
i = 1;
phi0 = b0;
phi = beta .* Xz(i, :)';
f = phi0 + sum(phi);

fprintf("样本 %d 的模型得分 f=%.4f\n", i, f);
fprintf("基线 phi0=%.4f\n", phi0);
for j = 1:numel(names)
fprintf(" %s: phi=%.4f (标准化值=%.3f)\n", names(j), phi(j), Xz(i,j));
end

% 可视化单样本归因
figure;
barh(phi);
set(gca, "YTickLabel", names);
xlabel("SHAP 风格贡献(线性)");
title("个案特征贡献");

% ---- 2) 树模型:用排列重要性做全局解释对照 ----
rf = TreeBagger(80, X, y, "Method", "classification", ...
"OOBPredictorImportance", "on", "MinLeafSize", 1);
imp = rf.OOBPermutedPredictorDeltaError;
figure; bar(imp);
set(gca, "XTickLabel", names);
ylabel("OOB 排列重要性");
title("随机森林全局重要性(非 SHAP,可作对照)");

% ---- 3) 若已用 Python shap 导出 csv ----
% T = readtable("shap_values.csv");
% meanAbs = mean(abs(T{:,:}), 1);
% bar(meanAbs); set(gca,"XTickLabel", T.Properties.VariableNames);

Python 侧(可选,供赛题复现)示意:

# import shap, sklearn
# explainer = shap.TreeExplainer(model)
# shap_values = explainer.shap_values(X)
# shap.summary_plot(shap_values, X)

六、如何解释结果​

  1. 个案:哪些特征把预测推离基线,方向是否符合业务;
  2. 全局排序:mean(|SHAP|) 高的特征是模型主要依赖;
  3. 依赖图:SHAP 随特征值变化是否单调、是否有阈值效应;
  4. 异常归因:若某无业务意义的变量 SHAP 很高,检查泄漏;
  5. 报告:模型类型、背景数据、解释尺度、Top 特征、1–2 个典型案例瀑布说明。

七、常见误区​

1. 把 SHAP 当成因果效应​

它解释模型计算,不自动等于干预世界后的结果。

2. 相关特征上过度解读“唯一功臣”​

共线时贡献会拆分或不稳定。

3. 背景集用测试集或含未来信息​

解释基线应来自合理的参照分布。

4. 只给全局条形图,不给个案​

分类题常需要“为什么这个人被判高风险”。

5. 不同模型的 SHAP 绝对值横比​

尺度与基线不同,不宜直接比大小跨模型硬刚,应比排序与方向。

八、小结​

SHAP 用 Shapley 值把单次预测分解为各特征的加性贡献,是连接黑箱分类器与论文叙事、业务沟通的标准桥梁。

好的可解释性流程是:先有准确且验证过的模型,再用 SHAP 做全局与局部归因,并明确“解释模型 ≠ 证明因果”。线性模型可闭式分解,树模型优先 TreeSHAP,必要时 MATLAB 与 Python 分工协作。