import time
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
import xgboost
import pandas as pd
import numpy as np
#混淆矩阵计算
from sklearn import metrics
from sklearn.metrics import roc_curve, auc,roc_auc_score
from sklearn.metrics import precision_score
from sklearn.metrics import accuracy_score
from sklearn.metrics import recall_score
from sklearn.metrics import f1_score

readFileName="data_Q5_filter.xlsx"
#读取excel
data=pd.read_excel(readFileName)
X=data.loc[:,"installment":"emp_length"]
y=data["target"]
train_x, test_x, y_train, y_test=train_test_split(X,y,test_size=0.3,random_state=0)model = xgboost.XGBClassifier(eval_metric=['logloss','auc','error'],use_label_encoder=False)
model.fit(train_x,y_train)
#XGBClassifier(base_score=0.5, booster='gbtree', colsample_bylevel=1,
#              colsample_bynode=1, colsample_bytree=1,
#              eval_metric=['logloss', 'auc', 'error'], gamma=0, gpu_id=-1,
#              importance_type='gain', interaction_constraints='',
#              learning_rate=0.300000012, max_delta_step=0, max_depth=6,
#              min_child_weight=1, missing=nan, monotone_constraints='()',
#              n_estimators=100,n_jobs=8,num_parallel_tree=1,random_state=0,
#              reg_alpha=0, reg_lambda=1, scale_pos_weight=1, subsample=1,
#              tree_method='exact', use_label_encoder=False,
#              validate_parameters=1, verbosity=None)

shap.plots.waterfall瀑布图-展示单个用户变量影响

shap.explainer:
This is the primary explainer interface for the SHAP library. It takes any combination of a model and masker and returns a callable subclass object that implements the particular estimation algorithm that was chosen.
这是 SHAP 库的主要解释器接口。它采用模型和掩码的任意组合,并返回一个可调用的子类对象,该对象实现所选的特定估计算法。

import shap
shap.initjs()  # notebook环境下,加载用于可视化的JS代码
explainer1 = shap.Explainer(model)
shap_values1 = explainer1(X)
shap_values1
#.values =
#array([[ 0.12214637,  0.5763162 ,  0.09239966, ...,  0.05956555,
#        -0.08578542,  0.00583912],
#       [-3.3557818 ,  1.981333  ,  0.589741  , ...,  0.00633732,
#        -0.07526105, -0.11162438],
#       [-0.33665466,  1.1700472 ,  0.24532834, ...,  0.04161756,
#        -0.02426036, -0.1627982 ],
#       ...,
#       [-2.7578328 , -0.5021786 , -0.2805183 , ..., -0.04732708,
#         0.02320154, -0.00695255],
#       [-0.68766063, -1.0604968 , -0.34821302, ...,  0.27330098,
#         0.30684933,  0.27966177],
#       [-1.0541837 , -0.6048023 ,  0.13503188, ..., -0.03302696,
#        -0.11473337, -0.08085796]], dtype=float32)
#
#.base_values =
#array([-4.852247, -4.852247, -4.852247, ..., -4.852247, -4.852247,
#       -4.852247], dtype=float32)
#
#.data =
#array([[3.24230e+02, 4.78340e+02, 3.24230e+02, ..., 1.58000e+02,
#        1.00000e+00, 0.00000e+00],
#       [8.49200e+01, 1.13980e+02, 8.49200e+01, ..., 1.40000e+02,
#        2.00000e+00, 1.00000e+01],
#       [2.76490e+02, 2.83370e+02, 2.76490e+02, ..., 4.00000e+00,
#        4.00000e+00, 0.00000e+00],
#       ...,
#       [1.69830e+02, 5.79600e+02, 1.69830e+02, ..., 1.47000e+02,
#        1.60000e+01, 1.00000e+01],
#       [3.27680e+02, 1.19947e+03, 3.27680e+02, ..., 6.10000e+01,
#        2.00000e+00, 1.10000e+01],
#       [3.56080e+02, 1.10657e+03, 3.56080e+02, ..., 1.44000e+02,
#        1.20000e+01, 2.00000e+00]])
shap_values1[0]
#.values =
#array([ 0.12214637,  0.5763162 ,  0.09239966,  0.6356046 , -0.922258  ,
#        0.17202896,  0.7647206 , -0.12842692, -0.24789801, -0.8769324 ,
#       -0.10680736, -0.07461585,  0.05956555, -0.08578542,  0.00583912],
#      dtype=float32)
#
#.base_values =
#-4.852247
#
#.data =
#array([3.2423e+02, 4.7834e+02, 3.2423e+02, 6.3985e+02, 1.0330e-01,
#       6.3985e+02, 1.6151e+02, 2.7500e+02, 6.1500e+00, 2.8000e+05,
#       1.7631e+04, 4.6000e+01, 1.5800e+02, 1.0000e+00, 0.0000e+00])

SHAP瀑布图
可视化第一个预测的解释:

shap.plots.waterfall(shap_values1[0])

#max_display显示y轴展现变量数量,默认参数是10
shap.plots.waterfall(shap_values1[0],max_display=20)

shap公式

基本值(base_value) ,即E[f(x)]是我们传入数据集上模型预测值的均值,可以通过自己计算来验证:
现在我们知道每个特征对第一次预测的贡献。对上图的解释: X轴是log-odds对数值
y轴是各个变量的数值
蓝色条显示某一特定特征在多大程度上降低了预测的值。 红条显示了一个特定的特征在多大程度上增加了预测值。 例如当total_pymt=639.85时,大大增加坏客户概率;当int_rate=0.103时,大大减少坏客户概率
我们应该期望总贡献等于预测与均值预测的差值。我们来验证一下: f(x)-E(f(x))=-3.161+5.599=2.438
0.97+0.81+0.76+0.52-0.37-0.31+0.25-0.16+0.15-0.19=2.4299999999999997
0.97是total_pymt=639.85时的shap值,当shap值>0时,表示该特征提升了预测值,也正向作用;反之,说明该特征使得预测值降低,有反作用。

#第二条记录
shap.plots.waterfall(shap_values1[1])

shap.plots.waterfall(shap_values1[3])


由于瀑布图只显示一个样本值的数据,我们无法看到变量的动态变化带来的影响

我们用散点图scatter来观察变量的动态变化

例如installment分期付款金额,整体趋势是这个值越大,shap value更高,坏客户概率越高

shap.plots.scatter(shap_values1[:,"installment"])

shap.TreeExplainer

Tree SHAP is a fast and exact method to estimate SHAP values for tree models and ensembles of trees, under several different possible assumptions about feature dependence. It depends on fast C++ implementations either inside an externel model package or in the local compiled C extention.Tree SHAP是一种快速而精确的方法,用于估计树模型和树集合的SHAP值,在关于特征依赖性的几种不同的可能假设下。它依赖于快速的C++实现,既可以在外部模型包内,也可以在本地编译的C扩展中实现。Tree SHAP 方法在数学上等效于对特征的所有可能排序的预测差异进行平均,而不仅仅是由它们在树中的位置指定的排序。只有 Tree SHAP 既一致又准确,这并非巧合。

explainer = shap.TreeExplainer(model)
# 最新版本的shap对于LGBMClassifier得到的shap_values为两个数组的列表,即两个分类的结果,这里使用分类1的结果
shap_values = explainer.shap_values(X)
shap_values
#array([[ 0.12214637,  0.5763162 ,  0.09239966, ...,  0.05956555,
#        -0.08578542,  0.00583912],
#       [-3.3557818 ,  1.981333  ,  0.589741  , ...,  0.00633732,
#        -0.07526105, -0.11162438],
#       [-0.33665466,  1.1700472 ,  0.24532834, ...,  0.04161756,
#        -0.02426036, -0.1627982 ],
#       ...,
#       [-2.7578328 , -0.5021786 , -0.2805183 , ..., -0.04732708,
#         0.02320154, -0.00695255],
#       [-0.68766063, -1.0604968 , -0.34821302, ...,  0.27330098,
#         0.30684933,  0.27966177],
#       [-1.0541837 , -0.6048023 ,  0.13503188, ..., -0.03302696,
#        -0.11473337, -0.08085796]], dtype=float32)

force plot是针对单个样本预测的解释,它可以将shap values可视化为force,每个特征值都是一个增加或减少预测的force,预测从基线开始,基线是解释模型的常数,每个归因值是一个箭头,增加(正值)或减少(负值)预测。
红色的为正贡献,蓝色为负贡献,对于第一个样本,由上图可以解释为特征total_pymnt=639.9的正贡献第一,total_pymnt_inv=639.9的正贡献第二,但是int_rate=0.1033的负贡献最大

# 可视化第一个prediction的解释   如果不想用JS,传入matplotlib=True
shap.force_plot(explainer.expected_value, shap_values[0,:], X.iloc[0,:])

explainer.expected_value
#-4.852247
shap.force_plot(explainer.expected_value, shap_values[1,:], X.iloc[1,:])


个图是直接由shap values绘成的,可以比较第一个样本的shap values具体数值:所以就算不绘制force plot,直接获取样本的shap values,就可以知道每个特征值是如何贡献得到模型预测值的。

sample_0_shap = pd.DataFrame(X.iloc[0,:])
sample_0_shap.rename(columns={0: 'feature_value'}, inplace=True)
sample_0_shap['shap_value'] = shap_values[0]
sample_0_shap.sort_values('shap_value', ascending=False)

shap.plots.bar

#绘图feature importance
shap.summary_plot(shap_values, X, plot_type="bar")

汇总:installment分期金额,total_rec_prncp迄今收到金额,int_rate贷款利率为前三最重要变量

其实如果要查看特征值大小与预测影响之间的关系的话,第二种图还是不够清楚,所以这里主要讲第一种图,第一种图其实就是对shap values按照特征维度聚合计算平均绝对值,也就是​,使用该公式去计算shap values,可得到下表:

feature_importance = pd.DataFrame()
feature_importance['feature'] = X.columns
feature_importance['importance'] = np.abs(shap_values).mean(0)
feature_importance.sort_values('importance', ascending=False)

summary_plot

summary plot 为每个样本绘制其每个特征的SHAP值,这可以更好地理解整体模式,并允许发现预测异常值。每一行代表一个特征,横坐标为SHAP值。一个点代表一个样本,颜色表示特征值(红色高,蓝色低)。比如,这张图表明installment分期付款金额值越高,会降提升坏客户概率

shap.summary_plot(shap_values, X)


Interaction Values

interaction value是将SHAP值推广到更高阶交互的一种方法。树模型实现了快速、精确的两两交互计算,这将为每个预测返回一个矩阵,其中主要影响在对角线上,交互影响在对角线外。这些数值往往揭示了有趣的隐藏关系(交互作用)

#当数据量大时,shap_interaction_values函数调用时非常耗时,建议关闭电脑其他应用,加速计算。
shap_interaction_values = explainer.shap_interaction_values(X)
shap.summary_plot(shap_interaction_values, X)

dependence_plot

如果要看特征值大小与预测影响之间的关系使用dependence plot更合适,dependence plot清楚地展示了单个特征是如何影响模型的预测结果的,dependence plot同样有多种使用方式,一种是查看某个特征是如何影响到模型预测结果的,另一种是一个特征是如何和另一个特征交互影响到模型预测结果的。

shap.dependence_plot('installment', shap_values, X, interaction_index=None)


总结:installment分期金额越大,坏客户概率越高
此图和scatter散点图绘制效果一致

shap.dependence_plot('installment', shap_values, X, interaction_index='installment')

shap.dependence_plot('int_rate', shap_values, X, interaction_index=None)

shap.dependence_plot('installment', shap_values, X, interaction_index='int_rate')


汇总:installment分期金额越大,int_rate贷款利率越高,坏客户风险越大;但不绝对

shap.dependence_plot('installment', shap_values, X, interaction_index='total_rec_prncp')


迄今收到的本金total_rec_prncp和installment分期金额交互明显

shap.dependence_plot('installment', shap_values, X, interaction_index='emp_length')


汇总:installment分期金额越大,emp_length对installment分期金额影响不明显,红色蓝色点几乎均匀混杂在一起

金融风控实战—模型可解释之shap相关推荐

  1. 金融风控实战——模型融合

    过采样方法使用条件 (1)负样本可以代表样本空间 (2)数据是足够干净的(样本.特征没有噪声) 过拟合 (1)增多数据 (2)特征筛选 (3)调参 (4)模型融合 模型融合 投票器模型融合 from ...

  2. 金融风控实战——特征工程上

    特征工程 业务建模流程 将业务抽象为分类or回归问题 定义标签,得到y 选取合适的样本,并匹配出全部的信息作为特征来源 特征工程+模型训练+模型评价与调优(相互之间可能会有交互) 输出模型报告 上线与 ...

  3. 金融风控实战——风控数据挖掘方法(决策树规则挖掘)

    风控数据挖掘方法(决策树规则挖掘) import pandas as pd import numpy as np data = pd.read_excel("/Users/zhucan/De ...

  4. 金融风控实战——基于时间序列进行特征衍生

    import numpy as np import pandas as pd import warnings warnings.filterwarnings("ignore") 给 ...

  5. 金融风控实战——额度模型与风控策略

    消费金融风控策略 变量分布的合理性:年龄为例,这期的用户大多集中在20-30之间,下一批用户年龄集中在30-40之间,导致变量分布不一致问题.机器学习模型都是基于独立同分布的假设的,会让模型失效,很多 ...

  6. 金融风控实战——风控领域涉及到的算法和风控算法工程师需要具备的能力

    一些简单的介绍 市面上算法相关的岗位,从大范围上分为两大类 1.研究驱动的算法工程师,这类算法工程师的门槛很高,分布在大型公司的研究院.创新实验室等部门,这类算法工程师主要是以研究新的算法或者是更好的 ...

  7. [学习笔记]金融风控实战

    参考资料: 零基础入门金融风控-贷款违约预测 导包 import pandas as pd import matplotlib.pyplot as plt # 读取数据 train = pd.read ...

  8. 金融风控实战入门-特征工程

    1. 业务建模流程介绍 * 将业务抽象为分类or回归问题 * 定义标签,得到y * 选取合适的样本,并匹配出全部的信息作为特征的来源 * 特征工程 + 模型训练 + 模型评价与调优(相互之间可能会有交 ...

  9. 金融风控实战-金融风控与评分卡基础

    金融风控与评分卡基础-b站视频

最新文章

  1. spark streaming 接收 kafka 数据java代码WordCount示例
  2. 43.StrVec类:std::move调用移动构造函数的一个实例
  3. 提醒ASP.NET的初学者们注意加深以下方面的技术了解
  4. SAP UI5 Mock server,为什么运行时无法返回 JSON 类型的测试数据?
  5. 系统架构师学习笔记-数据通信与计算机网络(一)
  6. SICP:Building Abstractions with Data
  7. 基于Python+Django的图书馆管理系统
  8. svn 使用TortoiseSVN server搭建本地SVN服务器
  9. 按值设置选择选项“已选择”
  10. 使用 matlab 求解多元非线性方程组
  11. Wireshark网络抓包
  12. 什么是互联网产品策划、什么是运营策划(经典收藏)
  13. matlab鼠标定位图像中像素点的坐标
  14. 交换机的工作原理及配置
  15. Java实现 LeetCode 718 最长重复子数组(动态规划)
  16. 【论文笔记】标准正交基和投影在分布式控制中的应用
  17. 基于javafx和虹软ArcFace的高校新生人脸录入与识别系统
  18. 基于51单片机的智能红外遥控防雨晾衣架 雨滴光强检测系统proteus仿真原理图PCB
  19. 【人工智能】课堂测验集锦
  20. 深度学习_深度学习基础知识_PReLU

热门文章

  1. mysql pool not open_安装 MariaDb 时报错:Could not open mysql.plugin table
  2. 12无法使用otg_ios设备该如何选择U盘,以及U盘日常使用技巧
  3. Qt中线程的生命期问题
  4. Qt中应用程序的打包与发布
  5. java什么叫内部对象,java – 函数对象的内部类中的变量/对象会发生什么?
  6. python中list[1啥意思_详解Python中list[::-1]的几种用法
  7. 用什么方式链接oracle数据库,使用cx_Oracle 连接oracle数据库的几种方式
  8. 定制ListView的界面(使用自定义的列表项布局,一边显示水果图片,一边显示水果文字)以及ListView的点击事件
  9. 左撇子的人怎么使用计算机,小漫画讲述冷知识,左撇子很苦恼,电脑自动弹窗发明者是谁?...
  10. MATLAB中代码优化的两种方法