机器学习很大一个问题是可解释性较差,虽然在RandomForest、LightGBM等算法中,均有feature_importance可以展现模型最重要的N个特征,但是对于单个样本来说情况可能并不与整体模型一致,所以就需要使用SHAP等算法将每个样本中不同特征的贡献度用数值展现出来。
对于SHAP算法的原理和其它同类算法可以看这2篇博客:
https://blog.csdn.net/weixin_41968505/article/details/119885046
https://zhuanlan.zhihu.com/p/100458526
本文主要使用SHAP完成每个样本不同特征的贡献度计算,并写了个简单的脚本把前N个重要特征提取出来。

准备工作:

首先还是需要传统的数据清洗、建模等,记得安装和导入shap库

pip install shap

注:我安装的shap版本是0.40.0,所有如果你的版本和我不一致,可能会导致后续代码略有差别。

所有样本的shap计算:

我这边的model是lightgbm,也就是树模型,所以使用的是shap.TreeExplainer

import shap
explainer = shap.TreeExplainer(model) #这里的model在准备工作中已经完成建模,模型名称就是model
shap_values = explainer.shap_values(test_data[predictors]) #这里的test_data是我的测试集,predictors是X_train的变量

在这里插入图片描述
在我的版本里,shap_values是一个list,里面有2个array,第一个array是负向结果的SHAP值,而第二个array是正向结果的SHAP值,需要根据不同的业务场景选择不同的array
在本次测试中,我做的model是宽带离网预测模型,所以我选择的是第一个array。
注:在做shap计算前,建议仅把有正样本(比如精准营销的话,就是把潜在客户)放入其中,因为shap的计算真的非常慢,我10000个样本跑了大概7分钟。

1)、可以输入下列代码显示和feature_importance类似的图片,只是同步会告诉我们不同特征的shap值取值范围是多少。

shap.summary_plot(shap_values[0], test_data[predictors], plot_type="bar")

在这里插入图片描述
2)、这是另一种可视化

shap.summary_plot(shap_values[0], test_data[predictors])

获得单个样本的TOP N 特征值和对应的SHAP值

总算到正文了,我写成了一个函数,参数主要包括:
old_list:shap_value中某个array的单个元素(类型是list),这里我选择的是array[0]中的590元素
features: 与old_list的列数相同,主要用于输出的特征能让人看得懂
top_num:展示前N个最重要的特征
min_value: 限制了shap值的最小值

def get_topN_reason(old_list,features=predictors[:22],top_num=3, min_value=0.0):
    #输出shap值最高的N个标签
    feature_importance_dict = {}
    for i, f in zip(old_list, features):
        feature_importance_dict[f] = i
    new_dict = dict(sorted(feature_importance_dict.items(), key=lambda e: e[1],reverse=True))
    return_dict = {}
    for k, v in new_dict.items():
        if top_num>0:
            if v>=min_value:
                return_dict[k] = v
                top_num -= 1
            else:
                break
        else:
            break
    return return_dict
print(get_topN_reason(shap_values[0][590]))

注1:可以简单改造后变成输出值为dataframe的形式,更进一步则是与原有特征的值结合,因为shap值只能作为排序和筛选,真正要让数据使用者理解,还是要转化业务能够理解的内容,比如“cdma_count(当月移动活跃设备数):2”,“net_play_time(上网时长):1”,“year_pay(是否年付):0”
注2:在模型训练中,很多特征并不都是可解释的,但是在训练过程中会很有用,所以在可解释性和实用性上需要平衡和取舍。

**SHAP是Python开发的一个“模型解释”包,可以解释任何机器学习模型的输出**。其名称来源于**SHapley Additive exPlanation**,在合作博弈论的启发下SHAP构建一个加性的解释模型,所有的特征都视为“贡献者”。对于每个预测样本,模型都产生一个预测值,SHAP value就是该样本中每个特征所分配到的数值。 可解释机器学习在这几年慢慢成为了机器学习重要研究方向。作为数据科学家需要防止模型存在偏见,且帮助决策者理解如何正确地使用我们的模型。越是严苛的场景,越需要模型提供证明它们是如何运作且避免错误的证据关于模型解释性,除了线性模型和决策树这种天生就有很好解释性的模型意外,sklean中有很多模型都有importance这一接口,可以查看特征的重要性。其实这已经含沙射影地体现了模型解释性的理念。只不过传统的importance的计算方法其实有很多争议,且并不总是一致。有兴趣可以之后阅读相关文章 permutati 画三分类SHAP图出错 今天干了一件很蠢的事情,还耽误了很多时间,特此记录一下 我将数据标准化之后训练模型,然后将未标准化的数据作为输入计算了SHAP值,得出的结果显然不对。类似于下图这种 但是如果画图时将X_test输入作为参数,那么横坐标就对应的是标准化之后的值,所以我们可以先对X_test未经标准化时候制作一个copy版本X_test1,然后作为画图时候参数输入就可以正确画出SHAP图的横坐标了,也可以得到我们想要的信息。另外三分类shap values得到一个3维数据,有时候使用起来需要切片,比如 shap是可视化机器学习模型的一种方法,在使用shap之,需要训练好特定的模型,然后导入shap import shap shap.initjs()#这是为了能够输出shap的图像 接着,将模型输入shap解释器中,创建一个explainer对象,利用它计算每个观察对象的SHAP值,每个特征将对应一个SHAP值。 explainer = shap.Explainer(model) shap_values = explainer(Xtrain) # 为第一个观察对 Python里对于shape()的理解 (1)shape()含义 在笔者debug深度学习相关代码的时候,很容易出现shape()这样形式的东西,用来告知输出数据的形式,由于shape()里出现的数字数量不同,还经常有shape(?,64,512)这样的数据存在,因此上网查了一些信息,作出比较通俗易懂的解释: import numpy as np a = np.array([[[1,2,3],[4,5,6]]]) print(a.s shap.TreeExplainer(model)报错 'utf-8’不能编码问题 shap.TreeExplainer(model)运行报错: ‘utf-8’ codec can’t decode byte 0xff in position 341: invalid start byte shap可以用于xgboost的模型可视化解释,很好用。 报错原因:xgb版本问题,1.1.0及以上会出现,老版本不会。 解决方法一 重装xgboost至1.0.0版本 解决方法二 1 首先,xgb建模中有 model Shap值衡量特征的边际贡献度,是当模型解释的最佳方法之一,对于模型进行可视化的全局解释、局部解释,可以在一定程度上满足业务对于模型解释性的要求。 本文通过实例对shap原理进行讲解,帮助初学者、从业人员快速理解,并以代码进行全流程实战和结果展示、帮助大家上手使用。............ 数据导入后对数据进行数据的分析和整理工作。好的数据清洗可以让未来的工作简单有效,对于未来的模型而言数据本身的质量决定了结果的上限,模型的选择和调优是不断趋近于这个上线的手段。 对于数据清洗而言首先应该对数据进行了解,了解数据的来源,通过来源可以对数据进行清洗和整理工作, 例如性别等字段可以将文字转化成向量等形式,同时可以对数据的空值等进行统计,根据数据的真实情况决定是否可以进行填补操作。 有的字段例如身高等字段需要通过分桶的技术将其进行类似降维处理。 时间字段根据... shape函数是numpy.core.fromnumeric中的函数,它的功能是读取矩阵的长度,比如shape[0]就是读取矩阵第一维度的长度。 shape的输入参数可以是一个整数(表示维度),也可以是一个矩阵。以下例子可能会好理解一些: (1)参数是一个数时,返回空: (2)参数是一维矩阵: (3)参数是二维矩阵: (4)直接用.shape可以快速读取矩阵的形状 PCA算法: 结论:PCA算法对矩阵A经过降维后得到的向量为矩阵ATA最大的k个特征值对应的k个特征向量构成的矩阵。 理解:PCA算法经过降维后保留的为最主要的k个信息,因此投影方向应为含信息量最大的方向,可以理解为投影后,在投影轴上分布最分散,即方差最大。因此证明该定理应当先找到投影轴,然后将数据投影到该轴上,最后计算方差使之最大。 证明:假设对m*n阶矩阵A做PCA变换,投影轴为向量u. 对的系列的学习(大佬的完整代码在2022年人工智能依旧飞速发展,从传统机器学习模型到如今以“炼丹”为主的深度神经网络,代表着模型拟合度与模型各自的发展趋势。至此,深刻体会并成功解释NN为何能取得更优的效果成为各行各业的新目标,而可解释性机器学习便应运而生。