kaggle数据集_Kaggle心脏病数据集冠军Kernel的可解释性技巧

Kaggle心脏病数据集冠军Kernel作者Rob Harrand,除了使用常见的python库,numpy、 pandas、 matplotlib、sklearn外还使用了 seaborn、eli5、shap、pdpbox、Ipython。

下面是原网址:

https://www.kaggle.com/tentotheminus9/what-causes-heart-disease-explaining-the-model

一. 下面简单介绍一下这几个工具:

seaborn : 统计数据可视化

Seaborn是基于matplotlib的Python数据可视化库。它提供了用于绘制引人入胜且内容丰富的统计图形的高级界面。

http://seaborn.pydata.org/

5515a6f3d99b4805b6fc68de0a1c5c3c.png

ELI5 :帮助调试机器学习分类器并解释它们的预测

允许解释scikit-learn 线性分类器和回归变量的权重和预测,将决策树打印为文本或SVG,显示特征重要性,并解释决策树和基于树的集成体的预测。eli5 可用于文本处理,可以相应地突出显示文本数据。支持 Pipeline 和 FeatureUnion。它还可以通过撤消散列来调试包含HashingVectorizer 的 scikit学习管道。

8f53c72e9b8f10b92ed7090d2f744cef.png

https://pypi.org/project/eli5/

SHAP:Python的可解释机器学习库

(Pycharm 不能正常显示力线图)

参考: https://zhuanlan.zhihu.com/p/83412330

SHAP是Python开发的一个"模型解释"包,可以解释任何机器学习模型的输出。其名称来源于SHapley Additive exPlanation,在合作博弈论的启发下SHAP构建一个加性的解释模型,所有的特征都视为“贡献者”。对于每个预测样本,模型都产生一个预测值,SHAP value就是该样本中每个特征所分配到的数值。

假设第i个样本为xi,第i个样本的第j个特征为xi_j,模型对该样本的预测值为yi,整个模型的基线(通常是所有样本的目标变量的均值)为y_base,那么SHAP value服从以下等式:

83b0f38a9c96526971fa71efcd2708bf.png

其中f(x_ij)为x_ij的SHAP值。直观上看,f(xi,1)就是第i个样本中第1个特征对最终预测值yi的贡献值,当f(xi,1)>0,说明该特征提升了预测值,也正向作用;反之,说明该特征使得预测值降低,有反作用。

传统的feature importance只告诉哪个特征重要,但我们并不清楚该特征是怎样影响预测结果的。SHAP value最大的优势是SHAP能对于反映出每一个样本中的特征的影响力,而且还表现出影响的正负性。

f1bb0c6e8a1369fe6341dc657b284d96.png

PDPbox : 可视化某些功能对任何监督学习算法的模型预测的影响。

(现在支持所有scikit-learn算法)

参考:https://swift.ctolib.com/SauceCat-PDPbox.html

1. 辅助功能用于可视化目标分布和预测分布。

2. 处理一键编码功能的正确方法。

3. 解决功能之间复杂的相互依赖性的解决方案。

4. 支持多分类器。

5. 支持两个变量交互的局部依赖图。

b5f38bee1d68cea00ee8dffe08117071.png

Ipython : ipython是一个python的交互式shell

支持变量自动补全,自动缩进,支持bash shell命令,内置了许多很有用的功能和函数。学习ipython将会让我们以一种更高的效率来使用python。同时它也是利用Python进行科学计算和交互可视化的一个最佳的平台。

二. 看下Kaggle心脏病数据集冠军Kernel的作者Rob Harrand是怎么使用这些工具来解释模型的:

先看看他引入的库的哪部分:

0de055084be958a4efc540dcc1c02406.png


sho

为了方便看出数据中每一列所代表的意思:重新命名一下列的名称:

469b5b873a5c6d39f1575bdba2dc7891.png

0507806a0a7ea414edffa2c2040b2680.png

数据中出现多选项的列(如chest_pain_type,可取0, 1,2,3,4 (Value 1: 典型心绞痛, Value 2: 非典型心绞痛, Value 3: 无心绞痛, Value 4: 无症状的 ))时,将这样的列先解耦,生成多个列,这些列里取值只能是0或1

135f7e5594f9871676893c0c4863967b.png

6a0303253af9d4c31a337ead1e3a5e73.png

b17702e6a69f085ac216ce20002de7d7.png

339461e7056e9d61279e11ffbd0e2647.png

作者使用了随机森林模型来预测样本:

8005a4b98413cad12124758a1cfced97.png

上面说了一堆都是为了下面的做铺垫,重点来了:

随机森林可视化:

92d8e3c4c67931f5f96d4cc15c4497a0.png

#code from https://towardsdatascience.com/how-to-visualize-a-decision-tree-from-a-random-forest-in-python-using-scikit-learn-38ad2d75f21c

export_graphviz(estimator, out_file='tree.dot',

feature_names = feature_names,

class_names = y_train_str,

rounded = True, proportion = True,

label='root',

precision = 2, filled = True)

from subprocess import call

call(['dot', '-Tpng', 'tree.dot', '-o', 'tree.png', '-Gdpi=600'])

from IPython.display import Image

Image(filename = 'tree.png')

5e441b1238fa13731ccde4de35228a7e.png

计算混淆矩阵:

y_predict = model.predict(X_test)

y_pred_quant = model.predict_proba(X_test)[:, 1]

y_pred_bin = model.predict(X_test)

confusion_matrix = confusion_matrix(y_test, y_pred_bin)

confusion_matrix

60b19f545fafedf92504dbe787dfc28d.png

ROC:

total=sum(sum(confusion_matrix))

sensitivity = confusion_matrix[0,0]/(confusion_matrix[0,0]+confusion_matrix[1,0])

print('Sensitivity : ', sensitivity )

specificity = confusion_matrix[1,1]/(confusion_matrix[1,1]+confusion_matrix[0,1])

print('Specificity : ', specificity)

fpr, tpr, thresholds = roc_curve(y_test, y_pred_quant)

fig, ax = plt.subplots()

ax.plot(fpr, tpr)

ax.plot([0, 1], [0, 1], transform=ax.transAxes, ls="--", c=".3")

plt.xlim([0.0, 1.0])

plt.ylim([0.0, 1.0])

plt.rcParams['font.size'] = 12

plt.title('ROC curve for diabetes classifier')

plt.xlabel('False Positive Rate (1 - Specificity)')

plt.ylabel('True Positive Rate (Sensitivity)')

plt.grid(True)

71f48f618e59044f9dcc2d995b9a7c76.png

AUC:

auc(fpr, tpr)

b41734f21e9706c1e6b812265e0951be.png

可以看出用随机森林模型预测这个心脏病数据集准确率还是相当高的。但它是否符合现实中人们的预判呢?常识告诉我们:肥胖,体内胆固醇高,高血压 可能得心脏病的概率更大,那么再来看下这个模型是不是也得出这样的结论呢?

使用ELI5的PermutationImportance来测试各列对应的变量对结果的影响大小,也就是对结果的重要性:

bd9bdea7176fdb31f68e9b25b2f914b1.png

e72c8b7d23849d5b5476cb3cbb16691e.png

所以,就排列而言,似乎最重要的因素是“可逆转的缺陷”导致的thalessemia。“达到最大心率”类型的重要性是有意义的,因为这是病人在检查时的直接的、主观的状态(相对于,比如说,年龄,这是一个更普遍的因素)。

让我们使用部分相关图来仔细查看主要vessles的数量(在这里了解更多信息)。这些图在一个值范围内改变一行中的单个变量,并查看它对结果的影响。它对几行这样做,并绘制平均效果。让我们来看看'num_major_vessel '变量,它位于排列重要性列表的顶部。

使用 PDPbox 来画出指定变量的值变化对结果的影响:

12d26e280822b54120ba0c9950194ec3.png

0112a9f4969ee0c2cd1e4a67bf54161d.png

005db1df15fc7c785611bccca7d2ef6a.png

99f28f5993c7ca12174cf2b3738b26d6.png

PDPbox画出两个变量同时变化对结果的影响:

25a98ff37f4cf7b464fc54215628c720.png

b200bfd27e8b3683e6642b707338d1d1.png

3d3c1ab26eea870afd20a13127f11371.png

使用SHAP来画出:每个变量对结果的平均影响图:

a08b5e527ffe09dc6199c397d5d9c8aa.png

5763f8970012594b9a583e8ce278c4e8.png

或者是这样的图:

edb28e949d80a3b3d20b6eeb1f67f65d.png

f55ede0a94d7aeb7fe2dff206a548cec.png

Shap 画某个样本的力线图:(那些特征的值起到正作用,哪些起到副作用)

下面查看其中两个样本(两个人)的各个属性对结果的影响。哪些属性让他看起来更可能得心脏病,哪些属性又让他看起来不可能得心脏病。

ca935de0cf422751b6eab26a2043189e.png

bd2bdd3ce34b5ec20e87b6b6669267dc.png

fb5230800f1737f6d4ec2b0b90e8ec36.png

abb93c0f82dca713a31bca8c2bee6dc2.png

力线的另一种画法:

1a6fe9f6a4e49643c9c09b366b2feb5a.png

4de5713650b5f5218e462a361acc712e.png
  • 0
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值