使用IV值和随机森林挑选特征

Contents

一、 背景

IV值(Information Value),中文意思是信息价值,或者信息量。是评分卡模型中的一个常见指标,“用IV去衡量变量预测能力”,在金融风控领域得到了广泛的应用。

二、 IV值特征选择

2.1 IV值的计算

IV值衡量了某个特征对目标的影响程度,其基本思想是根据该特征所命中黑白样本的比率与总黑白样本的比率,来对比和计算其关联程度,计算公式如下:

  • Distribution Good(i)表示i分组命中白样本的占比。
  • Distribution Bad(i)表示i分组命中黑样本的占比。
    因为计算过程中用的是命中黑白样本各自的比例,所以在工程实践中,一定程度上规避了黑白样本数的不同选择所带来的偏差。

2.2 IV值的选择

当我们计算出特征的IV值后,该如何去解释它的预测能力。或者说,当IV值取到多大时,我们才选择这个特征。这里给出一个经验参考表

Information Value Predictive Power
< 0.02 useless for prediction
0.1 to 0.3 Medium predictor
0.3 to 0.5 Strong predictor
>0.5 Suspicious or too good to be true

由表我们可以知道,并不是IV值越大越好,当IV值大于0.5时,我们需要对这个特征打个疑问,因为它过于太好而显得不够真实。通常我们会选择IV值在0.1~0.5这个范围的特征。可能不同场景在取值的细节上会有所不同。

2.3 代码

数据前期处理看用户贷款逾期预测特征工程,这里仅进行IV值计算

import math
import numpy as np
from scipy import stats
from sklearn.utils.multiclass import type_of_target

def woe(X, y, event=1):  
    res_woe = []
    iv_dict = {}
    for feature in X.columns:
        x = X[feature].values
        # 1) 连续特征离散化
        if type_of_target(x) == 'continuous':
            x = discrete(x)
        # 2) 计算该特征的woe和iv
        # woe_dict, iv = woe_single_x(x, y, feature, event)
        woe_dict, iv = woe_single_x(x, y, feature, event)
        iv_dict[feature] = iv
        res_woe.append(woe_dict) 
        
    return iv_dict
        
def discrete(x):
    # 使用5等分离散化特征
    res = np.zeros(x.shape)
    for i in range(5):
        point1 = stats.scoreatpercentile(x, i * 20)
        point2 = stats.scoreatpercentile(x, (i + 1) * 20)
        x1 = x[np.where((x >= point1) & (x <= point2))]
        mask = np.in1d(x, x1)
        res[mask] = i + 1    # 将[i, i+1]块内的值标记成i+1
    return res

def woe_single_x(x, y, feature,event = 1):
    # event代表预测正例的标签
    event_total = sum(y == event)
    non_event_total = y.shape[-1] - event_total
    
    iv = 0
    woe_dict = {}
    for x1 in set(x):    # 遍历各个块
        y1 = y.reindex(np.where(x == x1)[0])
        event_count = sum(y1 == event)
        non_event_count = y1.shape[-1] - event_count
        rate_event = event_count / event_total    
        rate_non_event = non_event_count / non_event_total
        
        if rate_event == 0:
            rate_event = 0.0001
            # woei = -20
        elif rate_non_event == 0:
            rate_non_event = 0.0001
            # woei = 20
        woei = math.log(rate_event / rate_non_event)
        woe_dict[x1] = woei
        iv += (rate_event - rate_non_event) * woei
    return woe_dict, iv
import warnings
warnings.filterwarnings("ignore")

iv_dict = woe(X_train, y_train)
iv = sorted(iv_dict.items(), key = lambda x:x[1],reverse = True)
print(iv)

输出

('historical_trans_amount', 2.5983243450412368),
 ('trans_amount_3_month', 2.439652353680444),
 ('repayment_capability', 2.203399723888678),
 ('pawns_auctions_trusts_consume_last_6_month', 2.183086956624587),
 ('abs', 1.9028793165065503),
 ('first_transaction_day', 1.9011368241454607),
 ('consfin_avg_limit', 1.510372924453647),
 ('consume_mini_time_last_1_month', 1.2355614394358072),
 ('loans_avg_limit', 1.2013678625464077),
 ('max_cumulative_consume_later_1_month', 1.0370901124990453),
 ('historical_trans_day', 0.9234360603045737),
 ('pawns_auctions_trusts_consume_last_1_month', 0.7276843991231458),
 ('consfin_credit_limit', 0.5745304394611106),
 ('avg_price_last_12_month', 0.5714514732916336),
 ('loans_score', 0.5647851192544522),
 ('loans_latest_day', 0.46648966500770134),
 ('apply_score', 0.3972614272798049),
 ...

三、 随机森林(RandomForest)

3.1 随机森林简介

随机森林是以决策树为基础学习器的集成学习算法,不仅在分类表现出较好的性能,而且在回归上也体现出了优异的性能。
image1 随机森林决策过程:

  1. 用有抽样放回的方法(bootstrap)从样本集中选取n个样本作为一个训练集
  2. 用抽样得到的样本集生成一棵决策树。在生成的每一个结点:
    • 随机不重复地选择d个特征
    • 利用这d个特征分别对样本集进行划分,找到最佳的划分特征(可用基尼系数、增益率或者信息增益判别)
  3. 重复步骤1到步骤2共k次,k即为随机森林中决策树的个数。
  4. 用训练得到的随机森林对测试样本进行预测,并用票选法决定预测的结果。

3.2 随机森林进行特征选择

用随机森林进行特征重要性评估的思想,主要是看每个特征在随机森林中的每棵树上做了多大的贡献,然后取平均值,最后比较不同特征之间的贡献大小。
贡献度的衡量指标包括:基尼指数(gini)、袋外数据(OOB)错误率作为评价指标来衡量。
这里仅调用sklearn包进行重要特征筛选,后期可能进行详细说明。
通过sklearn中的随机森林返回特征的重要性:

  1. 训练模型
    from sklearn.ensemble import RandomForestClassifier
    forest = RandomForestClassifier(n_estimators=10000, random_state=0, n_jobs=-1)
    forest.fit(X_train, y_train)
    
  2. 看看重要特征
    importances = forest.feature_importances_
    indices = np.argsort(importances)[::-1]
    feat_labels = dataset.columns[1:]
    for f in range(X_train.shape[1]):
     print("%2d) %-*s %f" % (f + 1, 30, feat_labels[indices[f]], importances[indices[f]]))
    

    输出:
    image2

  3. 筛选重要特征
    筛选出重要性比较高的变量,比如大于0.15的
    threshold = 0.15
    x_selected = X_train[:, importances > threshold]
    x_selected.shape
    

    输出

    (3803, 19)
    

    帮我们挑选出了19个特征 我们使用这19个特征进行模型训练和预测

    [准确率] 训练集: 0.8596 测试集: 0.7781
    [auc值] 训练集: 0.9030 测试集: 0.7757
    

    与之前相比,没有太明显的提高,因此需要进一步调整模型参数。

四、小结

我们可以用挑选后的特征,进行网格搜索和交叉验证,进一步进行模型优化。

References

[1] 二元分类特征的选择:IV值
[2] 数据挖掘模型中的IV和WOE详解
[3] 评分卡模型剖析之一(woe、IV、ROC、信息熵)
[4] python计算IV值
[5] 利用随机森林对特征重要性进行评估
[6] 特征筛选(随机森林)
[7] 使用随机森林做特征选择

Further Reading

[1] Information Value (IV) and Weight of Evidence (WOE) – A Case Study from Banking (Part 4)


转载请注明:yezuolin的博客 » 点击阅读原文