如何衡量变量重要性?

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

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

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

如何衡量变量的预测能力呢,可以采用通用方法:计算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正则化,逐步回归等等,并不能量化变量的重要程度,但能达到选择重要变量的目的。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,524评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,869评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,813评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,210评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,085评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,117评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,533评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,219评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,487评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,582评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,362评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,218评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,589评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,899评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,176评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,503评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,707评论 2 335

推荐阅读更多精彩内容