Py学习  »  机器学习算法

使用 shap 使机器学习模型变的可解释!!

GIS研发 • 1 年前 • 523 次点击  

大家好,我是小寒

今天给大家分享机器学习中的一个关键概念,SHAP 值

SHAP 值是一种用于解释机器学习模型的技术。它基于合作博弈论中的 Shapley 值概念,通过为每个特征分配一个"贡献值"来解释模型的预测结果。

SHAP 值提供了一种公平且理论稳健的方法来解释机器学习模型的行为,特别是在黑盒模型(如深度学习、集成方法等)中,这种解释方法非常有价值。

Shapley 值的理论背景

Shapley 值是由 Lloyd Shapley 于1953年提出的,它最初是用来衡量在合作博弈中,各个参与者对合作结果的贡献。

在机器学习中,特征被看作是博弈中的参与者,模型的预测结果则是合作博弈的总收益。

Shapley 值的核心思想是,计算每个特征在所有可能特征排列中的边际贡献,并基于这一贡献分配模型的预测结果。

Shap 值的计算

给定一个预测模型,假设模型的输入是一个特征向量 ,模型的预测结果是 。

Shap 值用来度量特征  对模型预测结果  的贡献。

数学公式如下所示

其中

  •  是特征  的 Shap 值,表示特征  对最终预测结果的贡献。
  • N 是特征集,表示模型的所有特征。
  • S 是特征集 N 的一个子集,不包括特征 。
  •  是模型在子集 S 上的预测结果。
  •  是在特征子集  的基础上,加入特征   后的模型预测值。

解释过程

  • 边际贡献

    对于每个特征 ,其边际贡献是通过计算在包含该特征时的模型输出与不包含该特征时的模型输出之间的差异来确定的。

    通过对所有可能的特征排列进行计算,Shap 值能够公平地分配每个特征对最终模型预测结果的贡献。

  • 权重

    公式中的 是每个排列的概率,它保证了每个特征在不同排列中的贡献都会被平等对待。这确保了 Shap 值的公平性。

这个公式的核心思想是,计算所有可能的特征组合,并分析某个特征在不同组合下的贡献,最终通过加权平均计算其 Shap 值。

然而,由于遍历所有子集的计算复杂度是指数级别,直接计算 SHAP 值在高维数据上是不现实的,因此 SHAP 提供了多种近似算法,能够在多种复杂模型下快速计算 SHAP 值。

近似 SHAP 值的方法

为了降低计算SHAP值的复杂度,研究人员提出了几种近似方法,其中最著名的包括。

  1. Kernel SHAP:一种通过采样和加权的方法,用于近似SHAP值的计算。
  2. Tree SHAP:针对树模型(如随机森林、XGBoost等)优化的SHAP计算方法,可以显著加快计算速度。

SHAP 值的加法性

SHAP 值是加法性的,这意味着每个特征的 SHAP 值可以直接加起来,以得到模型的预测结果。

设模型的预测值为 ,其中   是所有特征。则SHAP值满足:

其中, 是模型的基准预测值(例如,在没有任何特征时的预测值),而  是每个特征  对预测的贡献。

SHAP 值通过这种加法性确保了各个特征的贡献可以独立计算并加和,得到模型的最终预测。

SHAP 值的应用

SHAP 值可以应用于多种领域

  • 模型可解释性

    SHAP 值可以用来解释复杂模型(如深度学习模型、XGBoost、随机森林等)在个体预测中的决策过程,帮助理解模型如何依赖每个特征。

  • 特征选择

    通过评估不同特征的 SHAP 值,可以筛选出对模型预测最重要的特征。

  • 公平性和合规性

    SHAP值有助于提高机器学习模型在实际应用中的透明度,尤其在涉及到金融、医疗等领域时,SHAP值可以帮助确保模型的决策过程符合监管要求。

SHAP 值的优点

SHAP 值相较于其他解释方法(如LIME)有几个重要的优点

  • 理论基础:SHAP 值基于博弈论中的Shapley值,具有明确的理论基础,确保解释结果的公平性。
  • 一致性:SHAP 值满足一致性原理,如果某个特征在所有情况下对模型预测的贡献都增加,那么其SHAP值也不会减少。
  • 模型无关性:SHAP值适用于各种类型的模型,包括线性模型、树模型、深度学习模型等。

案例分享

下面是一个使用 SHAP 值来解释 XGBoost 模型预测结果的完整示例代码。

这个示例将展示如何训练一个 XGBoost 模型,并使用 SHAP 值来解释模型的预测。

import shap
import xgboost as xgb
import pandas as pd
import numpy as np
from sklearn.datasets import load_diabetes
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler

# 加载糖尿病数据集
data = load_diabetes()
X = pd.DataFrame(data.data, columns=data.feature_names)
y = pd.Series(data.target)

# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 标准化特征
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)

# 创建并训练 XGBoost 模型
model = xgb.XGBRegressor(objective='reg:squarederror', random_state=42)
model.fit(X_train_scaled, y_train)

# 使用 SHAP 解释模型
explainer = shap.Explainer(model, X_train_scaled)  # 创建解释器
shap_values = explainer(X_test_scaled)  # 计算 SHAP 值

# 可视化 SHAP 值的汇总图
shap.summary_plot(shap_values, X_test_scaled, feature_names=X.columns)

Force Plot

解释单个样本的预测贡献

shap.initjs()  # 初始化 JavaScript 环境
sample_index = 10  # 选择某个测试样本
shap.force_plot(explainer.expected_value, shap_values[sample_index].values, X_test.iloc[sample_index])

Bar Plot

SHAP 条形图,观察特征重要性

shap.plots.bar(shap_values)


最后

—


今天的分享就到这里。如果觉得近期的文章不错,请点赞,转发安排起来。‍‍
欢迎大家进高质量 python 学习群‍ ‍‍‍‍‍‍‍

「进群方式:加我微信,备注 “python”」



往期回顾


Fashion-MNIST 服装图片分类-Pytorch实现

python 探索性数据分析(EDA)案例分享

深度学习案例分享 | 房价预测 - PyTorch 实现

万字长文 |  面试高频算法题之动态规划系列

面试高频算法题之回溯算法(全文六千字)  

    




如果对本文有疑问可以加作者微信直接交流。

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/181311