申请评分卡中的数据预处理和特征衍生
模型处理的一般流程:
构建信用风险模型的特征
获取数据
链接:https://pan.baidu.com/s/1CsY11ArZ6YK3o1icghWj2w
提取码:znbs
数据预处理
1.基本处理:
原始数据带有一定的格式,需要转换成正确的格式
- 利率方面的处理办法:带%的百分比,需要转化为浮点数
- 工作年限“<1 year”转化为0,“>10 year”的转化为11
- 日期方面:如Nov-10直接转化为标准日期,python能识别的日期格式
- 文本类数据的处理方式
例如:After amassing credit card debt through several years of college, I now have spending under control and a stable job。。。上述文本信息:字段中的desc就是客户申请期间的申请原因等信息,这里处理采用最简单的办法,如果里面有信息,则为1,无信息则为0,即编码处理,其他例如采用NLP的办法,做其他处理,暂时不做,因为涉及分词等等,处理其他麻烦,不是写这次博客的主要目的。
主题提取(NPL自然语言处理)
优点:提取准确、详细的信息,对风险的评估非常有效,
缺点:NPL的模型较为复杂,且需要足够多的的训练样本。
编码处理:
优点:简单
缺点:丢失信息较高
2.缺失值处理:
缺失值的种类情况:
- 完全随机缺失
- 随机缺失
- 完全非随机缺失
处理的办法一般为以下几种:
- 补缺
- 作为一种状态,例如,空的为0,非空为1,处理起来简单,如果缺失值不多,效果不错
- 删除本行的记录,这种处理办法最简单,尤其在数据量较大的情况下,删除部分数据,对整体基本无影响。
3.数据特征构建-特征衍生
因为在原有的特征上面,也就是直接特征方面的信息含量不足以很好的建立申请评分卡模型,所以一般都会去构建新的特征,进行特征的衍生。那么经常接触到的特征衍生办法如下:
- 计数:过去1年内申请贷款的总次数
- 求和:过去1年内的在线上的消费金额
- 比例:贷款申请额度和年收入的占比
- 时间差:第一次开户距离今天的时间长度
- 波动率:过去3年内每份工作的时间的标准差,或者标准差/期望值
以上构建的办法均基于经验的构建,不包含了因子分析等办法
特征的分箱
分箱简单的解释就是:分箱就是为了做到同组之间的差异尽可能的小,不同组之间的差异尽可能的大。
1. 特征分箱的目的:
- 将连续变量离散化
- 将多状态的离散变量合并成少状态
2.分箱的重要性:
- 稳定性:避免了特征中的无意义的波动对评分带来的不好的影响
- 健壮性:避免了模型受到极端值的影响
举个例子:例如未进行分箱之前,样本数据里面没有一个高二年级的学生,那么假定做好分箱之后,高一到高三均属于高中,因此出现一个高二年级的学生后,就会被划入高中这个“箱”,模型的稳定性就得到了加强;在健壮性方面,例如我的收入是1000,在申请贷款的时候给予的评分很低,假定就20分,经过我的不断努力,跳槽7-8次之后,薪水涨到1500左右,这个时候,还是属于低收入的困难人群,那么给予的评分还是20分左右,这样模型的健壮性就得到了体现,模型不需要根据一些小的变化就进行调整。
3.分箱的好处:
- 可以把缺失值作为一个独立的箱带入到模型中去
- 将所有的变量变换到相似的尺度上(例如:一个变量是年龄,一个变量是月收入,不做分箱,2者之间的变化差距太大)
4.分箱的缺点:
- 计算量比较大,处理数据过程较为繁琐。
- 分箱后,数据不能直接被模型使用,需要编码
- 编码之后容易导致信息的丢失。
5.分箱的方法:
有监督分箱与无监督方法的区别就在于是否有目标变量,有目标变量就是有监督,无目标变量就是无监督。
-
无监督分箱方法(一般不推荐,好不好用,得看人品,一般比卡方和决策树的效果要差点)
-
等距划分: 从最小值到最大值之间,均分为 N 等份, 这样, 如果 A,B 为最小最大值, 则每个区间的长度为 W=(B−A)/N , 则区间边界值为A+W,A+2W,….A+(N−1)W 。这里只考虑边界,每个等份里面的实例数量可能不等。
-
等频分箱: 区间的边界值要经过选择,使得每个区间包含大致相等的实例数量。比如说 N=10 ,每个区间应该包含大约10%的实例。
-
比较: 比如,等宽区间划分,划分为5区间,最高工资为50000,则所有工资低于10000的人都被划分到同一区间。等频区间可能正好相反,所有工资高于50000的人都会被划分到50000这一区间中。这两种算法都忽略了实例所属的类型,落在正确区间里的偶然性很大。
对特征进行分箱后,需要对分箱后的每组(箱)进行woe编码,然后才能放进模型训练。
-
-
有监督分箱方法
-
Best-KS分箱(非常类似决策树的分箱,决策树分箱的标准是基尼指数,这里就只考虑KS值): 让分箱后组别的分布的差异最大化。
-
步骤:对于连续变量
1.排序,x = { x 1 x_1 x1, x 2 x_2 x2, x 3 x_3 x3,… x k x_k xk}
2.计算每一点的KS值
3.选取最大的KS值对应的特征值 x m x_m xm,将x分为{ x i ≤ x m x_i≤x_m xi≤xm}与{ x i > x m x_i>x_m xi>xm}两部分,对于每一部分,循环2、3步骤,直到满足终止条件 -
终止条件,继续回滚到上一步:
1.下一步分箱,最小的箱的占比低于设定的阈值(0.05)
2.下一步分箱后,有一箱数据比较单纯,比如对应的y的类别全部为0或者1
3.下一步分箱后,bad rate不单调 -
对于离散很高的分类变量分箱方法
1.编码(类别变量个数很多,先编码,再分箱。)
2.依据连续变量的方式进行分箱
分箱以后变量必须单调,具体的例子如下图:
-
假定变量被分成了6个箱,假定X轴为年龄,Y轴为坏样本率,这样就可以解释了,年龄越大,坏客户的比例约多。如果分箱之后不单调,那么模型在这个变量上的可解释性就成问题了。所以在分箱期间要注意变量的单调性。
-
-
卡方分箱:
这里copy一段官方解释(比较长):自底向上的(即基于合并的)数据离散化方法。它依赖于卡方检验:具有最小卡方值的相邻区间合并在一起,直到满足确定的停止准则。通俗的讲,即让组内成员相似性强,让组间的差异大。
基本思想: 对于精确的离散化,相对类频率在一个区间内应当完全一致。因此,如果两个相邻的区间具有非常类似的类分布,则这两个区间可以合并;否则,它们应当保持分开。而低卡方值表明它们具有相似的类分布。- 忘记上面,直接实践一下,步骤如下:
- 预先我们设定一个卡方的阈值
- 初始化:根据离散化的属性对实例进行排序,每个实例属于一个区间
- 开始合并,具体分2步:
(1). 计算每一对相邻区间的卡方数值
(2)卡方值最小的一对区间直接合并
A i j A_{ij} Aij:第i区间第j类的实例的数量
E i j E_{ij} Eij: A i j A_{ij} Aij的期望频率, = ( N i ∗ C j ) / N =(N_i*C_j)/N =(Ni∗Cj)/N,N是总样本, N i N_i Ni是第i组的样本数, C j C_j Cj是第j类样本在全体中的比例
目前一般分箱5个或者6个,置信度在0.95左右,区间为10-15之间。主要是因为分箱太多,操作起来太麻烦,对模型的提高也不大,分箱5个一般就不错。
卡方分箱的终止条件很简单,基本就是2条:- 默认分到多少箱,如果已经分到了这个数值了,那就第2步
- 检查一下单调性,满足就完成分箱了,如果不满足,相邻的箱就合并,直到单调了为止,因为最后合并到2个箱的时候,是一定单调的。
-
和Best-KS分箱相比,ChiMerge卡方分箱可以应用于multi-Class(多分类),而Best-KS分箱多应用于二分类
补充:分箱之前要切分,通常50-100个切分点,看数据量的大小,最最最重要的,千万不要用等距划分,因为比如收入、年龄这些字段成偏态分步,数据没有平均分布,要用等频划分。
类别变量,类别较少,就不用在分箱了,如果有那个类别是全部为坏样本,需要和最小的不是坏样本的合并一下,因为不合并等会WOE不能计算了。
最后补充:在评分卡模型中,能不用热编码就不要用热编码,因为热编码膨胀了数据量,在选择变量是不是进入模型当中去,也是存在问题了,例如逐步回归就不好搞,业务方面的解释性也差,没直接的业务逻辑关系。总之,能不用就不用,要是没变量了,还是可以考虑用一下。
WOE编码
WOE(weight of evidence,证据权重)
WOE编码官方解释:一种有监督的编码方式,将预测类别(目标变量)的集中度的属性作为编码的数值
优点:
- 将特征的值规范到相近的尺度上。(经验上讲,WOE的绝对值波动范围在0.1~3之间,超过2的可能性就已经很小了)
- 具有业务含义
缺点:
- 需要分箱后每箱都同时有好坏样本(预测违约和不违约可是使用WOE编码,如果去预测中度违约、重度违约、轻度违约等等情况,这个时候WOE编码就不行了)
WOE计算公式:
WOE编码的意义:
- 符号与好样本的比例有关;
- 当好样本为分子,坏样本为分母的时候,可以要求回归模型的系数为负。
具体的WOE编码这里就不找材料了,CSDN博客上,有很多写的很好的,这里引用一篇博客在这里,请猛击WOE编码。
这里简单引用一下其他人成熟的比较正式说法,WOE公式如下:
W O E i = l n ( p y 1 p y 0 ) = l n ( B i / B T G i / G T ) WOE_i=ln({p_{y_1}\over p_{y_0}})=ln({B_i/B_T\over G_i/G_T}) WOEi=ln(py0py1)=ln(Gi/GTBi/BT)
例如,以年龄作为一个变量,由于年龄是连续型自变量,需要对其进行离散化处理,假设离散化分为5组(如何分箱,上面已经介绍,后面将继续介绍),#bad和#good表示在这五组中违约用户和正常用户的数量分布,最后一列是woe值的计算,通过后面变化之后的公式可以看出,woe反映的是在自变量每个分组下违约用户对正常用户占比和总体中违约用户对正常用户占比之间的差异;从而可以直观的认为woe蕴含了自变量取值对于目标变量(违约概率)的影响。再加上woe计算形式与logistic回归中目标变量的logistic转换(logist_p=ln(p/1-p))如此相似,因而可以将自变量woe值替代原先的自变量值;具体的计算情况如下:
Age | bad | good | WOE |
---|---|---|---|
0-10 | 50 | 200 | =ln((50/100)/(200/1000))=ln((50/200)/(100/1000)) |
10-18 | 20 | 200 | =ln((20/100)/(200/1000))=ln((20/200)/(100/1000)) |
18-35 | 5 |