在机器学习的二分类问题中,IV值(Information Value)主要用来对输入变量进行编码和预测能力评估。特征变量IV值的大小即表示该变量预测能力的强弱,在面对大量变量的情况下,可计算各个变量的IV值,取IV值大于某个固定值的变量参与到模型中去,这样不仅保留了特征携带的信息量。且提高了模型效率,此外有利于给客户解释和汇报。
2. IV值计算(python 代码如下)
#########单个变量计算IV值
##Xvar:自变量
##Yvar:因变量
def CalcIV_Single(Xvar, Yvar):
N_0 = np.sum(Yvar==0)
N_1 = np.sum(Yvar==1)
N_0_group = np.zeros(np.unique(Xvar).shape)
N_1_group = np.zeros(np.unique(Xvar).shape)
iv = 0
for i in range(len(np.unique(Xvar))):
N_0_group[i] = Yvar[(Xvar == np.unique(Xvar)[i]) & (Yvar == 0)].count()
N_1_group[i] = Yvar[(Xvar == np.unique(Xvar)[i]) & (Yvar == 1)].count()
#iv = np.sum((N_0_group/N_0 - N_1_group/N_1) * np.log((N_0_group/N_0)/(N_1_group/N_1)))
if N_0_group[i] == 0 or N_1_group[i] == 0:
iv = iv + 0
else:
iv =iv + (N_0_group[i]/N_0 - N_1_group[i]/N_1) * np.log((N_0_group[i]/N_0)/(N_1_group[i]/N_1))
return iv
####### 数值型变量打标记
# 返回数字num在向量vec中处于哪个位置
def rangeMark(num,vec):
mark = int()
for i in range(len(vec)-1):
if num >= vec[i] and num <= vec[i+1]:
mark = i
break
return mark
########数值型变量的排序
## Xvar: 要计算的指标,n : 分组的个数
## 返回 Xvar变量分成n个组以后的组序号
def cut_group(Xvar , n):
bins = []
labels = []
for i in range(n+1):
bins.append(np.percentile(Xvar , (1/ n ) * i * 100))
for i in Xvar:
temp = rangeMark(i,bins)
labels.append(temp)
return labels
##计算离散型属性的IV值
## df_data: 要计算的数据框的名称
## var_lst: 变量名称
## Yvar:目标变量
## 返回多个变量的IV值
def CalcIV_DataFrame_char(df_data , var_lst ,Yvar):
iv_res = []
#df_data[Yvar]
for varName in var_lst:
iv = CalcIV_Single(df_data[varName], Yvar)
iv_res.append(iv)
df_iv= pd.DataFrame({"varName" : var_lst, "iv" : iv_res })
df_iv = df_iv.sort_values(by='iv' , ascending = False)
cols = list(df_iv)
cols.insert(0,cols.pop(cols.index('varName')))
df_iv = df_iv.loc[:,cols]
return df_iv
## DataFrame类型的变量;
## var_lst_num : 要计算的数值指标的变量名
## Yvar :目标变量名称
## n: 数值型指标变量切分的份数
## 返回多个数值型变量的IV值
def CalcIV_DataFrame_num(df_data , var_lst_num ,Yvar ,n):
for var_name in var_lst_num:
df_data[var_name] = cut_group(df_data[var_name] , n)
res = CalcIV_DataFrame_char(df_data , var_lst_num ,Yvar)
return res
############测试上述方法################
if __name__ == '__main__':
inputfile = 'D:/PycharmProjects/lessonOnLine/data/HR2.csv'
data = pd.read_csv(inputfile)
## 计算单个变量salary的IV值
res = CalcIV_Single(data['salary'], data['left']) #测试通过
#####测试分组函数
Xvar = data['average_monthly_hours']
n = 10
res_cut = cut_group(Xvar , n)
################数值型变量名
var_lst_num = ['satisfaction_level',
'last_evaluation',
'average_monthly_hours']
################离散型变量名
var_lst_char = ['department',
'salary',
'number_project',
'time_spend_company',
'Work_accident',
'promotion_last_5years']
df_data = data
Yvar = data['left']
n= 10 # 把这些数值变量切分成10个组
####计算多个数值型变量的IV值
df_iv_num = CalcIV_DataFrame_num(df_data , var_lst_num ,Yvar , n)
######计算离散型数据的IV值
df_iv_char = CalcIV_DataFrame_char(df_data , var_lst_char ,Yvar)
```
参考博客:https://www.cnblogs.com/bigdatafengkong/p/9079934.html
https://www.jianshu.com/p/cc4724a373f8