700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > 利用随机森林对特征重要性进行评估

利用随机森林对特征重要性进行评估

时间:2021-02-07 15:00:41

相关推荐

利用随机森林对特征重要性进行评估

文章目录

1 前言2 随机森林(RF)简介3 特征重要性评估4 举个例子5 参考文献

1 前言

随机森林是以决策树为基学习器的集成学习算法。随机森林非常简单,易于实现,计算开销也很小,更令人惊奇的是它在分类和回归上表现出了十分惊人的性能,因此,随机森林也被誉为“代表集成学习技术水平的方法”。

本文是对随机森林如何用在特征选择上做一个简单的介绍。

2 随机森林(RF)简介

只要了解决策树的算法,那么随机森林是相当容易理解的。随机森林的算法可以用如下几个步骤概括:

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

下图比较直观地展示了随机森林算法(图片出自文献2):

图1:随机森林算法示意图

没错,就是这个到处都是随机取值的算法,在分类和回归上有着极佳的效果,是不是觉得强的没法解释~

然而本文的重点不是这个,而是接下来的特征重要性评估。

3 特征重要性评估

现实情况下,一个数据集中往往有成百上前个特征,如何在其中选择比结果影响最大的那几个特征,以此来缩减建立模型时的特征数是我们比较关心的问题。这样的方法其实很多,比如主成分分析,lasso等等。不过,这里我们要介绍的是用随机森林来对进行特征筛选。

用随机森林进行特征重要性评估的思想其实很简单,说白了就是看看每个特征在随机森林中的每颗树上做了多大的贡献,然后取个平均值,最后比一比特征之间的贡献大小。

好了,那么这个贡献是怎么一个说法呢?通常可以用基尼指数(Gini index)或者袋外数据(OOB)错误率作为评价指标来衡量。

我们这里只介绍用基尼指数来评价的方法,想了解另一种方法的可以参考文献2。

我们将变量重要性评分(variable importance measures)用 V I M VIM VIM来表示,将Gini指数用 G I GI GI来表示,假设有 J J J个特征 X 1 , X 2 , X 3 , . . . , X J X_1,X_2,X_3,...,X_J X1​,X2​,X3​,...,XJ​, I I I棵决策树, C C C个类别,现在要计算出每个特征 X j X_j Xj​的Gini指数评分 V I M j ( G i n i ) VIM_j^{(Gini)} VIMj(Gini)​,亦即第 j j j个特征在RF所有决策树中节点分裂不纯度的平均改变量。

第 i i i棵树节点 q q q的Gini指数的计算公式为

G I q ( i ) = ∑ c = 1 ∣ C ∣ ∑ c ′ ≠ c p q c ( i ) p q c ′ ( i ) = 1 − ∑ c = 1 ∣ C ∣ ( p q c ( i ) ) 2 (3-1) GI_q^{(i)}=\sum_{c=1}^{|C|}\sum_{c' \neq c } p_{qc}^{(i)} p_{qc'}^{(i)}=1-\sum_{c=1}^{|C|}(p_{qc}^{(i)})^2 \tag{3-1} GIq(i)​=c=1∑∣C∣​c′​=c∑​pqc(i)​pqc′(i)​=1−c=1∑∣C∣​(pqc(i)​)2(3-1)

其中, C C C表示有 C C C个类别, p q c p_{qc} pqc​表示节点 q q q中类别 c c c所占的比例。

直观地说,就是随便从节点 q q q中随机抽取两个样本,其类别标记不一致的概率。

特征 X j X_j Xj​在第 i i i棵树节点 q q q的重要性,即节点 q q q分枝前后的 G i n i Gini Gini指数变化量为

V I M j q ( G i n i ) ( i ) = G I q ( i ) − G I l ( i ) − G I r ( i ) (3-2) VIM_{jq}^{(Gini)(i)}=GI_q^{(i)}-GI_l^{(i)}-GI_r^{(i)} \tag{3-2} VIMjq(Gini)(i)​=GIq(i)​−GIl(i)​−GIr(i)​(3-2)

其中, G I l ( i ) GI_l^{(i)} GIl(i)​和 G I r ( i ) GI_r^{(i)} GIr(i)​分别表示分枝后两个新节点的 G i n i Gini Gini指数。

如果,特征 X j X_j Xj​在决策树 i i i中出现的节点为集合 Q Q Q,那么 X j X_j Xj​在第 i i i颗树的重要性为

V I M j ( G i n i ) ( i ) = ∑ q ∈ Q V I M j q ( G i n i ) ( i ) (3-3) VIM_{j}^{(Gini)(i)}=\sum_{q \in Q}VIM_{jq}^{(Gini)(i)} \tag{3-3} VIMj(Gini)(i)​=q∈Q∑​VIMjq(Gini)(i)​(3-3)

假设 R F RF RF中共有 I I I颗树,那么

V I M j ( G i n i ) = ∑ i = 1 I V I M j ( G i n i ) ( i ) (3-4) VIM_j^{(Gini)}=\sum_{i=1}^{I}VIM_{j}^{(Gini)(i)} \tag{3-4} VIMj(Gini)​=i=1∑I​VIMj(Gini)(i)​(3-4)

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

V I M j ( G i n i ) = V I M j ( G i n i ) ∑ j ′ = 1 J V I M j ′ ( G i n i ) (3-5) VIM_j^{(Gini)}=\dfrac{VIM_j^{(Gini)}}{\sum_{j'=1}^J VIM_{j'}^{(Gini)}} \tag{3-5} VIMj(Gini)​=∑j′=1J​VIMj′(Gini)​VIMj(Gini)​​(3-5)

4 举个例子

值得庆幸的是, s k l e a r n sklearn sklearn已经帮我们封装好了一切,我们只需要调用其中的函数即可。

我们以UCI上葡萄酒的例子为例,首先导入数据集。

import pandas as pdurl = 'http://archive.ics.uci.edu/ml/machine-learning-databases/wine/wine.data'df = pd.read_csv(url, header = None)df.columns = ['Class label', 'Alcohol', 'Malic acid', 'Ash', 'Alcalinity of ash', 'Magnesium', 'Total phenols', 'Flavanoids', 'Nonflavanoid phenols', 'Proanthocyanins', 'Color intensity', 'Hue', 'OD280/OD315 of diluted wines', 'Proline']

然后,我们来大致看下这时一个怎么样的数据集

import numpy as npnp.unique(df['Class label'])

输出为

array([1, 2, 3], dtype=int64)

可见共有3个类别。然后再来看下数据的信息:

df.info()

输出为

<class 'pandas.core.frame.DataFrame'>RangeIndex: 178 entries, 0 to 177Data columns (total 14 columns):Class label 178 non-null int64Alcohol178 non-null float64Malic acid 178 non-null float64Ash 178 non-null float64Alcalinity of ash178 non-null float64Magnesium 178 non-null int64Total phenols 178 non-null float64Flavanoids 178 non-null float64Nonflavanoid phenols 178 non-null float64Proanthocyanins 178 non-null float64Color intensity 178 non-null float64Hue 178 non-null float64OD280/OD315 of diluted wines 178 non-null float64Proline178 non-null int64dtypes: float64(11), int64(3)memory usage: 19.5 KB

可见除去class label之外共有13个特征,数据集的大小为178。

按照常规做法,将数据集分为训练集和测试集。

try:from sklearn.cross_validation import train_test_splitexcept:from sklearn.model_selection import train_test_splitfrom sklearn.ensemble import RandomForestClassifierx, y = df.iloc[:, 1:].values, df.iloc[:, 0].valuesx_train, x_test, y_train, y_test = train_test_split(x, y, test_size = 0.3, random_state = 0)feat_labels = df.columns[1:]forest = RandomForestClassifier(n_estimators=10000, random_state=0, n_jobs=-1)forest.fit(x_train, y_train)

好了,这样一来随机森林就训练好了,其中已经把特征的重要性评估也做好了,我们拿出来看下。

importances = forest.feature_importances_indices = np.argsort(importances)[::-1]for f in range(x_train.shape[1]):print("%2d) %-*s %f" % (f + 1, 30, feat_labels[indices[f]], importances[indices[f]]))

输出的结果为

1) Color intensity0.1824832) Proline 0.1586103) Flavanoids 0.1509484) OD280/OD315 of diluted wines 0.1319875) Alcohol 0.1065896) Hue 0.0782437) Total phenols 0.0607188) Alcalinity of ash 0.0320339) Malic acid 0.02540010) Proanthocyanins0.02235111) Magnesium 0.02207812) Nonflavanoid phenols 0.01464513) Ash 0.013916

对的就是这么方便。

如果要筛选出重要性比较高的变量的话,这么做就可以

threshold = 0.15x_selected = x_train[:, importances > threshold]x_selected.shape

输出为

(124, 3)

瞧,这不,帮我们选好了3个重要性大于0.15的特征了吗~

5 参考文献

[1] Raschka S. Python Machine Learning[M]. Packt Publishing, .

[2] 杨凯, 侯艳, 李康. 随机森林变量重要性评分及其研究进展[J]. .

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。