在风控建模中IV(信息价值)和WOE(证据权重)分别是变量筛选和变量转换中不可缺少的部分。

  很多文章已经讨论过这两个变量,本文在吸收前人优秀成果的基础上,希望用通俗易懂的语言让大家快速理解这两个变量。并用简单的例子让大家明白在实际中如何运用这两个变量,最后给出建模过程中实际需要用到的Python代码。

1. IV运用背景

  在信贷中,都希望借钱给有意愿且有能力还钱的客户,这样借出去的钱才会有收益(利息),并且不会形成坏账(欠钱不还给公司造成损失)。如何找到这样的客户,把这些客户和会逾期的客户区分开来?

  很多银行和公司,基础的模型都是逻辑回归,通过逻辑回归建模把正常客户(好客户)和逾期客户(坏客户)区分开来。而可以用逻辑回归区分好坏客户的前提假设是 “历史样本和未来样本服从同一总体分布” ,逻辑回归模型通过从过去的数据中学习样本的分布特征,从而可以对未来的数据进行处理,判别出未来客户逾期的可能性,从而决定公司是放款还是拒绝。

  那哪些变量可以进入逻辑回归模型,帮助模型更好的区分正常客户和逾期客户?让公司放款金额更多地进入能还钱的人手里,按期还本付息。尽可能少地给到会逾期不还钱的人手里,产生坏账?本文所讲的IV就可以帮助我们挑选变量,决定哪些变量可以进入到模型,哪些变量最好不要进入模型。其它挑选变量的方法如:GBDT、随机森林、相关系数、逐步回归等会在后续文章中详细说明。对于IV的预测能力,一般的会有以下建议:

  IV值可不可能小于0?为什么IV值过大时要考虑把该变量做成前端条件分成两部分去做数据处理或建立模型?这些在后文中将会解答。

  注1: 对于不同的单位,申请借款客户的处理结果可能不一样。比如有些银行拒绝的客户(银行认为相对通过贷款申请的客户,该客户的逾期率要高),而该客户在信贷公司申请贷款,可能结果又会通过放贷。有些在银行和信贷公司都拒绝的客户,在p2p平台有可能会通过放贷。其实最终放贷结果跟公司的客户群体、数据信息是否全面、资金面松紧、领导人决策有很大的关系。下文所讲的好样本(好客户)和坏样本(坏客户)并不是讲这个客户是个好人或坏人。只是在不同的公司,根据自己已有信息判断决定的放款客户和拒绝客户。

  注2: 在信贷中,模型分类标签y的定义可以有多种,一种是历史逾期20天以上的定义为1(坏样本),逾期20天以内的定义为0(好样本)。一种是历史逾期超过15天以上的定义为1(坏样本), 逾期7天以内的定义为0(好样本)。在信贷中,一般逾期不超过X天(一般不同公司按照自己的实际情况取值)的客户不会定义为坏样本, 因为有些客户是忘记还款了, 只要提醒就会及时还款,或者暂时因为某种原因没能还款,过几天就会还款,不是恶意欠款。本文模型分类标签采用第一种。

2. WOE和IV的公式
2.1 WOE

  WOE可以写成两种形式,分别对应了两种不同的解释

  第一种:
    
  WOEi = ln(第i个分箱的坏样本数/总坏样本数)-ln(第i个分箱的好样本数/总好样本数)

  此时可以理解为:对于第i个分箱,该分箱里的坏人在总坏人中的占比和的该分箱中的好人在总好人中占比的差异性,或者说坏样本分布和好样本分布之间的差异性。

  我们来看一种极端的情况,看看WOE的值会是多少。此时可以理解为:对于第i个分箱,该分箱里的坏人在总坏人中的占比和的该分箱中的好人在总好人中占比的差异性,或者说坏样本分布和好样本分布之间的差异性。我们来看一种极端的情况,看看WOE的值会是多少。

表 1 - 极端例子1(用第一种方法算WOE)

  从表1可知,如果该分箱中坏人在总坏人中的占比和的该分箱中的好人在总好人中占比相同,WOEi为0。或者说坏样本分布和好样本分布之间完全相同,那么所有的WOEi都为0.想一想这有什么启发?

  第二种:
      
  WOEi = ln(第i个分箱的坏样本数/第i个分箱的好样本数)-ln(总坏样本数/总好样本数)

  此时可以理解为:每个分箱的坏好比和总体坏好比之间的差异。

表 2 - 极端例子1(用第二种方法算WOE)

  从表2可知,如果每个分箱中的坏好比和总体坏好比相同(无差异),则WOEi为0,且两种形式的公式计算结果相同。

2.2 IV

   
   

  从IV的计算公式可以看出,IV可以看成WOE的加权和。之前提到一个问题:IV值可不可能小于0?接下来我们证明一下IVi的值为什么恒大于等于0,而IV是IVi求和,从而IV值恒大于等于0.

  
  
  
  从而证明了IV值恒大于0。
  下面我们来看一个极端的例子,通过极端的例子来探求一下为什么IV大于过大时要考虑把该变量做成前端条件分成两部分去做模型或数据处理。

表 3 - 极端例子2(算IV)

  从表3知,该组别中坏样本占比和好样本占比的差异性越大,该组中WOEi的绝对值越大。而坏样本占比和好样本占比的差异大又可以理解为(坏样本更可能在这组时,好样本在这组的概率较小;或者好样本更可能在这组时,坏样本在这组的概率较小)。

  具体看下组别1,在所有客户中,有50%的正常客户,1.3%的逾期客户落在该组,坏样本占比和好样本占比的差值为48.7%。在该组中逾期客户占比0.0999%(5/5005),正常客户占比99.9%(5000/5005),该组的WOEi为-3.69,IVi为1.8。可以理解为历史上落在该组的客户99.9%是正常客户,0.0999%是逾期客户,由同样本分布推测,未来落在该组的客户也有99.9%是正常客户,0.0999%是逾期客户。

  再来想一想为什么IV值过大时要考虑把该变量做成前端条件分成两部分去做模型或数据处理。我们可以针对组别1的条件划成两种情况,在组别1中的客户重点找到0.0999%的逾期客户,绝大部分是好客户,此时可以通过黑名单、灰名单、简单规则的方式直接对这一组别的数据进行过滤管理,不用再单独建立一个模型,针对不在组别1中的数据另外进行分析。

2.3 两个数据分布的实例

  从上文的分析可知,当坏样本和好样本在该变量的分布差异越大,该变量的IV值越大。下面两个例子是真实建模过程中用到的两个变量,其中红色部分代表坏样本的分布情况,绿色部分代表好样本的分布情况。

图1 图2

  从图1和图2可以看出,图1坏样本和好样本的分布相差不大,图2的好样本分布偏左边,坏样本的分布偏右边。且图2变量的IV值大于图1变量的IV值,从单个变量的信息价值来看,图2的变量比图1的变量更应该选入模型。

3. 用Python计算WOE和IV

  接下来用一个实例说明如何在python中计算变量的WOE和IV

3.1 加载数据

  由于篇幅原因,不在文中放具体数据,如需要,请到公众号中回复“用python计算iv”

import pandas as pd
import numpy as np
df = pd.read_csv("data.csv")
3.2 变量挑选阶段用等频方法粗略算WOE和IV

  在变量挑选阶段一般会用等频的方式,计算iv。在变量转换成woe的阶段会根据业务逻辑微调变量切割的阈值。

#等频切割变量
def bin_frequency(x,y,n=10): # x为待分箱的变量,y为target变量.n为分箱数量total = y.count()       #1 计算总样本数bad = y.sum()           #2 计算坏样本数good = total-bad        #3 计算好样本数if x.value_counts().shape[0]==2:    #4 如果该变量值是0和1则只分两组d1 = pd.DataFrame({'x':x,'y':y,'bucket':pd.cut(x,2)}) else:d1 = pd.DataFrame({'x':x,'y':y,'bucket':pd.qcut(x,n,duplicates='drop')})  #5 用pd.cut实现等频分箱d2 = d1.groupby('bucket',as_index=True)  #6 按照分箱结果进行分组聚合d3 = pd.DataFrame(d2.x.min(),columns=['min_bin']) d3['min_bin'] = d2.x.min()               #7 箱体的左边界d3['max_bin'] = d2.x.max()               #8 箱体的右边界d3['bad'] = d2.y.sum()                   #9 每个箱体中坏样本的数量d3['total'] = d2.y.count()               #10 每个箱体的总样本数d3['bad_rate'] = d3['bad']/d3['total']   #11 每个箱体中坏样本所占总样本数的比例d3['badattr'] = d3['bad']/bad            #12 每个箱体中坏样本所占坏样本总数的比例d3['goodattr'] = (d3['total'] - d3['bad'])/good    #13 每个箱体中好样本所占好样本总数的比例d3['WOEi'] = np.log(d3['badattr']/d3['goodattr'])  #14 计算每个箱体的woe值IV = ((d3['badattr']-d3['goodattr'])*d3['WOEi']).sum()  #15 计算变量的iv值d3['IVi'] = (d3['badattr']-d3['goodattr'])*d3['WOEi']   #16 计算IVd4 = (d3.sort_values(by='min_bin')).reset_index(drop=True) #17 对箱体从大到小进行排序cut = []cut.append(float('-inf'))for i in d4.min_bin:cut.append(i)cut.append(float('inf'))WOEi = list(d4['WOEi'].round(3))return IV,cut,WOEi,d4

  在上面代码的#后面有对应的解析,如果还有不理解的可以加我微信进行咨询。
计算单个变量的调用语句如下:

IV,cut,WOEi,d4 = bin_frequency(df['1个月内申请人在多个平台申请借款'], df['y'])

我们来看下得到的结果
IV值: 0.39747
左分箱cut:[-inf, 0, 3, 4, 6, inf]
各组别的WOEi:[-0.529, 0.476, 0.614, 1.105]
d4:

计算多个变量的循环调用语句如下:

columns_iv = ['7天内申请人在多个平台申请借款','1个月内申请人在多个平台申请借款','3个月内申请人在多个平台申请借款','7天内关联P2P网贷平台数','1个月内关联P2P网贷平台数','3个月内关联P2P网贷平台数','X3个月内申请人手机号作为第二联系人手机号出现的次数','X3个月内申请人手机号作为前三联系人手机号出现的次数'
]
ivs=[]
for i in columns_iv:print(i)IV,cut,WOEi,d4 = bin_frequency(df[i], df['flag'])print('IV=', IV)ivs.append(IV)print(d4)
3.3 变量转换阶段根据业务逻辑调整切割阈值计算WOE和IV
#自定义切割变量
def bin_cut(x,y,cut):     # x为待分箱的变量,y为target变量.cut为分箱的切割点total = y.count()     # 计算总样本数bad = y.sum()         # 计算坏样本数good = total-bad      # 计算好样本数bucket = cutif x.value_counts().shape[0]==2:d1 = pd.DataFrame({'x':x,'y':y,'bucket':pd.cut(x,2)}) else:d1 = pd.DataFrame({'x':x,'y':y,'bucket':pd.cut(x,cut)})  # 用pd.cut实现分箱d2 = d1.groupby('bucket',as_index=True)             # 按照分箱结果进行分组聚合d3 = pd.DataFrame(d2.x.min(),columns=['min_bin']) d3['min_bin'] = d2.x.min()                          # 箱体的左边界d3['max_bin'] = d2.x.max()                          # 箱体的右边界d3['bad'] = d2.y.sum()                              # 每个箱体中坏样本的数量d3['total'] = d2.y.count()                          # 每个箱体的总样本数d3['bad_rate'] = d3['bad']/d3['total']              # 每个箱体中坏样本所占总样本数的比例d3['badattr'] = d3['bad']/bad                       # 每个箱体中坏样本所占坏样本总数的比例d3['goodattr'] = (d3['total'] - d3['bad'])/good     # 每个箱体中好样本所占好样本总数的比例d3['WOEi'] = np.log(d3['badattr']/d3['goodattr'])   # 计算每个箱体的woe值IV = ((d3['badattr']-d3['goodattr'])*d3['WOEi']).sum()     # 计算变量的iv值d3['IVi'] = (d3['badattr']-d3['goodattr'])*d3['WOEi']d4 = (d3.sort_values(by='min_bin')).reset_index(drop=True) # 对箱体从大到小进行排序cut = []cut.append(float('-inf'))for i in d4.min_bin:cut.append(i)cut.append(float('inf'))WOEi = list(d4['WOEi'].round(3))return IV,cut,WOEi,d4

  在上面代码的#后面有对应的解析,如果还有不理解的可以加我微信进行咨询。
函数的调用语句如下:

IV,cut,WOEi,d4 = bin_cut(df['3个月内关联P2P网贷平台数'], df['y'],[-1,0,1,4,40])

我们来看下得到的结果:
IV值: 0.39184
左分箱cut:[-inf, 0, 1, 2, 5, inf]
各组别的WOEi:[-0.547, 0.386, 0.878, 1.043]
d4:

  想要知道怎么定义切割变量的阈值[-1,0,1,4,40],一方面可以根据业务逻辑(一般3个月关联的P2P网贷平台数越多,说明这个人越缺资金,更有逾期的可能),一方面可以看下等频分割的结果(可以自己尝试下)。

3.4 在原始数据中加上对应转成WOEi后的列

定义的函数如下:

def turn_woe(df):for i in range(d4.shape[0]):if df >= d4['min_bin'][i] and df <= d4['max_bin'][i]:return d4['WOEi'][i]

调用的语句如下:

df['3个月内关联P2P网贷平台数_woe'] = df['3个月内关联P2P网贷平台`数'].apply(turn_woe)

可以用如下语句进行验证:

df['3个月内关联P2P网贷平台数_woe'].value_counts()

  得到的结果应该和d4中的total列保持一致。

  本文是本人进行IV计算后的一些见解,如有不当之处恳请指正。如果想更深入地了解IV和WOE,推荐参考文献中写得很好的两篇文章。

参考文献:
1. https://zhuanlan.zhihu.com/p/80134853
2. https://blog.csdn.net/kingzone_2008/article/details/80449287

你可能感兴趣:
用Python绘制皮卡丘
用Python绘制词云图
逻辑回归三部曲——逻辑回归和sigmod函数的由来
Python画好看的星空图V2版——添加背景图片和音乐
逻辑回归三部曲——逻辑回归项目实战(信贷数据+Python代码实现)
逻辑回归三部曲——逻辑回归(logistics regression)原理-让你彻底读懂逻辑回归


-end- 长按(扫一扫)识别上方二维码学习更多Python知识

风控建模中的IV和WOE相关推荐

  1. 特征编码在风控建模中的应用(上篇)—WOE是否可以提升集成算法效果?

    序言: 在风控模型开流程中,使用的场景分别有A卡.B卡.C卡等模型,常规使用最多的就是逻辑回归算法.使用逻辑回归算法80%会使用的编码方式就是WOE编码,相信做模型的同学对这种编码方式非常熟悉. 做W ...

  2. 风控建模中的样本偏差与拒绝推断

    风控业务背景 幸存者偏差(Survivorship Bias)是一个广泛存在的逻辑谬误.我们在进行统计的时候,可能会忽略样本的随机性和全面性,用局部样本代替了总体样本,对总体的描述出现偏差,从而得出错 ...

  3. 机器学习在信贷风控建模中的优势和挑战

    今天,你AI了没? 关注:决策智能与机器学习,学点AI干货 在国内国外金融风控领域大致分为两个流派,其中一派为具有统计学背景的人,分布在银行.金融消费公司等传统的金融领域,偏好评分卡进行建模.另外一派 ...

  4. 特征工程中的IV和WOE详解

    1.IV的用途 IV的全称是Information Value,中文意思是信息价值,或者信息量. 我们在用逻辑回归.决策树等模型方法构建分类模型时,经常需要对自变量进行筛选.比如我们有200个候选自变 ...

  5. woe分析_特征工程中的IV和WOE详解

    1.IV的用途 IV的全称是Information Value,中文意思是信息价值,或者信息量. 我们在用逻辑回归.决策树等模型方法构建分类模型时,经常需要对自变量进行筛选.比如我们有200个候选自变 ...

  6. 风控ML[16] | 风控建模中怎么做拒绝推断

    00 Index 01 什么是拒绝推断? 02 为什么要做拒绝推断? 03 什么时候做拒绝推断? 04 做拒绝推断都有哪些方法? 05 验证拒绝推断效果的方式 06 总结一下

  7. 如何浅显得理解风控模型中的特征筛选|附实操细节(全)

    今天我们综合了星球同学的一些需求,给大家梳理了这样一篇风控建模中特征筛选,希望对所有的风控人员在模型开发上都有所启发. 本文,我们会跟大家介绍特征选择的内容,包括其中的重点问题跟注意的细节. 因为完整 ...

  8. 手把手系列|风控建模中共线性的影响和处理(上)

    序言: 所谓的多重共线性是指一些自变量之间存在较强的线性关系.这种情况在实际应用中非常普遍,如研究高血压与年龄.吸烟年限.饮白酒年限等因素的关系,这些自变量通常是相关的. 如果当我们发现有多个变量存在 ...

  9. 迁移率 计算方法及用途 风控建模系列 02

    迁移率 计算方法及用途 风控建模系列 02 在上一篇博客中,我们讲解了vintage分析的原理及方法(https://blog.csdn.net/weixin_44239904/article/det ...

最新文章

  1. Go 学习笔记(41)— Go 标准库之 encoding/base64 (编解码)
  2. 从头开始学习Adobe Photoshop CC图像编辑
  3. PHP实进程池,swoole_process实现进程池的方法示例
  4. 全字段排序 VS rowid 排序
  5. python动态显示数据_python中plot实现即时数据动态显示方法
  6. 他是我们内心世界的一员 (见信息时报2011年7月10日)
  7. 以太坊2.0存款合约地址余额已突破50万ETH
  8. Ubuntu 16.04安装 Nmap 6.46.1
  9. CS229学习笔记(3)逻辑回归(Logistic Regression)
  10. 关于作者(《蓝调口琴指南》名作拙译)
  11. 魔兽争霸显示无法登录服务器,魔兽登陆不上去_网络一切正常,但是魔兽世界就是登不上去...
  12. TurboMail邮件系统配置之预防邮件炸弹
  13. echarts柱形图根据数据排序顺序要求更改颜色
  14. 异常:HRESULT: 0x80070057 (E_INVALIDARG) 的处理
  15. 一位五年工作经验架构师的感悟
  16. Nature封面:基因突变才是衰老的罪魁祸首?体细胞突变越快,寿命越短
  17. php伪装请求ip,php搞定ip伪装的两种方式
  18. html5音频文件生成波形图代码,使用wavesurfer.js显示mp3 audio音频的波形图
  19. Webots2021b和ROS2调试笔记21-07-27
  20. Android uevent进程源码分析

热门文章

  1. 数字图像处理 --- 图像的傅里叶变换的频谱特征 二(方向性)
  2. 编程之美----小飞的电梯调度算法
  3. 读兰迪波许《追寻你童年时的梦想》
  4. 域策略怎么分发计算机软件,AD域中如何布置软件自动分发
  5. AD域部署软件自动下发
  6. 诺贝尔奖计算机二级,计算机二级ppt真题:制作介绍诺贝尔奖ppt
  7. 【react面试题】不可错过的react 面试题 「务必收藏」
  8. 生存还是毁灭?新物种爆发时代,企业请回答
  9. 山艺2021年高考成绩查询,2021年山东艺术学院高考录取结果什么时候出来及查询系统入口...
  10. 月薪 2 万到 3 万的测试员一天是怎样度过的?