1.自变量进行筛选
IV的全称是Information Value,中文意思是信息价值,或者信息量。
我们在用逻辑回归、决策树等模型方法构建分类模型时,经常需要对自变量进行筛选。比如我们有200个候选自变量,通常情况下,不会直接把200个变量直接放到模型中去进行拟合训练,而是会用一些方法,从这200个自变量中挑选一些出来,放进模型,形成入模变量列表。那么我们怎么去挑选入模变量呢?
挑选入模变量过程是个比较复杂的过程,需要考虑的因素很多,比如:变量的预测能力,变量之间的相关性,变量的简单性(容易生成和使用),变量的强壮性(不容易被绕过),变量在业务上的可解释性(被挑战时可以解释的通)等等。但是,其中最主要和最直接的衡量标准是变量的预测能力。
“变量的预测能力”这个说法很笼统,很主观,非量化,在筛选变量的时候我们总不能说:“我觉得这个变量预测能力很强,所以他要进入模型”吧?我们需要一些具体的量化指标来衡量每自变量的预测能力,并根据这些量化指标的大小,来确定哪些变量进入模型。IV就是这样一种指标,他可以用来衡量自变量的预测能力。类似的指标还有信息增益、基尼系数等等。
补充说明对数简写
np.log(a) np.log10(a) np.log2(a) : 计算各元素的自然对数、10、2为底的对数
WOE(Weight of Evidence)
WOE的全称是“Weight of Evidence”,即证据权重。
因子数量/好客户总数,必须进行加权处理
文件夹内数据
# -*- coding: utf-8 -*-
"""
Created on Thu Jan 11 10:09:47 2018
@author: Administrator
好客户数据是第一列
坏客户数据是第二列
"""
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
#读取文件
readFileName="frequency_compare.xlsx"
#保存文件
saveFileName="woe_iv.xlsx"
#读取excel
df=pd.read_excel(readFileName)
#如果有多个sheet表格,要用sheet_name参数
#第一列字段名(好客户属性)
column1Name_good=list(df.columns)[0]
#第二列字段名(坏客户属性)
column2Name_bad=list(df.columns)[1]
#第一列好客户内容和第二列坏客户内容
column_goodCustomers=df[column1Name_good]
column_badCustomers=df[column2Name_bad]
#去掉NAN
num_goodCustomers=column_goodCustomers.dropna()
#统计数量
num_goodCustomers=num_goodCustomers.size
#去掉NAN
num_badCustomers=column_badCustomers.dropna()
#统计数量
num_badCustomers=num_badCustomers.size
#第一列频率分析
fenquency_goodCustomers=column_goodCustomers.value_counts()
#第二列频率分析
fenquency_badCustomers=column_badCustomers.value_counts()
#各个元素占比
ratio_goodCustomers=fenquency_goodCustomers/num_goodCustomers
ratio_badCustomers=fenquency_badCustomers/num_badCustomers
#最终好坏比例
ratio_goodDevideBad=ratio_goodCustomers/ratio_badCustomers
#woe函数,阵列计算
def Woe(ratio_goodDevideBad):
woe=np.log(ratio_goodDevideBad)
return woe
#iv函数,阵列计算
def Iv(woe):
iv=(ratio_goodCustomers-ratio_badCustomers)*woe
return iv
#iv参数评估,参数iv_sum(变量iv总值)
def Iv_estimate(iv_sum):
#评估能力较强
if 0.5>iv_sum>0.3:
print("good informative")
return "A"
#评估能力一般
if 0.3>iv_sum>0.1:
print("medium informative")
return "B"
#评估能力强或可疑
if iv_sum>0.5:
print("good informative or suspicious")
return "C"
#详细参数输出
def Print():
print("iv_sum",iv_sum)
#print("",)
#print("",)
woe=Woe(ratio_goodDevideBad)
iv=Iv(woe)
df_write=pd.DataFrame({"woe":woe,"iv":iv})
#ratio_badDevideGood数据写入到result_compare_badDevideGood.xlsx文件
df_write.to_excel(saveFileName, sheet_name='Sheet1')
#计算iv总和,评估整体变量
iv_sum=sum([i for i in iv if np.isnan(i)!=True])
#iv参数评估,参数iv_sum(变量iv总值)
iv_estimate=Iv_estimate(iv_sum)
Print()
结果:
预测有价值变量准确,但不完整,因为没有进行分箱,造成损失
举例说明
例如按年龄分组,一般进行分箱,我们都喜欢按照少年、青年、中年、老年几大类进行分组,但效果真的不一定好: