机器学习可解释性之shap模块的使用——基础用法(一)

文章目录

之前对模型可解释性有相关的讨论:
模型树结构的可视化、特征重要性

本文主要是总结shap对模型进行可解释性分析时的使用方式与含义,简单来说就是把官方文档翻译一遍:
Shap模块官方文档

安装命令如下:


pip3 install shap

conda install -c conda-forge shap

本文使用shap版本为0.39.0,所展示的案例中要导入的所有的包如下:

import shap
import sklearn
import matplotlib.pyplot as plt
import interpret.glassbox
import xgboost
import pandas as pd
import transformers
import datasets
import torch
import numpy as np
import scipy as sp

【用Shapely解释机器学习模型】

1. 用Shapely解释线性模型

1.1 传统特征系数计算


data_df, label_array = shap.datasets.boston()
print(list(data_df.columns))
"""
数据集中的所有特征名称
['CRIM', 'ZN', 'INDUS', 'CHAS', 'NOX', 'RM', 'AGE', 'DIS', 'RAD', 'TAX', 'PTRATIO', 'B', 'LSTAT']
"""

X100 = shap.utils.sample(data_df, 100)

model = sklearn.linear_model.LinearRegression()
model.fit(data_df, label_array)

print("Model coefficients:\n")
for i in range(data_df.shape[1]):
    print(data_df.columns[i], "=", model.coef_[i].round(5))
"""
Model coefficients:

CRIM = -0.10801
ZN = 0.04642
INDUS = 0.02056
CHAS = 2.68673
NOX = -17.76661
RM = 3.80987
AGE = 0.00069
DIS = -1.47557
RAD = 0.30605
TAX = -0.01233
PTRATIO = -0.95275
B = 0.00931
LSTAT = -0.52476
"""

1.2 部分特征依赖图(partial dependence plots)

shap.partial_dependence_plot(
    ind="CRIM", model=model.predict,
    data=X100, ice=False,
    model_expected_value=True,
    feature_expected_value=True
)

如图所示,其中E [ f ( x ) ] E[f(x)]E [f (x )]对应的 灰色横线表示的是模型对波士顿房价预测的期望值,垂直的灰色线条表示的是特征CRIM的平均取值,蓝色的线表示的是模型预测结果的平均值随特征CRIM平均取值的变化,从图中可以看出也就意味着CRIM平均取值越大,预测的数值平均会越小,二者相交的点为依赖中心。灰色的条形图则表示参与模型可解释性的样本的数据分布。

机器学习可解释性之shap模块的使用——基础用法(一)
对线性预测模型f ( x ) f(x)f (x )进行可解释性分析时,对于特定特征C R I M CRIM CR I M而言其对应的shap值为在特征i i i取值下的样本x C R I M = 特定值 x_{CRIM=特定值}x CR I M =特定值​的模型预测数值f ( x C R I M = 特定值 ) f(x_{CRIM=特定值})f (x CR I M =特定值​)和部分特征依赖图中对应的期望预测均值E ( f ( x ) ∣ C R I M = 特定值 ) E(f(x)|{CRIM=特定值})E (f (x )∣CR I M =特定值​)的差值,即:s i n g l e _ s h a p C R I M = f ( x C R I M = 特定值 ) − E ( f ( x ) ∣ C R I M = 特定值 ) single_shap{CRIM}=f(x_{CRIM=特定值})-E(f(x)|{CRIM=特定值})s in g l e _s ha p CR I M ​=f (x CR I M =特定值​)−E (f (x )∣CR I M =特定值)

explainer = shap.Explainer(model.predict, X100)
shap_values = explainer(data_df)

sample_ind = 20
shap.partial_dependence_plot(
    ind="CRIM", model=model.predict,
    data=X100, ice=False,
    model_expected_value=True,
    feature_expected_value=True,
    shap_values=shap_values[sample_ind:sample_ind+1, :]
)

机器学习可解释性之shap模块的使用——基础用法(一)
shap值和部分特征依赖图之间联系紧密,因此如果能够在数据集中绘制特定特征对应的shap值,就能够很快解析出该特征对应的部分特征依赖图的依赖中心

shap.plots.scatter(shap_values[:, "CRIM"], show=False)
plt.tight_layout()
plt.show()

机器学习可解释性之shap模块的使用——基础用法(一)

1.3 瀑布图(waterfall plot)

shap值计算过程中的一个基本属性是,对所有特征而言,其shap取值总是多有样本对应的期望预测结果和当前预测结果之差的总和,即:t o t a l _ s h a p C R I M = ∑ ( f ( x C R I M = 特定值 ) − E [ f ( x ) ∣ C R I M = 特定值 ] ) total_shap_{CRIM}=\sum(f(x_{CRIM=特定值})-E[f(x)|CRIM=特定值])t o t a l _s ha p CR I M ​=∑(f (x CR I M =特定值​)−E [f (x )∣CR I M =特定值])特定值 ∈ 数据集中 C R I M 的取值集合 特定值\in 数据集中CRIM的取值集合特定值∈数据集中CR I M 的取值集合
对于从样本期望输出值E [ f ( x ) ] E[f(x)]E [f (x )]而言,要得到模型预测的输出结果f ( x ) f(x)f (x ),需要逐步增加其他特征,使得期望输出不断靠近预测结果,瀑布图就能够清楚的展示该过程


sample_ind = 20

plt.subplots(constrained_layout=True)
shap.plots.waterfall(shap_values[sample_ind], max_display=14)

机器学习可解释性之shap模块的使用——基础用法(一)

2. 用Shapely解释加法回归模型

线性模型的部分依赖图之所以与SHAP值有如此密切的联系,是因为在线性模型中每个特征都是独立进行处理的(最终效果是加在一起)。可以在放宽直线的线性要求的同时保留这种加法特性,从而就衍生出了很多广义上的加法模型(Generalized Additive Models, GAMs),如:深度为1的XGBOOST。在shap模块中,专门为广义的模型设计了 InterpretMLs explainable boosting machines(可解释性提升机器?),用于解释更宽泛的预测模型

2.1 基础解释图(局部依赖、依赖关系散点图、瀑布图)


model_ebm = interpret.glassbox.ExplainableBoostingRegressor(interactions=0)
model_ebm.fit(data_df, label_array)

explainer_ebm = shap.Explainer(model_ebm.predict, X100)
shap_values_ebm = explainer_ebm(data_df)
sample_ind = 20

fig, ax = shap.partial_dependence_plot(
    ind="CRIM",  model=model_ebm.predict, data=X100,
    model_expected_value=True, feature_expected_value=True, ice=False,
    shap_values=shap_values_ebm[sample_ind:sample_ind + 1, :]
)

机器学习可解释性之shap模块的使用——基础用法(一)

shap.plots.scatter(shap_values_ebm[:, "CRIM"], show=False)
plt.tight_layout()
plt.show()

机器学习可解释性之shap模块的使用——基础用法(一)

shap.plots.waterfall(shap_values_ebm[sample_ind], show=False)
plt.tight_layout()
plt.show()

机器学习可解释性之shap模块的使用——基础用法(一)

2.2 蜂群图(beeswarm)


shap.plots.beeswarm(shap_values_ebm, show=False)
plt.tight_layout()
plt.show()

蜂群图可以反映各个特征取值的高低对SHAP取值的影响(结合上述对SHAP的解释,SHAP值的绝对值越大表明期望输出和真实输出的差异越大),就可以看到特征对模型预测的影响

机器学习可解释性之shap模块的使用——基础用法(一)

3. 用Shapely解释非加法性质的提升树模型

3.1 基础解释图(部分依赖图、依赖关系图)


model_xgb = xgboost.XGBRegressor(n_estimators=100, max_depth=2).fit(data_df, label_array)

explainer_xgb = shap.Explainer(model_xgb, X100)
shap_values_xgb = explainer_xgb(data_df)
sample_ind = 20

fig, ax = shap.partial_dependence_plot(
    ind="CRIM", model=model_xgb.predict, data=X100,
    model_expected_value=True,
    feature_expected_value=True, ice=False,
    shap_values=shap_values_xgb[sample_ind:sample_ind + 1, :]
)

机器学习可解释性之shap模块的使用——基础用法(一)

shap.plots.scatter(shap_values_xgb[:, "CRIM"], show=False)
plt.tight_layout()
plt.show()

机器学习可解释性之shap模块的使用——基础用法(一)

3.2 带SHAP值的依赖关系图


shap.plots.scatter(shap_values_xgb[:, "CRIM"], color=shap_values_xgb, show=False)
plt.tight_layout()
plt.show()

机器学习可解释性之shap模块的使用——基础用法(一)

4. 用Shapely解释线性逻辑回归分类模型

4.1 基础解释图(局部依赖、依赖关系图)


X_iris, y_iris = shap.datasets.iris()
print(list(X_iris.columns))

model_iris = sklearn.linear_model.LogisticRegression(max_iter=10000)
model_iris.fit(X_iris, y_iris)

def model_iris_proba(x):
    return model_iris.predict_proba(x)[:, 1]

def model_iris_log_odds(x):
    p = model_iris.predict_log_proba(x)
    return p[:, 1] - p[:, 0]

sample_ind = 18
fig, ax = shap.partial_dependence_plot(
    ind="sepal length (cm)", model=model_iris_proba,
    data=X_iris, model_expected_value=True,
    feature_expected_value=True, ice=False
)

机器学习可解释性之shap模块的使用——基础用法(一)

background_iris = shap.maskers.Independent(X_iris, max_samples=100)
explainer = shap.Explainer(model_iris_proba, background_iris)
shap_values_iris = explainer(X_iris[:1000])

shap.plots.scatter(shap_values_iris[:, "petal width (cm)"], show=False)
plt.tight_layout()
plt.show()

机器学习可解释性之shap模块的使用——基础用法(一)

4.2 引入log的线性依赖关系图


explainer_log_odds = shap.Explainer(model_iris_log_odds, background_iris)
shap_values_iris_log_odds = explainer_log_odds(X_iris[:1000])

shap.plots.scatter(shap_values_iris_log_odds[:, "petal width (cm)"], show=False)
plt.tight_layout()
plt.show()

log概率预测值可以观察输入与输出之间的线性关系

机器学习可解释性之shap模块的使用——基础用法(一)

sample_ind = 18
fig, ax = shap.partial_dependence_plot(
    "petal width (cm)", model_iris_log_odds, X_iris, model_expected_value=True,
    feature_expected_value=True, ice=False
)

机器学习可解释性之shap模块的使用——基础用法(一)

5. 用Shapely解释非加法性质的提升树逻辑回归模型

adult数据集下载
数据集预处理参考

5.1 特征重要性

5.1.1 特征重要性条形图(SHAP平均绝对值)

columns = ['Age', 'Workclass', 'fnlgwt', 'Education', 'EdNum', 'MaritalStatus',
           'Occupation', 'Relationship', 'Race', 'Sex', 'CapitalGain',
           'CapitalLoss', 'HoursPerWeek', 'Country', 'Income']

adult_df = pd.read_csv("adult.data", names=columns)

def data_process(df):
"""
    处理数据集的函数
    :param df:
    :param model:
    :return:
"""
    df.replace(" ?", pd.NaT, inplace=True)
    df.replace(" >50K", 1, inplace=True)
    df.replace(" , 0, inplace=True)
    trans = {'Workclass': df['Workclass'].mode()[0], 'Occupation': df['Occupation'].mode()[0],
             'Country': df['Country'].mode()[0]}
    df.fillna(trans, inplace=True)
    df.drop('fnlgwt', axis=1, inplace=True)
    df.drop('CapitalGain', axis=1, inplace=True)
    df.drop('CapitalLoss', axis=1, inplace=True)
    df_object_col = [col for col in df.columns if df[col].dtype.name == 'object']
    df_int_col = [col for col in df.columns if df[col].dtype.name != 'object' and col != 'Income']
    target = df["Income"]
    dataset = pd.concat([df[df_int_col], pd.get_dummies(df[df_object_col])], axis=1)

    return dataset, target

X_adult, y_adult = data_process(adult_df)

print(list(X_adult.columns))

xgb_adult = xgboost.XGBClassifier(n_estimators=5, max_depth=2).fit(X_adult, y_adult * 1, eval_metric="logloss")

background_adult = shap.maskers.Independent(X_adult, max_samples=100)
explainer = shap.Explainer(xgb_adult, background_adult)
shap_values = explainer(X_adult)

shap.plots.bar(shap_values, show=False)
plt.tight_layout()
plt.show()

特征条形图反应了特征与SHAP平均绝对值之间的关系,也就从全局反应了特征重要性的排名

机器学习可解释性之shap模块的使用——基础用法(一)

5.1.2 特征重要性条形图(SHAP最大绝对值)


shap.plots.bar(shap_values.abs.max(0), show=False)
plt.tight_layout()
plt.show()

机器学习可解释性之shap模块的使用——基础用法(一)

5.2 蜂群图

5.2.1 基础蜂群图

shap.plots.beeswarm(shap_values, show=False)
plt.tight_layout()
plt.show()

机器学习可解释性之shap模块的使用——基础用法(一)

5.2.2 绝对值蜂群图(配色更改)

shap.plots.beeswarm(shap_values.abs, color="shap_red", show=False)
plt.tight_layout()
plt.show()

绝对值蜂群图是蜂群图和条形图的折中,复杂度适中,也能反应特征的重要性

机器学习可解释性之shap模块的使用——基础用法(一)

5.3 热力图


shap.plots.heatmap(shap_values[:1000], show=False)
plt.tight_layout()
plt.show()

机器学习可解释性之shap模块的使用——基础用法(一)

5.4 散点图

5.4.1 基础散点图(依赖关系图)

shap.plots.scatter(shap_values[:, "Age"], show=False)
plt.tight_layout()
plt.show()

机器学习可解释性之shap模块的使用——基础用法(一)
shap.plots.scatter(shap_values[:, "EdNum"], color=shap_values, show=False)
plt.tight_layout()
plt.show()

机器学习可解释性之shap模块的使用——基础用法(一)

5.4.2 散点图(根据SHAP值分配颜色)

shap.plots.scatter(shap_values[:, "Age"], color=shap_values, show=False)
plt.tight_layout()
plt.show()

机器学习可解释性之shap模块的使用——基础用法(一)

5.4.3 散点图(根据其他特征SHAP值分配颜色)

shap.plots.scatter(shap_values[:, "Age"], color=shap_values[:, "HoursPerWeek"], show=False)
plt.tight_layout()
plt.show()

机器学习可解释性之shap模块的使用——基础用法(一)

5.5 特征聚类相关性条形图


clustering = shap.utils.hclust(X_adult, y_adult)

shap.plots.bar(shap_values, clustering=clustering, show=False)
plt.tight_layout()
plt.show()

机器学习可解释性之shap模块的使用——基础用法(一)

shap.plots.bar(shap_values, clustering=clustering, clustering_cutoff=0.8, show=False)
plt.tight_layout()
plt.show()

机器学习可解释性之shap模块的使用——基础用法(一)

Original: https://blog.csdn.net/weixin_36488653/article/details/126787642
Author: `AllureLove
Title: 机器学习可解释性之shap模块的使用——基础用法(一)

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/614392/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球