WOE&IV编码&分箱

IV

  • 概念:
    • IV的全称是Information Value,中文意思是信息价值,或者信息量。
  • 作用:
    • 构建分类模型时,对特征进行筛选,挑选特征时 用来衡量自变量(特征)的预测能力
    • ”用IV去衡量变量预测能力“的理解
      • 我们假设在一个分类问题中,目标变量的类别有两类:Y1,Y2。对于一个待预测的样本A,要判断A属于Y1还是Y2,我们是需要一定的信息,假设这个信息总量是I,而这些所需要的信息,就蕴含在所有的待预测样本的特征C1,C2,C3,……,Cn中,那么,对于其中的一个特征Ci来说,其蕴含的信息越多,那么它对于判断A属于Y1还是Y2的贡献就越大,Ci的信息价值就越大,Ci的IV就越大,它就越应该进入到入模变量列表中。
  • 公式:


    3.vi.png

    计算整个特征的IV值 :
    4.png

WOE

  • WOE的全称是“Weight of Evidence”,即证据权重。WOE是对原始特征的一种编码形式。要对一个特征进行WOE编码,需要首先把这个变量进行分组处理(也叫离散化、分箱等等,说的都是一个意思)。
  • WOE的计算公式:


    1.woe.png

    公式含义:
    pyi是这个组中正例样本占整个样本中正例样本的比例
    pni是这个组中负例样本占整个样本中负例样本的比例
    (#yi是这个组中正例样本的数量 )
    (#ni是这个组中负例样本的数量 )
    (#yT是整个样本中所有正例样本的数量)
    (#nT是整个样本中所有负例样本的数量 )
    公式表示: “当前分组中正例样本占所有样本中所有正例样本的比例”和“当前分组中负例样本占所有样本中所有负例样本比例”的差异

  • 公式变换:
    2.png

    公式表示:当前这个组中响应的客户和未响应客户的比值,和所有样本中这个比值的差异
    WOE越大,这种差异越大,这个分组里的样本响应的可能性就越大(这组数据分到正例的概率越大),WOE越小,差异越小,这个分组里的样本响应的可能性就越小
    分母是固定的,如果分子中的yi越大,则WOE返回的数值越大

用实例介绍IV的计算和使用

  • 例子
    • 假设现在某个公司举行一个活动,在举行这个活动之前,先在小范围的客户中进行了一次试点,收集了一些用户对这次活动的一些响应,然后希望通过这些数据,去构造一个模型,预测如果举行这次的活动,是否能够得到很好的响应或者得到客户的响应概率之类。
    • 假设我们已经从公司客户列表中随机抽取了100000个客户进行了营销活动测试,收集了这些客户的响应结果,作为我们的建模数据集,其中响应的客户有10000个。另外假设我们也已经提取到了这些客户的一些变量,作为我们模型的候选变量集,这些变量包括以下这些:
      • 最近一个月是否有购买;
      • 最近一次购买金额;
      • 最近一笔购买的商品类别;
      • 是否是公司VIP客户;
    • 假设,我们已经对这些变量进行了离散化,统计的结果如下面几张表所示
      (1) 最近一个月是否有过购买:


      5. 最近一个月是否有过购买:.png

      (2) 最近一次购买金额:


      6.最近一次购买金额:.png

      (3) 最近一笔购买的商品类别:
      7.最近一笔购买的商品类别:.png

      (4) 是否是公司VIP客户:
      8.是否是公司VIP客户.png

计算WOE和IV

  • 以其中的一个变量“最近一次购买金额”变量为例:


    6.最近一次购买金额:.png
  • 计算WOE


    9.计算WOE.png

    10.png

    WOE的基本特点:

  • 当前分组中,响应的比例越大,WOE值越大;
  • 当前分组WOE的正负,由当前分组响应和未响应的比例,与样本整体响应和未响应的比例的大小关系决定,当前分组的比例小于样本整体比例时(分子小于分母),WOE为负,当前分组的比例大于整体比例时(分子大于分母),WOE为正,当前分组的比例和整体比例相等时(分子等于分母),WOE为0。
    WOE描述了某一特征的当前这个分组,对判断该特征是否会响应(或者说属于哪个类)所起到影响方向和大小,当WOE为正时,特征当前取值对判断个体是否会响应起到的正向的影响,当WOE为负时,起到了负向影响。而WOE值的大小,则是这个影响的大小的体现。
  • 计算IV


    11.计算iv值.png

    IV的特点:

  • 对于特征的一个分组,这个分组的响应和未响应的比例与样本整体响应和未响应的比例(WOE)相差越大,IV值越大,否则,IV值越小;
  • 极端情况下,当前分组的响应和未响应的比例和样本整体的响应和未响应的比例相等时,IV值为0;
  • 计算变量总IV值:


    12.iv和.png

IV值的比较和变量预测能力的排序

其他三个特征的iv和woe计算同上
最近一次购买金额的IV为0.49270645
最近一个月是否有过购买的IV为0.250224725
最近一笔购买的商品类别的IV为0.615275563
是否为公司VIP客户的IV为1.56550367
IV排序: 是否是公司VIP客户 > 最近一笔购买的商品类别 > 最近一次购买金额 > 最近一个月是否有过购买
“是否是公司VIP客户”是预测能力最高的特征,“最近一个月是否有过购买”是预测能力最低的特征

关于IV和WOE的进一步思考:为什么用IV而不是直接用WOE

从计算公式来看,对于特征的一个分组,IV是WOE乘以这个分组响应占比和未响应占比的差。而一个特征的IV等于各分组IV的和。WOE构造出一个和,只需要把特征各个分组的WOE和取绝对值再相加,(取绝对值是因为WOE可正可负,如果不取绝对值,则会把特征的区分度通过正负抵消的方式抵消掉):

13.woe.png

用IV而不是直接用WOE的原因:

  • 指标值不应该是负数 ,iv中乘以 (py-pn) 这个系数,保证了特征每个分组的结果都是非负数
  • 主要原因: 乘以(py-pn)后,体现出了特征当前分组中个体的数量占整体个体数量的比例


    14.png

    15.png

    从上表可以看到,特征取1时,响应比达到90%,对应的WOE很高,但对应的IV却很低,原因就在于IV在WOE的前面乘以了一个系数(py-pn),而这个系数很好的考虑了这个分组中样本占整体样本的比例,比例越低,这个分组对特征整体预测能力的贡献越低。相反,如果直接用WOE的绝对值加和,会得到一个很高的指标,这是不合理的

分箱

  • 数据分箱(也称为离散分箱或分段)是一种数据预处理技术,用于减少次要观察误差的影响,是一种将多个连续值分组为较少数量的“分箱”的方法。简单说就是将连续型特征进行离散化
    关于人年龄的数据


    对连续性特征进行离散化
    17.png

  • 注意:

    • 分箱的数据不一定必须是数字,它们可以是任何类型的值,如“狗”,“猫”,“仓鼠”等。 分箱也用于图像处理,通过将相邻像素组合成单个像素,它可用于减少数据量。
  • 分箱的作用&意义

    • 离散特征的增加和减少都很容易,易于模型的快速迭代,提升计算速度
    • 特征离散化后,模型会更稳定,比如如果对用户年龄离散化,20-30作为一个区间,不会因为一个用户年龄长了一岁就变成一个完全不同的人。
    • 特征离散化以后,起到了简化了模型的作用,可以适当降低了模型过拟合的风险。
  • pandas实现数据的分箱:pd.cut()

    import numpy as np
    import pandas as pd
    from pandas import Series, DataFrame
    
    score_list = np.linspace(0,20,num=11)
    print(score_list) #[ 0.  2.  4.  6.  8. 10. 12. 14. 16. 18. 20.]
    
    #设置分箱:方式1
    bins=[0,4,8,16,20] #指定分箱数据的范围
    score_cat=pd.cut(score_list,bins=bins)
    score_cat.value_counts()
    #输出结果:
    (0, 4]      2
    (4, 8]      2
    (8, 16]     4
    (16, 20]    2
     
    #设置分箱:方式2
    #指定分箱数据的个数
    pd.cut(score_list,bins=4).value_counts()
    #输出结果:
    (-0.02, 5.0]    3
    (5.0, 10.0]     3
    (10.0, 15.0]    2
    (15.0, 20.0]    3
    
    #设置分箱:方式3
    #label参数的作用:设置分箱的每一个范围的标识
    #指定分箱数据的个数
    pd.cut(score_list,bins=4,labels=['a','b','c','d']).value_counts()
    #输出结果:
    a    3
    b    3
    c    2
    d    3
     
    pd.cut(score_list,bins=4,labels=range(4)).value_counts()
    #输出结果:
    0    3
    1    3
    2    2
    3    3
    
  • pd.qcut() ·qcut根据值的频率来选择箱子的均匀间隔,即每个箱子含有的数的数量相同

factors=np.random.randn(9)
pd.qcut(factors,3).value_counts() #计算每个分组中含有数的数量
#输出结果:
(-1.1289999999999998, -0.124]    3
(-0.124, 0.393]                  3
(0.393, 1.496]                   3
  • cut与qcut的区别:
    1.cut:按连续数据的大小分到各个桶里,每个桶里样本量可能不同,但每个桶相当于等长的区间
    2.qcut:每个桶的样本数量一定(等频分箱)
    特征是连续性倾向于使用qcut,离散型倾向于使用cut

  • 注意:分箱后就可以求解出IV和WOE的值了。如果想对连续性特征进行离散化,需要对分箱后的每组(箱)数据进行woe或者iv编码,然后才能放进模型训练。

import sklearn.datasets as ds
bc = ds.load_breast_cancer() #加载乳腺癌数据
feature = bc.data #特征
target = bc.target  #标签
feature.shape #(569, 30)
#查看第1列数据范围,判定其为连续性数据
feature[:,1].min(),feature[:,1].max()
#(9.71, 39.28)

#对其进行分箱处理,将其离散化
fea_bins = pd.cut(feature[:,1],bins=5)
fea_bins.value_counts()
#输出结果:
(9.68, 15.624]      113
(15.624, 21.538]    299
(21.538, 27.452]    129
(27.452, 33.366]     25
(33.366, 39.28]       3

#对分箱后的特征列进行woe编码 crosstab()交叉表
#每组中正例和反例样本的数量
gi = pd.crosstab(fea_bins,target)
gi
#输出结果:
 col_0  0   1
row_0       
(9.68, 15.624]  8   105
(15.624, 21.538]    101 198
(21.538, 27.452]    90  39
(27.452, 33.366]    11  14
(33.366, 39.28] 2   1
 
#样本数据中正例样本和反例样本的数量
gb = pd.Series(data=target).value_counts()
gb
#输出结果:
1    357
0    212

#规定0类别为正例样本,1为反例样本
gbi = (gi[0]/gi[1]) / (gb[0]/gb[1])
gbi
#输出结果:
row_0
(9.68, 15.624]      0.128302
(15.624, 21.538]    0.858991
(21.538, 27.452]    3.886067
(27.452, 33.366]    1.323113
(33.366, 39.28]     3.367925

#WOE的计算
woe = np.log(gbi)
woe
#输出结果:
(9.68, 15.624]     -2.053369
(15.624, 21.538]   -0.151997
(21.538, 27.452]    1.357398
(27.452, 33.366]    0.279987
(33.366, 39.28]     1.214297

#计算IV
iv=((gi[0]/gb[0])-(gi[1]/gb[1]))*woe
iv
#输出结果:
row_0
(9.68, 15.624]      0.526447
(15.624, 21.538]    0.011887
(21.538, 27.452]    0.427967
(27.452, 33.366]    0.003548
(33.366, 39.28]     0.008054

f_iv=iv.sum()
f_iv #0.977902238264725

#进行映射操作
dict = iv.to_dict()
dict
#输出结果:
{Interval(9.68, 15.624, closed='right'): 0.5264465134478181,
 Interval(15.624, 21.538, closed='right'): 0.011887192576072856,
 Interval(21.538, 27.452, closed='right'): 0.4279665436826456,
 Interval(27.452, 33.366, closed='right'): 0.0035477507112311505,
 Interval(33.366, 39.28, closed='right'): 0.008054237846957362}
 
ivs_bins = fea_bins.map(dict)
ivs_bins.tolist()

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,482评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,377评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,762评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,273评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,289评论 5 373
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,046评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,351评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,988评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,476评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,948评论 2 324
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,064评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,712评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,261评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,264评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,486评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,511评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,802评论 2 345