赞
踩
Datawhale干货
编辑:数据派THU,来源:机器学习研习院
本文约2000字,建议阅读8分钟本文对随机森林如何用在特征选择上做一个简单的介绍。
只要了解决策树的算法,那么随机森林是相当容易理解的。随机森林的算法可以用如下几个步骤概括:
用有抽样放回的方法(bootstrap)从样本集中选取n个样本作为一个训练集。
用抽样得到的样本集生成一棵决策树。在生成的每一个结点:
随机不重复地选择d个特征;
利用这d个特征分别对样本集进行划分,找到最佳的划分特征(可用基尼系数、增益率或者信息增益判别)。
重复步骤1到步骤2共k次,k即为随机森林中决策树的个数。
用训练得到的随机森林对测试样本进行预测,并用票选法决定预测的结果。
下图比较直观地展示了随机森林算法(图片出自文献2):
没错,就是这个到处都是随机取值的算法,在分类和回归上有着极佳的效果,是不是觉得强的没法解释~
然而本文的重点不是这个,而是接下来的特征重要性评估。
现实情况下,一个数据集中往往有成百上前个特征,如何在其中选择比结果影响最大的那几个特征,以此来缩减建立模型时的特征数是我们比较关心的问题。这样的方法其实很多,比如主成分分析,lasso等等。不过,这里我们要介绍的是用随机森林来对进行特征筛选。
用随机森林进行特征重要性评估的思想其实很简单,说白了就是看看每个特征在随机森林中的每棵树上做了多大的贡献,然后取个平均值,最后比一比特征之间的贡献大小。
好了,那么这个贡献是怎么一个说法呢?通常可以用基尼指数(Gini index)或者袋外数据(OOB)错误率作为评价指标来衡量。
我们这里只介绍用基尼指数来评价的方法,首先对另一种方法做个简单介绍,具体可以参考文献2:
的定义为:在 RF 的每棵树中,使用随机抽取的训练自助样本建树,并计算袋外数据 OOB)的预测错误率,然后随机置换变量X,的观测值后再次建树并计算 OOB 的预测错误率,最后计算两次 OOB 错误率的差值经过标准化处理后在所有树中的平均值即为变量 ,的置换重要性 ()
我们将变量重要性评分(variable importance measures)用 来表示,将Gini指数用 来表示,假设有 个特征 ,,,,, 棵决策树, 个类别,现在要计算出每个特征 的Gini指数评分 ,亦即第 个特征在RF所有决策树中节点分裂不纯度的平均改变量。
第 棵树节点 的 指数的计算公式为:
其中, 表示有 个类别, 表示节点 中类别 所占的比例。直观地说,就是随便从节点 中随机抽取两个样本,其类别标记不一致的概率。
特征 在第 棵树节点 的重要性,即节点 分枝前后的 指数变化量为:
其中,和 分别表示分枝后两个新节点的指数。如果,特征 在决策树 i 中出现的节点为集合,那么 在第 棵树的重要性为:
假设 RF 中共有 I 棵树,那么:
最后,把所有求得的重要性评分做一个归一化处理即可。
值得庆幸的是,sklearn已经帮我们封装好了一切,我们只需要调用其中的函数即可。
我们以UCI上葡萄酒的例子为例,首先导入数据集。
- import pandas as pd
- url = '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 np
- np.unique(df['Class label'])
输出为:
array([1, 2, 3], dtype=int64)
可见共有3个类别。然后再来看下数据的信息:
df.info()
输出为:
<class 'pandas.core.frame.DataFrame'> RangeIndex: 178 entries, 0 to 177 Data columns (total 14 columns): Class label 178 non-null int64 Alcohol 178 non-null float64 Malic acid 178 non-null float64 Ash 178 non-null float64 Alcalinity of ash 178 non-null float64 Magnesium 178 non-null int64 Total phenols 178 non-null float64 Flavanoids 178 non-null float64 Nonflavanoid phenols 178 non-null float64 Proanthocyanins 178 non-null float64 Color intensity 178 non-null float64 Hue 178 non-null float64 OD280/OD315 of diluted wines 178 non-null float64 Proline 178 non-null int64 dtypes: float64(11), int64(3) memory usage: 19.5 KB
可见除去class label之外共有13个特征,数据集的大小为178。按照常规做法,将数据集分为训练集和测试集。
- try:
- from sklearn.cross_validation import train_test_split
- except:
- from sklearn.model_selection import train_test_split
- from sklearn.ensemble import RandomForestClassifier
- x, y = df.iloc[:, 1:].values, df.iloc[:, 0].values
- x_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 intensity 0.182483
- 2) Proline 0.158610
- 3) Flavanoids 0.150948
- 4) OD280/OD315 of diluted wines 0.131987
- 5) Alcohol 0.106589
- 6) Hue 0.078243
- 7) Total phenols 0.060718
- 8) Alcalinity of ash 0.032033
- 9) Malic acid 0.025400
- 10) Proanthocyanins 0.022351
- 11) Magnesium 0.022078
- 12) Nonflavanoid phenols 0.014645
- 13) Ash 0.013916
对的就是这么方便。如果要筛选出重要性比较高的变量的话,这么做就可以:
- threshold = 0.15
- x_selected = x_train[:, importances > threshold]
- x_selected.shape
输出为:
(124, 3)
瞧,这不,帮我们选好了3个重要性大于0.15的特征了吗~
参考文献
[1] Raschka S. Python Machine Learning[M]. Packt Publishing, 2015.
[2] 杨凯, 侯艳, 李康. 随机森林变量重要性评分及其研究进展[J]. 2015.
来源:https://blog.csdn.net/zjuPeco/article
作者:zjuPeco
- 往期精彩回顾
-
-
-
-
- 适合初学者入门人工智能的路线及资料下载(图文+视频)机器学习入门系列下载机器学习及深度学习笔记等资料打印《统计学习方法》的代码复现专辑机器学习交流qq群955171419,加入微信群请扫码
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。