评分卡建模Toad库的使用

  信贷评分卡中常用的两个库有scorecardpy和Toad。其中scorecardpy是由谢士晨博士开发,Toad是由厚本金融风控团队内部孵化产生的标准评分卡库。本文以Toad官方指导教程为例,讲解如何运用Toad库进行傻瓜式的评分卡开发。

Toad基础教程

参考自Toad库中的Basic Tutorial for Toad.

Toad遵循信用风险记分卡模型开发的一般流程:
(1)EDA
(2)特征的选择与WOE分箱的结合
(3)模型选择
(4)模型验证
(5)评分卡转换

数据准备

本文使用的数据是著名的德国信用卡数据集。数据预处理包括:
(1)将target从’good’ / 'bad’替换为0,1;
(2)划分训练集测试集;
(3)增加一列表示训练和测试的特征。训练集将用于建模,而测试集将仅用于验证。

import pandas as pd
import numpy as np
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
import toad

data = pd.read_csv('germancredit.csv')
data.replace({'good':0,'bad':1},inplace=True)

print(data.shape) # 1000 data and 20 features 
data.head()

  划分训练集和测试集:

Xtr,Xts,Ytr,Yts = train_test_split(data.drop('creditability',axis=1),data['creditability'],test_size=0.25,random_state=450)
data_tr = pd.concat([Xtr,Ytr],axis=1)
#增加一列区分训练/测试的特征
data_tr['type'] = 'train'
data_ts = pd.concat([Xts,Yts],axis=1)
data_ts['type'] = 'test'

一、EDA数据处理

  Toad支持常用的特征EDA分析,包括检测缺失值和特征分布。

toad.detector.detect():返回每个特性的EDA报告,包括数据类型、分布、缺失率和惟一值。

toad.detector.detect(data_tr).head(10)

二、特征选择,WOE转换

  Toad可以用来过滤大量的特征,如高缺失率、低iv和高度相关的特征。它还可以使用各种分箱技巧进行分箱和实现WOE转化。

toad.selection.select():用于根据缺失百分比、iv(20箱)和多重共线性(带有VIF和/或自相关)来过滤特征。

  下面以缺失率大于0.5.IV值小于0.05或者相关性大于0.7(保留较高的特征)来进行特征筛选。

selected_data, drop_lst= toad.selection.select(data_tr,target = 'creditability', empty = 0.5, iv = 0.05, corr = 0.7, return_drop=True, exclude=['type'])

selected_test = data_ts[selected_data.columns]

print(selected_data.shape)
drop_lst 

  可以看到,8个特征由于IV值过低被剔除。

toad.quality(dataframe, target):返回每个特征的质量,包括iv、基尼系数和熵。可以帮助我们发现更有用的潜在信息。

quality = toad.quality(data,'creditability')
quality.head(6)

分箱

第一步:分箱

toad.transform.Combiner():可以用来对数值型和类别型变量进行分箱,支持决策树分箱、卡方分箱、最优分箱等。该行代码生成一个Combiner类,这个类有以下方法:
combiner().fit(data, y = ‘target’, method = ‘chi’, min_samples = None, n_bins = None ):分箱,支持卡方、决策树、等频和等宽。
combiner().set_rules(dict):设置箱号。
combiner().transform(data): 将特征的值转化为分箱的箱号。

# 初始化一个combiner类
combiner = toad.transform.Combiner()

# 训练数据并指定分箱方法,其它参数可选
combiner.fit(selected_data,y='creditability',method='chi',min_samples =  0.05,exclude='type')

# 以字典形式保存分箱结果
bins = combiner.export() 

#查看每个特征的分箱结果
print('status.of.existing.checking.account:',bins['status.of.existing.checking.account'])
print('credit.amount:',bins['credit.amount'])
print('duration.in.month:', bins['duration.in.month'])

第二步:WOE分箱可视化

toad.plot.badrate_plot(data,target = ‘target’, x = None, by = None): 画出不同数据集的每一箱的bad_rate图。这里可以是训练集测试集,也可以不同月份的对比。by后面是纵轴。x是需要对比的维度,比如训练集测试集、不同的月份。
toad.plot.proportion_plot(datacol): 画出一个特征每一箱的比例。

# 根据bad_rate图调整分箱

# 比如查看duration.in.month这个变量的分箱情况
adj_bin = {'duration.in.month': [9, 12, 18, 33]}

c2 = toad.transform.Combiner()
c2.set_rules(adj_bin)

data_ = pd.concat([data_tr,data_ts],axis = 0)
temp_data = c2.transform(data_[['duration.in.month','creditability','type']])

from toad.plot import badrate_plot, proportion_plot
badrate_plot(temp_data, target = 'creditability', x = 'type', by = 'duration.in.month') 
proportion_plot(temp_data['duration.in.month'])

  第一张图是训练集和测试集下每一箱对应的坏样本率,第二张图是每一箱的占比情况。可以看到第一张图中的第一箱和第二箱的bad_rate存在倒挂,说明bad_rate不单调,需要进行调整。可以尝试将第一箱和第二箱进行合并。

# 假定将第一箱、第二箱合并
adj_bin = {'duration.in.month': [9, 18,33]}
c2.set_rules(adj_bin)

temp_data = c2.transform(data_[['duration.in.month','creditability','type']])
badrate_plot(temp_data, target = 'creditability', x = 'type', by = 'duration.in.month')

adj_bin = {'duration.in.month': [9, 18,33],'foreign.worker': [['no'], ['yes']]}

  调整之后可以看到分箱的bad_rate大致呈现单调的趋势。

第三步:分箱转化

toad.transform.WOETransformer():对分箱后的数据进行WOE转化
WOETransformer().fit_transform(data, y_true, exclude = None):

#设置分箱号 
combiner.set_rules(adj_bin)

#将特征的值转化为分箱的箱号。
binned_data = combiner.transform(selected_data)

#计算WOE
transer = toad.transform.WOETransformer()

#对WOE的值进行转化,映射到原数据集上。对训练集用fit_transform,测试集用transform.
data_tr_woe = transer.fit_transform(binned_data, binned_data['creditability'], exclude=['creditability','type'])
data_ts_woe = transer.transform(combiner.transform(selected_test))

模型选择

toad.selection.stepwise():可以通过向前、向后、双向选择来进行特征选择,使用AIC/BIC/KS/AUC作为选择标准。

final_data = toad.selection.stepwise(data_tr_woe.drop('type',axis=1),target = 'creditability',direction = 'both', criterion = 'aic')

final_test = data_ts_woe[final_data.columns]
print(final_data.shape)
print(final_data.columns)

  可以看到经过模型选择,15个特征减少为8个特征。

建模

Xtr = final_data.drop('creditability',axis=1)
Ytr = final_data['creditability']
Xts = final_test.drop('creditability',axis=1)
Yts = final_test['creditability']

lr = LogisticRegression()
lr.fit(Xtr, Ytr)

模型评估和验证

  1. 常用的评估指标如KS、F1、AUC
from toad.metrics import KS, F1, AUC

EYtr_proba = lr.predict_proba(Xtr)[:,1]
EYtr = lr.predict(Xtr)

print('Training error')
print('F1:', F1(EYtr_proba,Ytr))
print('KS:', KS(EYtr_proba,Ytr))
print('AUC:', AUC(EYtr_proba,Ytr))

EYts_proba = lr.predict_proba(Xts)[:,1]
EYts = lr.predict(Xts)

print('\nTest error')
print('F1:', F1(EYts_proba,Yts))
print('KS:', KS(EYts_proba,Yts))
print('AUC:', AUC(EYts_proba,Yts))

  1. PSI
    比较训练集和测试集各变量的稳定性。
psi = toad.metrics.PSI(final_data,final_test)
psi.sort_values(0,ascending=False) # Further tune the unstable feature if any 

  1. KS
tr_bucket = toad.metrics.KS_bucket(EYtr_proba,Ytr,bucket=10,method='quantile')
tr_bucket

分数转换

card = toad.scorecard.ScoreCard(combiner = combiner, transer = transer , C = 0.1) 
card.fit(Xtr, Ytr)
card.export(to_frame = True,).head(10)

  可以输出每个变量的得分情况。

A complete tutorial

  以下参考自A complete tutorial,对基础版中未提到的部分进行补充。

  1. 卡方分箱时加上min_samples参数。
      不设置min_samples参数的话,默认分为10箱,分箱结果由于bad_rate不单调而不能直接使用,不过可以手动对分箱进行调整。
combiner = toad.transform.Combiner()
combiner.fit(data_tr2,y='creditability',method='chi',min_samples = 0.05)
combiner.export()
  1. 使用bin_plot()画图对分箱进行调整
      使用bin_plot对样本集分箱进行调整,使用bad_rate验证分箱在测试集或者跨时间验证集上的稳定性。
from toad.plot import bin_plot

transformed = combiner.transform(data_tr2,labels=True)
#传给bin_plot的数据必须是分箱转化之后的
bin_plot(transformed,x='duration.in.month',target='creditability')

  柱形图表示每一箱的占比,折线图表示每一箱的坏样本率。一般折线图要呈现出单调的趋势。
  再看一个对类别型变量分箱进行调整的例子。对类别型变量进行分箱的时候,易出现某个类别只有好样本/坏样本,这样对计算WOE值造成问题,所以需要将只有好/坏样本的箱进行合并。

#分箱合并
c2.set_rules({'purpose': [['domestic appliances','retraining','car (used)'], ['radio/television'], ['furniture/equipment','repairs','business','car (new)'], ['education','others']]})
bin_plot(c2.transform(data_tr2[['purpose','creditability']],labels=True),x='purpose',target='creditability')

总结:Toad库的出现使得评分卡建模越来越傻瓜式,技术是通用的,但是背后的业务理解需要在实践中不断加深理解。评分卡建模的代码基本可以固化成一套,接下来就是根据业务理解去调整模型。总之,任何脱离业务的模型都是空中楼阁,只有带来实际价值才是王道。

Toad库相关的文档:

github主页:
https://github.com/amphibian-dev/toad
文档:
https://toad.readthedocs.io
中文文档:
https://toad.readthedocs.io/en/dev/tutorial_chinese.html
演示:
https://toad.readthedocs.io/en/latest/tutorial.html
whl下载地址:
https://pypi.org/simple/toad/

【作者】:Labryant
【原创公众号】:风控猎人
【简介】:某创业公司策略分析师,积极上进,努力提升。乾坤未定,你我都是黑马。
【转载说明】:转载请说明出处,谢谢合作!~

猜你喜欢

转载自blog.csdn.net/lc434699300/article/details/105232380