python 计算变量的IV值

在机器学习的二分类问题中,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

   
WOE编码和IV是一种常用的特征工程方法,它们可以用于衡量一个特征与目标变量之间的关联程度和预测能力。下面是Python计算IV和WOE编码的示例代码: ```python import pandas as pd import numpy as np def calc_woe_iv(df, col, target): """ 计算指定特征的WOE编码和IV :param df: 数据集 :param col: 特征列名 :param target: 目标变量列名 :return: WOE编码和IV """ # 计算该特征每个取的数量和占比 freq = pd.DataFrame({'total': df.groupby(col)[target].count(), 'bad': df.groupby(col)[target].sum()}) freq['good'] = freq['total'] - freq['bad'] freq['bad_rate'] = freq['bad'] / freq['bad'].sum() freq['good_rate'] = freq['good'] / freq['good'].sum() # 防止出现除0错误 freq.loc[freq['bad_rate'] == 0, 'bad_rate'] = 0.0001 freq.loc[freq['good_rate'] == 0, 'good_rate'] = 0.0001 # 计算WOE编码 freq['woe'] = np.log(freq['good_rate'] / freq['bad_rate']) # 计算IV freq['iv'] = (freq['good_rate'] - freq['bad_rate']) * freq['woe'] iv = freq['iv'].sum() return freq[['woe', 'iv']].reset_index().rename(columns={col: 'value'}), iv ``` 这个函数的输入参数包括数据集`df`、特征列名`col`和目标变量列名`target`,输出WOE编码和IV。在函数中,我们首先计算了该特征每个取的数量、坏样本数量、好样本数量、坏样本率、好样本率和WOE,然后根据IV的公式计算了每个取对应的IV,并将它们相加得到总的IV。最后,我们将WOE编码和IV合并成一个DataFrame并返回。 需要注意的是,代码中为了避免出现除0错误,我们在计算WOE编码和IV时对分母加上了一个极小0.0001。同时,WOE编码和IV计算方式可以根据具体的业务需求进行调整。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值