如何衡量变量重要性?

作者: weston_Xiang | 来源:发表于2018-06-02 16:11 被阅读26次

    为了挑出优质变量,我们可能会考虑:

    变量的预测能力
    变量之间的相关性
    变量的简单性(容易生成和使用)
    变量的健壮性(适用于各种情形)
    变量在业务上的可解释性(被挑战时可以解释的通)

    其中,预测能力是最主要的影响因素。

    如何衡量变量的预测能力呢,可以采用通用方法:计算IV、信息增益或基尼系数等等;也可以为特定模型设计特定的计算方法,本文针对线性模型和随机森林模型,解释了变量重要性是如何计算的。

    一、通用计算方法

    Information Value(IV),信息值,可以用来衡量自变量的预测能力。类似的指标还有信息增益、基尼系数等,它们的原理类似。

    计算这类指标时,并不需要考虑具体使用的模型算法是什么。

    IV的原理是什么?如何计算?

    ①首先,只有类别变量才能计算IV,因此,连续变量需要先分箱(分区间)

    ②对于类别变量,需要计算该变量中每一个类别的WOE(weight of evidence)

    计算公式为:


    woe计算

    WOE表示的含义即是"当前分组中响应客户占所有响应客户的比例"和"当前分组中没有响应的客户占所有没有响应客户的比例"的差异。

    ③计算变量中每个类别对应的IV

    计算公式为:


    类别 i 的IV值

    ④计算整个变量的IV
    很简单,加总所有类别的IV值。

    计算公式为:


    变量的IV值

    python实现IV计算

    Python中没有现成的功能模块,本人写了一个函数,有兴趣可以参考一下:

    def woe_iv(data, feature, label):
            '''
            :param data: DataFrame,
                    data files contain feature and label
            :param feature: String
                    a predict variable
            :param label: String
                    the object variable
            :return: information value of given feature
            '''
            data = data[[feature, label]]
            cato_num = data.groupby(feature).count().reset_index()
            default_num = data.groupby(feature).sum().reset_index()
            all_number = data.shape[0]
            default_number = data[label].sum()
            normal_number = all_number - default_number
            iv = 0
            for i in np.arange(cato_num.shape[0]):
                    p_default = default_num[label][i]/default_number
                    p_normal = (cato_num[label][i] - default_num[label][i])/normal_number
                    if p_default == 0 or p_normal == 0:
                            print('woe_{}_{} is not avalible'.format(feature, cato_num[feature][i]))
                    else:
                            locals()['woe_{}'.format(cato_num[feature][i])] = \
                                    np.log(p_normal / p_default)
                            print('woe_{}: {}'.format(cato_num[feature][i],
                                                       locals()['woe_{}'.format(cato_num[feature][i])]))
                            iv = iv + (p_normal - p_default) * locals()['woe_{}'.format(cato_num[feature][i])]
            print('iv of {}: '.format(feature), iv)
            return iv
    

    测试一波~

    import numpy as np
    # 生成data,包括x1,x2,x3三个自变量
    x1 = np.random.randint(-3, 3, (1000))
    x2 = 1.5*np.random.randint(-3, 3, (1000))
    x3 = 0.5*np.random.randint(-3, 3, (1000))
    y = (1 + x1 + x2 + x3 + np.random.randn()) > 0
    X = np.column_stack([x1, x2, x3])
    
    data = pd.DataFrame(X, columns=['x1', 'x2', 'x3'])
    data['y'] = y
    
    woe_iv(data, 'x1', 'y')
    

    woe_iv函数能输出变量的每个类别的woe值,并返回iv值。

    二、在模型中计算变量重要性

    1.线性模型及逻辑回归

    线性模型及逻辑回归中,给定一个变量,衡量它的影响力的最简单的量化方法就是,将变量的系数乘以该变量的标准差。

    import numpy as np    
    from sklearn.linear_model import LogisticRegression
    
    x1 = np.random.randn(100)
    x2 = 4*np.random.randn(100)
    x3 = 0.5*np.random.randn(100)
    y = (3 + x1 + x2 + x3 + 0.2*np.random.randn()) > 0
    X = np.column_stack([x1, x2, x3])
    
    m = LogisticRegression()
    m.fit(X, y)
    
    # 逻辑回归估计的参数都接近1:
    print(m.coef_)
    
    # 以下输出说明了X2有更强的预测能力,符合预期
    print(np.std(X, 0)*m.coef_)
    

    乘以变量标准差是为了消除变量量纲带来的影响。

    另一种更常见的做法是,在建模之前将变量标准化,这种情况下,变量的系数即可以直接作为变量重要性的判断指标。

    2.随机森林

    先简单介绍一下随机森林算法,它是基于决策树的集成算法,以下是构建一个随机森林模型的具体过程:


    随机森林算法步骤:
    ①用有抽样放回的方法(bootstrap)从样本集中选取n个样本作为一个训练集

    ②用抽样得到的样本集生成一棵决策树。在生成的每一个结点: 随机不重复地选择d个特征 利用这d个特征分别对样本集进行划分,找到最佳的划分特征(可用基尼系数、增益率或者信息增益判别)

    ③重复步骤1到步骤2共k次,k即为随机森林中决策树的个数。

    ④用训练得到的随机森林对测试样本进行预测,并用票选法决定预测的结果。

    简单示意图:


    回到正题,讲述计算随机森林变量重要性的两种方法:

    1.Gini指数法

    ①第i棵树中,节点m的Gini指数是:



    其中,K表示m节点中有K个类别,Pmk表示节点m中类别k所占的比例。

    ②节点m分枝前后的Gini指数变化量为:



    其中, 后两项分别表示分枝后两个新节点的Gini指数。

    Gini指数变化量还不能直接使用,考虑到节点的样本数量,需要进行加权处理,权重就是节点的样本数量(n)除以总样本数量(N):


    ③特征X𝑗在节点m的重要性为:


    ④如果特征X𝑗在决策树i中出现的节点在集合M中,那么X𝑗在第i棵树的重要性为:


    ⑤假设RF中共有n棵树,那么:


    ⑥最后,把所有求得的重要性评分做一个归一化处理即可:


    Python中,随机森林模型中变量重要性计算,采用的就是这种方法,有现成的函数可以直接调用。

    2.精度下降法(Mean Decrease in Accuracy)

    ①.对每一颗决策树,选择相应的袋外数据(out of bag,OOB)​计算袋外数据误差,记为errOOB1

    ②.随机对袋外数据OOB所有样本的特征X加入噪声干扰(可以随机改变样本在特征X处的值),再次计算袋外数据误差,记为errOOB2

    ③. ​假设森林中有N棵树,则特征X的重要性=∑(errOOB2-errOOB1)/N。这个数值之所以能够说明特征的重要性是因为,如果加入随机噪声后,袋外数据准确率大幅度下降(即errOOB2上升),说明这个特征对于样本的预测结果有很大影响,进而说明重要程度比较高。

    PS:所谓袋外数据是指,每次建立决策树时,通过重复抽样得到一个数据用于训练​决策树,这时还有大约1/3的数据没有被利用,没有参与决策树的建立。这部分数据可以用于对决策树的性能进行评估,计算模型的预测错误率,称为袋外数据误差。

    三、总结

    1.几乎任何情况下,都可以通过计算IV值来衡量变量重要性(只要可以转化为类别变量),但是在某些情况下,把所有变量都转化为类别变量并不是一件容易的事,而且转化方法的差异也会影响计算结果。

    2.针对特定模型,采用特定的变量重要性算法,在计算效率上显然更高了。但这种方法下得出的结果,是变量在“大环境”下对结果的贡献度,而非单独进行观测(除非事先保证变量的独立性),因此难以排除变量间的相关性影响。

    上文中用线性模型和随机森林模型为例,概括了变量重要性的主要计算方法和原理,其它可以计算变量重要性的还有神经网络模型、决策树、贝叶斯网络模型、判别分析模型、SVM以及最近相邻元素(KNN) 模型等等。

    PS:一些特征选择/缩减方法,如主成分分析、L1正则化,逐步回归等等,并不能量化变量的重要程度,但能达到选择重要变量的目的。

    相关文章

      网友评论

        本文标题:如何衡量变量重要性?

        本文链接:https://www.haomeiwen.com/subject/vtbxsftx.html