金融风控实战—模型可解释之shap
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)负样本可以代表样本空间 (2)数据是足够干净的(样本.特征没有噪声) 过拟合 (1)增多数据 (2)特征筛选 (3)调参 (4)模型融合 模型融合 投票器模型融合 from ...
- 金融风控实战——特征工程上
特征工程 业务建模流程 将业务抽象为分类or回归问题 定义标签,得到y 选取合适的样本,并匹配出全部的信息作为特征来源 特征工程+模型训练+模型评价与调优(相互之间可能会有交互) 输出模型报告 上线与 ...
- 金融风控实战——风控数据挖掘方法(决策树规则挖掘)
风控数据挖掘方法(决策树规则挖掘) import pandas as pd import numpy as np data = pd.read_excel("/Users/zhucan/De ...
- 金融风控实战——基于时间序列进行特征衍生
import numpy as np import pandas as pd import warnings warnings.filterwarnings("ignore") 给 ...
- 金融风控实战——额度模型与风控策略
消费金融风控策略 变量分布的合理性:年龄为例,这期的用户大多集中在20-30之间,下一批用户年龄集中在30-40之间,导致变量分布不一致问题.机器学习模型都是基于独立同分布的假设的,会让模型失效,很多 ...
- 金融风控实战——风控领域涉及到的算法和风控算法工程师需要具备的能力
一些简单的介绍 市面上算法相关的岗位,从大范围上分为两大类 1.研究驱动的算法工程师,这类算法工程师的门槛很高,分布在大型公司的研究院.创新实验室等部门,这类算法工程师主要是以研究新的算法或者是更好的 ...
- [学习笔记]金融风控实战
参考资料: 零基础入门金融风控-贷款违约预测 导包 import pandas as pd import matplotlib.pyplot as plt # 读取数据 train = pd.read ...
- 金融风控实战入门-特征工程
1. 业务建模流程介绍 * 将业务抽象为分类or回归问题 * 定义标签,得到y * 选取合适的样本,并匹配出全部的信息作为特征的来源 * 特征工程 + 模型训练 + 模型评价与调优(相互之间可能会有交 ...
- 金融风控实战-金融风控与评分卡基础
金融风控与评分卡基础-b站视频
最新文章
- spark streaming 接收 kafka 数据java代码WordCount示例
- 43.StrVec类:std::move调用移动构造函数的一个实例
- 提醒ASP.NET的初学者们注意加深以下方面的技术了解
- SAP UI5 Mock server,为什么运行时无法返回 JSON 类型的测试数据?
- 系统架构师学习笔记-数据通信与计算机网络(一)
- SICP:Building Abstractions with Data
- 基于Python+Django的图书馆管理系统
- svn 使用TortoiseSVN server搭建本地SVN服务器
- 按值设置选择选项“已选择”
- 使用 matlab 求解多元非线性方程组
- Wireshark网络抓包
- 什么是互联网产品策划、什么是运营策划(经典收藏)
- matlab鼠标定位图像中像素点的坐标
- 交换机的工作原理及配置
- Java实现 LeetCode 718 最长重复子数组(动态规划)
- 【论文笔记】标准正交基和投影在分布式控制中的应用
- 基于javafx和虹软ArcFace的高校新生人脸录入与识别系统
- 基于51单片机的智能红外遥控防雨晾衣架 雨滴光强检测系统proteus仿真原理图PCB
- 【人工智能】课堂测验集锦
- 深度学习_深度学习基础知识_PReLU
热门文章
- mysql pool not open_安装 MariaDb 时报错:Could not open mysql.plugin table
- 12无法使用otg_ios设备该如何选择U盘,以及U盘日常使用技巧
- Qt中线程的生命期问题
- Qt中应用程序的打包与发布
- java什么叫内部对象,java – 函数对象的内部类中的变量/对象会发生什么?
- python中list[1啥意思_详解Python中list[::-1]的几种用法
- 用什么方式链接oracle数据库,使用cx_Oracle 连接oracle数据库的几种方式
- 定制ListView的界面(使用自定义的列表项布局,一边显示水果图片,一边显示水果文字)以及ListView的点击事件
- 左撇子的人怎么使用计算机,小漫画讲述冷知识,左撇子很苦恼,电脑自动弹窗发明者是谁?...
- MATLAB中代码优化的两种方法