个人微信小程序免费制作,学seo建网站,推动高质量发展为主题,剁椒怎么做制作方法模型介绍 上面这个图就是一个比较直观的解释。机器学习模型一般都是一个黑盒。比如某个模型要进行一些预测任务#xff0c;首先对模型输入一些已知条件#xff08;Age65,SexF,BP180,BMI40#xff09;#xff0c;然后模型根据输入进行训练#xff0c;最终训练完的模型可以对…模型介绍 上面这个图就是一个比较直观的解释。机器学习模型一般都是一个黑盒。比如某个模型要进行一些预测任务首先对模型输入一些已知条件Age65,SexF,BP180,BMI40然后模型根据输入进行训练最终训练完的模型可以对该条件输出预测结果Output0.4
所以这样模型只能得到最终的结果至于模型内部是怎么计算的输入的已知条件Age65,SexF,BP180,BMI40是怎么对预测结果Output0.4影响的我们都没法知道
而SHAP模型就可以让我们知道这些已知条件到底对最终预测结果起到哪些影响是对结果起到正向影响还是对结果起到了负向影响除了SHAP模型其实也有其他方法可以进行特征重要性的计算比如下面这个表格里提到的我们可以根据各种方法的优点选择适合的进行特征重要性计算 SHAP
而本文主要介绍的SHAP 属于模型事后解释的方法它的核心思想是计算特征对模型输出的边际贡献再从全局和局部两个层面对“黑盒模型”进行解释。SHAP构建一个加性的解释模型所有的特征都视为“贡献者”
SHAP的全称是SHapley Additive exPlanationSHAP是由Shapley value启发的可加性解释模型。而Shapley value起源于合作博弈论那什么是合作博弈呢。比如说甲乙丙丁四个工人一起打工甲和乙完成了价值100元的工件甲、乙、丙完成了价值120元的工件乙、丙、丁完成了价值150元的工件甲、丁完成了价值90元的工件那么该如何公平、合理地分配这四个人的工钱呢Shapley提出了一个合理的计算方法我们称每个参与者分配到的数额为Shapley value。
结合文章一开始提到的预测任务我认为就是已知条件Age65,SexF,BP180,BMI40一起完成了预测结果Output0.4那么该如何公平、合理地分配这四个已知条件对预测结果的贡献呢此时SHAP模型就会给这四个已知条件都分配一个Shapley value值根据这个值我们就可以很好的进行理解
SHAP可以具体解决的任务
调试模型用指导工程师做特征工程指导数据采集的方向指导人们做决策建立模型和人之间的信任
这一部分参见https://yyqing.me/post/2018/2018-09-25-kaggle-model-insights
SHAP库可用的explainers
在SHAP中进行模型解释需要先创建一个explainerSHAP支持很多类型的explainer
deep用于计算深度学习模型基于DeepLIFT算法支持TensorFlow / Keras。gradient用于深度学习模型综合了SHAP、集成梯度、和SmoothGrad等思想形成单一期望值方程但速度比DeepExplainer慢并且做出了不同的假设。 此方法基于Integrated Gradient归因方法并支持TensorFlow / Keras / PyTorch。kernel模型无关适用于任何模型linear适用于特征独立不相关的线性模型tree适用于树模型和基于树模型的集成算法如XGBoostLightGBM或CatBoost
实验
在网上找了几个相关的实验跑一下加深印象SHAP模型输出的可视化图真的是挺美观的。
红色特征使预测值更大类似正相关蓝色使预测值变小紫色邻近均值。而颜色区域宽度越大说明该特征的影响越大。 这里我们尝试通过SHAP来解释深度学习模型每一层网络对最终检查结果的影响情况。11种shap可视化图形来解释任何机器学习模型统计如下 数据集
标准的 UCI 成人收入数据集。
import shap
X,y shap.datasets.adult()
X_display, y_display shap.datasets.adult(displayTrue)创建Explainer并计算SHAP值
在SHAP中进行模型解释需要先创建一个explainerSHAP支持很多类型的explainer(例如deep, gradient, kernel, linear, tree, sampling)本文使用支持常用的XGB、LGB、CatBoost等树集成算法的tree为例。
deep用于计算深度学习模型基于DeepLIFT算法gradient用于深度学习模型综合了SHAP、集成梯度、和SmoothGrad等思想形成单一期望值方程kernel模型无关适用于任何模型linear适用于特征独立不相关的线性模型tree适用于树模型和基于树模型的集成算法sampling 基于特征独立性假设当你想使用的后台数据集很大时kenel的一个很好的替代方案
explainer shap.TreeExplainer(model) 然后计算shap_values值计算非常简单直接利用上面得到的解释器解释训练样本X这里有两种形式
输出numpy.array数组
shap_values explainer.shap_values(X) 输出shap.Explanation对象
shap_values2 explainer(X) 模型自带特征重要性
关于模型解释性除了线性模型和决策树这种天生就有很好解释性的模型意外sklean/ xgboost 中有很多模型都有importance这一接口可以查看特征的重要性。
model xgboost.XGBClassifier(eval_metricmlogloss).fit(X, y)
xgboost.plot_importance(model,height .5, max_num_features10,show_values False)SHAP 特征重要性
Summary Plot
将 SHAP 值矩阵传递给条形图函数会创建一个全局特征重要性图其中每个特征的全局重要性被视为该特征在所有给定样本中的平均绝对值。
shap.summary_plot(shap_values, X_display, plot_typebar)在上面两图中可以看到由 SHAP value 计算的特征重要性与使用 scikit-learn / xgboost计算的特征重要性之间的比较它们看起来非常相似但它们并不相同。
Bar plot
全局条形图
特征重要性的条形图还有另一种绘制方法。
shap.plots.bar(shap_values2)同一个 shap_values不同的计算 summary_plot中的shap_values是 numpy.array数组 plots.bar中的shap_values是 shap.Explanation对象 当然shap.plots.bar()还可以按照需求修改参数绘制不同的条形图。如通过max_display参数进行控制条形图最多显示条形树数。
局部条形图
将一行 SHAP 值传递给条形图函数会创建一个局部特征重要性图其中条形是每个特征的 SHAP 值。其中特征值是否显示是通过参数show_data控制默认 auto 特征值以灰色显示在特征名称的左侧。
shap.plots.bar(shap_values2[1], show_dataTrue)队列条形图
传递解释对象的字典将为解释对象表示的每个群组创建一个多条形图其中包含一个条形类型。下面我们使用它来分别绘制男性和女性特征重要性的全局摘要。
sex [Women if shap_values2[i,Sex].data 0 else Men for i in range(shap_values2.shape[0])]
shap.plots.bar(shap_values2.cohorts(sex).abs.mean(0))队列条形图还有另一个比较有意思的绘图他使用 Explanation 对象的自动群组功能来使用决策树创建一个群组。调用Explanation.cohorts(N)将创建 N 个队列使用 sklearn DecisionTreeRegressor 最佳地分离实例的 SHAP 值。
例如将其用于成人人口普查数据则看到低资本收益与高资本收益之间的明显区别。括号中的数字是每个队列中的实例数。
v shap_values2.cohorts(2).abs.mean(0)
shap.plots.bar(v)使用特征聚类
很多时候数据集中的特征存在冗余。这意味着模型可以使用任一特征并仍然获得相同的准确性。可以通过计算特征之间的相关矩阵或使用聚类方法来找到这些特征。
在 SHAP 中通过模型损失比较来测量特征冗余。即使用shap.utils.hclust方法并通过训练 XGBoost 模型来预测每对输入特征的结果来构建特征的层次聚类。与从无监督方法如相关性中获得的特征冗余相比。对典型的结构化数据集进行特征冗余度量会更加准确。
计算聚类并传递给条形图就可以同时可视化特征冗余结构和特征重要性。默认只会显示距离 0.5 的聚类部分。假设聚类中的距离大致在 0 和 1 之间缩放其中 0 距离表示特征完全冗余1 表示它们完全独立。
在下图中我们看到只有关系和婚姻状况有超过 50% 的冗余因此它们是条形图中分组的唯一特征
clustering shap.utils.hclust(X, y)
shap.plots.bar(shap_values2, clusteringclustering,clustering_cutoff0.5)Summary Plot
上面使用Summary Plot方法并设置参数plot_typebar绘制典型的特征重要性条形图而他默认绘制Summary_plot图他是结合了特征重要性和特征效果取代了条形图。
Summary_plot 为每一个样本绘制其每个特征的Shapley value它说明哪些特征最重要以及它们对数据集的影响范围。
y 轴上的位置由特征确定x 轴上的位置由每 Shapley value 确定。颜色表示特征值红色高蓝色低颜色使我们能够匹配特征值的变化如何影响风险的变化。重叠点在 y 轴方向抖动因此我们可以了解每个特征的 Shapley value分布并且这些特征是根据它们的重要性排序的。
shap.summary_plot(shap_values, X)Beeswarm plot
同条形图一样shap也提供了另一个接口plots.beeswarm蜂群图。
蜂群图旨在显示数据集中的TOP特征如何影响模型输出的信息密集摘要。给定解释的每个实例由每个特征流上的一个点表示。点的 x 位置由该特征的 SHAP 值 ( shap_values.value[instance,feature]) 确定并且点沿每个特征行“堆积”以显示密度。颜色用于显示特征的原始值 ( shap_values.data[instance,feature])。
在下图中我们可以看到平均而言年龄是最重要的特征与年轻蓝色人相比收入超过 5 万美元的可能性较小。 同样可以使用max_display参数调整最多显示行数。
默认使用每个特征的 SHAP 值的平均绝对值shap_values.abs.mean(0) 对特征排序。然而这个顺序更强调广泛的平均影响而不是罕见但高强度的影响。如果我们想找到对个人影响较大的特征可以按最大绝对值排序。
shap.plots.beeswarm(shap_values2, ordershap_values.abs.max(0))另外在绘图之前就对shap_values取绝对值得到与条形图类似的图形但比条形图具有更丰富的平行线因为条形图只是绘制蜂群图中点的平均值。
# 蜂群图
shap.plots.beeswarm(shap_values2.abs, colorshap_red)
# 条形图
shap.plots.bar(shap_values2.abs.mean(0))还可以自定义颜色默认使用shap.plots.colors.red_blue颜色图。
import matplotlib.pyplot as plt
shap.plots.beeswarm(shap_values, colorplt.get_cmap(cool))在Summary_plot图中首先看到了特征值与对预测的影响之间关系的迹象但是要查看这种关系的确切形式还必须查看 SHAP Dependence Plot图。
Dependence Plot
SHAP Partial dependence plot (PDP or PD plot) 依赖图显示了一个或两个特征对机器学习模型的预测结果的边际效应它可以显示目标和特征之间的关系是线性的、单调的还是更复杂的。他们在许多样本中绘制了一个特征的值与该特征的 SHAP 值。
PDP 是一种全局方法该方法考虑所有实例并给出关于特征与预测结果的全局关系。PDP 的一个假设是第一个特征与第二个特征不相关。如果违反此假设则 PDP 计算的平均值将包括极不可能甚至不可能的数据点。
为了显示哪个特征可能会驱动这些交互效应可以通过第二个特征为我们的年龄依赖性散点图着色默认第二个特征是自动选择的尝试挑选出与 Age 交互作用最强的特征列。也可以通过参数interaction_index设置交互项。如果另一个特征与正在绘制的特征之间存在交互作用它将显示为不同的垂直着色模式。
shap.dependence_plot(Age, shap_values, X, display_featuresX_display,interaction_indexCapital Gain)Dependence plot 是一个散点图显示单个特征对整个数据集的影响。
每个点都是来自数据集的单个预测行。x 轴是数据集中的实际值。来自 X 矩阵存储在 中shap_values.data。y 轴是该特征的 SHAP 值存储在 中shap_values.values它表示该特征值对该预测的模型输出的改变程度。
Scatter plot
同样散点图绘图依赖图这与上面 dependence_plot 绘制基本一样。
在显示方面有些许不同plots scatter 图底部的浅灰色区域是显示数据值分布的直方图。
在交互颜色方面。dependence_plot 默认而散点图则需要将整个 Explanation 对象传递给 color 参数。
另外有时候在输入模型之前是字符串为输入到模型需要将其设置为分类编码此时绘图是并不能很直观地显示内容。此时可以将.display_data Explanation 对象的属性设置为我们希望在图中显示的原始数据类型。
shap_values2.display_data X_display.values
shap.plots.scatter(shap_values2[:, Age], colorshap_values2[:,Workclass])使用全局特征重要性排序
在只想绘制最重要的特征却不知道其特征名或索引此时可以使用 Explanation 对象的点链功能来计算全局特征重要性的度量按该度量降序排序然后挑选出顶部特征。
# 平均绝对均值的特征
ind_mean shap_values2.abs.mean(0).argsort[-1]
# 平均绝对值最大的特征
ind_max shap_values.abs.max(0).argsort[-1]
# 95% 绝对值对特征进行排序
ind_perc shap_values.abs.percentile(95, 0).argsort[-1]
shap.plots.scatter(shap_values2[:, ind_mean])另外还可以自定义图形属性详情可参加官方文档。
模型预测的可解释性
Force plot
Local 可解释性提供了预测的细节侧重于解释单个预测是如何生成的。它可以帮助决策者信任模型并且解释各个特征是如何影响模型单次的决策。
单个预测的解释可视化
SHAP force plot 提供了单一模型预测的可解释性可用于误差分析找到对特定实例预测的解释。
# 如果不想用JS,传入matplotlibTrue
shap.force_plot(explainer.expected_value, shap_values[0,:], X_display.iloc[0,:])尝试分析此图。
模型输出值-5.89基值模型输出与训练数据的平均值explainer.expected_value绘图箭头下方数字是此实例的特征值。如Age39Education-Num13将预测推高的特征用红色表示将预测推低的特征用蓝色表示箭头越长特征对输出的影响越大。通过 x 轴上刻度值可以看到影响的减少或增加量。
多个预测的解释可视化
如果对多个样本进行解释将上述形式旋转90度然后水平并排放置得到力图的变体我们可以看到整个数据集的 explanations
通过上图中上方和左方选项卡可以任意选择单个变量的多个样本对模型输出结果的影响。如下Age前80个样本对模型输出结果f(x)的影响。 Interaction Values
interaction value是将SHAP值推广到更高阶交互的一种方法。树模型实现了快速、精确的两两交互计算这将为每个预测返回一个矩阵其中主要影响在对角线上交互影响在对角线外。这些数值往往揭示了有趣的隐藏关系(交互作用)。
shap_interaction_values explainer.shap_interaction_values(X)
shap.summary_plot(shap_interaction_values, X)Decision plot
SHAP 决策图显示复杂模型如何得出其预测即模型如何做出决策。决策图是 SHAP value 的文字表示使其易于解读。
决策图显示的信息与力图基本相同都可以有效地解释上述模型的预测。而且很容易识别出主要影响的大小和方向。
决策图比力图更清晰和直观尤其是要分析的特征比较多的时候。在力图中当预测变量的数量较多时信息可能看起来非常紧凑。
explainer shap.TreeExplainer(model)
expected_value explainer.expected_value
# 限制20个样本
features X.iloc[range(20)]
# 展示第一条样本
shap_values explainer.shap_values(features)[1]shap.decision_plot(expected_value, shap_values, features_display)决策图中间灰色垂直直线标记了模型的基础值彩色线是预测表示每个特征是否将输出值移动到高于或低于平均预测的值。特征值在预测线旁边以供参考。从图的底部开始预测线显示 SHAP value 如何从基础值累积到图顶部的模型最终分数。
shap_values explainer.shap_values(features)
y_pred (shap_values.sum(1) expected_value) 0
misclassified y_pred ! y[select]
shap.decision_plot(expected_value, shap_values, features_display, linklogit, highlightmisclassified)决策图支持将对 linklogit数几率转换为概率。 使用虚线样式 highlightmisclassified突出显示一个错误分类的观察结果。 通过单独绘制来检查错误分类的观察结果。绘制单个观测值时会显示其相应的特征值。
shap.decision_plot(expected_value, shap_values[misclassified], features_display[misclassified],linklogit, highlight0)错误分类观察的力图如下所示。在这种情况下决策图和力图都可以有效地显示模型如何得出其决策。
shap.force_plot(expected_value, shap_values[misclassified], features_display[misclassified],linklogit, matplotlibTrue)决策图的基本作用
大量特征效果清晰展示。可视化多输出预测。显示交互的累积效果。探索一系列特征值的特征效果。进行异常值检测。确定典型的预测路径。比较和对比几个模型的预测。
如需要具体了解每种作用的方法建议去官网决策图查看每种作用所举的例子。
使用 SHAP 值进行异常值检测
这里只介绍一个异常检测的例子。
X_train, X_test, y_train, y_test train_test_split(X, y, test_size0.2, random_staterandom_state)
d_train lgb.Dataset(X_train, labely_train)
d_test lgb.Dataset(X_test, labely_test)params {max_bin: 512, learning_rate: 0.05,boosting_type: gbdt, objective: binary,metric: binary_logloss, verbose: -1,min_data: 100, random_state: 1boost_from_average: True, num_leaves: 10 }model lgb.train(params, d_train, 10000, valid_sets[d_test], early_stopping_rounds50, verbose_eval1000)
explainer shap.TreeExplainer(model)
expected_value explainer.expected_value[1]features X_test.iloc[range(20)]
features_display X_display.loc[features.index]
shap_values explainer.shap_values(features)[1]y_pred model.predict(X_test)
r shap.decision_plot(expected_value, explainer.shap_values(T)[1], X_test[(y_pred 0.03) (y_pred 0.1)], feature_orderhclust, return_objectsTrue)将决策图叠加在一起有助于根据 SHAP value 定位异常值。在上图中你可以看到一个不同数据集的示例用于使用SHAP决策图进行异常值检测。 Heatmap plot
热图旨在使用监督聚类和热图显示数据集的总体子结构。监督聚类涉及的不是通过数据点的原始特征值而是通过它们的 shap values 对数据点进行聚类。默认使用 shap.utils.hclust_ordering 进行聚类。
绘图时将 SHAP 值矩阵传递给热图绘图函数。得到的图中 x 轴上是实例、y 轴上是模型输入以及色标上是编码的 SHAP 值。默认情况下样本使用 shap.order.hclust 排序它基于层次聚类并根据解释相似性对样本进行排序。
这将因相同原因和具有相同模型输出的样本被分组在一起如下图中对capital gain影响较大的人被分组在一起了。
shap.plots.heatmap(shap_values)在热图矩阵上方是模型的输出灰色虚线是基线(.base_value图右侧的条形图是每个模型输入的全局重要性默认用shap.order.abs.mean整体重要性来度量
更改排序顺序和全局特征重要性值
通过给feature_values参数传递一组值来改变衡量特征整体重要性的方式以及它们的排序顺序。默认情况下feature_valuesshap.Explanation.abs.mean(0)还可以在所有样本中按特征的最大绝对值进行排序。
shap.plots.heatmap(shap_values2, feature_valuesshap_values.abs.max(0))通过给instance_order参数传递一组值控制实例的顺序。默认情况下设置instance_ordershap.Explanation.hclust(0)将具有相似解释的样本分组在一起。还可以按所有特征的 SHAP 值总和排序。
shap.plots.heatmap(shap_values2, instance_ordershap_values.sum(1))Waterfall plot
瀑布图旨在显示单个预测的解释因此将解释对象的单行作为输入。瀑布图从底部的模型输出的预期值开始每一行显示每个特征的是正红色或负蓝色贡献即如何将值从数据集上的模型预期输出值推动到模型预测的输出值。
shap.plots.waterfall(shap_values2[5])这里值得注意拥有 2,174 美元的资本收益的人会比每年赚取超过 5 万美元的人的预测概率明显低很多。这里由于waterfall绘图仅显示了单个样本数据因此我们无法看到资本收益变化的影响。可以使用scatter图来展示资本收益的低值是如何比根本没有资本收益更负面地预测收入。
shap.plots.scatter(shap_values2[:,Capital Gain])参考文章
[1] https://shap.readthedocs.io/en/latest/index.html [2]https://www.bilibili.com/read/cv116