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

文章目录

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

1 前言

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

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

2 随机森林(RF)简介

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

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

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

随机森林算法

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

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

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

3 特征重要性评估

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

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

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

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

我们将变量重要性评分(variable importance measures)用VIMVIMVIM来表示,将Gini指数用GIGIGI来表示,假设有JJJ个特征X1,X2,X3,...,XJX_1,X_2,X_3,...,X_JX1X2X3...XJIII棵决策树,CCC个类别,现在要计算出每个特征XjX_jXj的Gini指数评分VIMj(Gini)VIM_j^{(Gini)}VIMj(Gini),亦即第jjj个特征在RF所有决策树中节点分裂不纯度的平均改变量。

iii棵树节点qqq的Gini指数的计算公式为

GIq(i)=∑c=1∣C∣∑c′≠cpqc(i)pqc′(i)=1−∑c=1∣C∣(pqc(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=1Cc=cpqc(i)pqc(i)=1c=1C(pqc(i))2(3-1)

其中,CCC表示有CCC个类别,pqcp_{qc}pqc表示节点qqq中类别ccc所占的比例。

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

特征XjX_jXj在第iii棵树节点qqq的重要性,即节点qqq分枝前后的GiniGiniGini指数变化量为

VIMjq(Gini)(i)=GIq(i)−GIl(i)−GIr(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)

其中,GIl(i)GI_l^{(i)}GIl(i)GIr(i)GI_r^{(i)}GIr(i)分别表示分枝后两个新节点的GiniGiniGini指数。

如果,特征XjX_jXj在决策树iii中出现的节点为集合QQQ,那么XjX_jXj在第iii颗树的重要性为

VIMj(Gini)(i)=∑q∈QVIMjq(Gini)(i)(3-3)VIM_{j}^{(Gini)(i)}=\sum_{q \in Q}VIM_{jq}^{(Gini)(i)} \tag{3-3}VIMj(Gini)(i)=qQVIMjq(Gini)(i)(3-3)

假设RFRFRF中共有III颗树,那么

VIMj(Gini)=∑i=1IVIMj(Gini)(i)(3-4)VIM_j^{(Gini)}=\sum_{i=1}^{I}VIM_{j}^{(Gini)(i)} \tag{3-4}VIMj(Gini)=i=1IVIMj(Gini)(i)(3-4)

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

VIMj(Gini)=VIMj(Gini)∑j′=1JVIMj′(Gini)(3-5)VIM_j^{(Gini)}=\dfrac{VIM_j^{(Gini)}}{\sum_{j'=1}^J VIM_{j'}^{(Gini)}} \tag{3-5}VIMj(Gini)=j=1JVIMj(Gini)VIMj(Gini)(3-5)

4 举个例子

值得庆幸的是,sklearnsklearnsklearn已经帮我们封装好了一切,我们只需要调用其中的函数即可。

我们以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.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.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的特征了吗~

5 参考文献

[1] Raschka S. Python Machine Learning[M]. Packt Publishing, 2015.
[2] 杨凯, 侯艳, 李康. 随机森林变量重要性评分及其研究进展[J]. 2015.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/470773.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

个人博客总结3

一&#xff0e;昨天做了什么&#xff1f; 昨天利用安卓连接数据库完成一个图片的保存的程序例子&#xff0c;为我们的团队作业刷脸将人脸图片保存到数据中打下基础。 创建了一个相片和数据库保存和查询的工程创建了一个数据库然后将图片保存到数据库中&#xff0c;先将图片转化…

Promise学习——解决回调地狱问题

Promise promise 容器概念&#xff1a; callback hell&#xff08;回调地狱&#xff09;: 文件的读取无法判断执行顺序&#xff08;文件的执行顺序是依据文件的大小来决定的&#xff09;(异步api无法保证文件的执行顺序) var fs require(fs);fs.readFile(./data/a.text,ut…

基于哈希表的索引堆变形(Hackerrank: QHEAP1)

问题来源 此题来自于Hackerrank中的QHEAP1问题&#xff0c;考查了对堆结构的充分理解。成功完成此题&#xff0c;对最大堆或者最小堆的基本操作实现就没什么太大问题了。 问题简述 实现一个最小堆&#xff0c;对3种类型的输入能给出正确的操作&#xff1a; “1 v” - 表示往…

Node 中的path模块

参考文档&#xff1a;https://nodejs.org/docs/latest-v13.x/api/path.html path模块中的常用API&#xff1a; path.basename&#xff1a;获取路径的文件名&#xff0c;默认包含扩展名path.dirname&#xff1a;获取路径中的目录部分path.extname&#xff1a;获取一个路径中的扩…

利用回溯法解决1-9之间添加+或-或使得运算结果为100的问题

问题描述 编写一个在1&#xff0c;2&#xff0c;…&#xff0c;9&#xff08;顺序不能变&#xff09;数字之间插入或-或什么都不插入&#xff0c;使得计算结果总是100的程序&#xff0c;并输出所有的可能性。例如&#xff1a;1 2 34 – 5 67 – 8 9 100。 问题分析 这时…

Atitit。数据库 安全性 重要敏感数据加密存储解决方案

Atitit。数据库 安全性 重要敏感数据加密存储解决方案 1.1. 加密存储的重要性1 1.2. 使用的加密算法aes1 1.3. 数据加密以后会有一些问题。1 1.3.1. 一个是统计&#xff0c;比如统计资金总额。。就无法直接使用sql的sum等数据库内部聚合函数来处理了。。1 1.3.2. 还有一个就是按…

Node中的fs模块

1.fs.stat检测是文件还是目录 2.fs.mkdir创建目录 3.fs.writeFile创建写入文件 4.fs.appendFile追加文件 5.fs.readFile 读取文件 6.fs.readdir读取目录 7.fs.rename重命名 8.fs.rmdir删除目录 9.fs.unlink 删除文件 fs.stat 检测是文件还是目录 const fs require(fs)fs.stat…

主成分分析(PCA)和基于核函数的主成分分析(KPCA)入门

文章目录1 前言2 PCA的原理2.1 什么是投影2.2 投影后的方差2.3 转化为求特征值的问题2.4 符号的表示3 KPCA的原理4 PCA和KPCA在Python中的使用4.1 PCA的使用4.2 KPCA的使用5 参考文献1 前言 主成分分析是在做特征筛选时的重要手段&#xff0c;这个方法在大部分的书中都只是介绍…

算法分类整理+模板①:矩阵快速幂

一直有一个想法&#xff0c;感觉自己很多基础算法不是很扎实&#xff0c;想要找个机会写一些算法的整理&#xff0c;顺便自己总结一些实用的模板。 最近偶然在训练赛中连续做了2道思维矩阵快速幂的题目&#xff0c;碰巧有时间&#xff0c;就以矩阵快速幂作为这个系列博客的开始…

爬虫小记:利用cookies跳过登陆验证码

前言 在爬取某些网页时&#xff0c;登陆界面时经常遇到的一个坎&#xff0c;而现在大多数的网站在登陆时都会要求用户填写验证码。当然&#xff0c;我们可以设计一套机器学习的算法去破解验证码&#xff0c;然而&#xff0c;验证码的形式多种多样&#xff0c;稍微变一下&#…

IOS的 testflight测试设置

管理员邀请参与者 1、登录开发者账号https://developer.apple.com/account 2、进入后&#xff0c;点击ituns connect 3、点击进入用户和职能 4、在用户栏点击添加按钮 5、输入姓名、邮件 6、勾选职能为“开发人员”&#xff0c;选择所要测试或参与研发的APP 7、不用修改&#x…

Nodejs 中的包、npm 、第三方模块、 package.json 以及 cnpm

一、包与 NPM 包Nodejs 中除了它自己提供的核心模块外&#xff0c;我们可以自定义模块&#xff0c;也可以使用第三方的 模块。Nodejs 中第三方模块由包组成&#xff0c;可以通过包来对一组具有相互依赖关系的模块进行 统一管理。 完全符合 CommonJs 规范的包目录一般包含如下…

神经网络中BP(back propagation)到底在干些什么

前言 想要理解神经网络的工作原理&#xff0c;反向传播(BP)是必须搞懂的东西。BP其实并不难理解&#xff0c;说白了就是用链式法则(chain rule)算算算。本文试图以某个神经网络为例&#xff0c;尽可能直观&#xff0c;详细&#xff0c;明了地说明反向传播的整个过程。 正向传…

TOP 子句

TOP 子句TOP 子句用于规定要返回的记录的数目。对于拥有数千条记录的大型表来说&#xff0c;TOP 子句是非常有用的。注释&#xff1a;并非所有的数据库系统都支持 TOP 子句。SQL Server 的语法&#xff1a;SELECT TOP number|percent column_name(s)FROM table_nameMySQL 和 Or…

Nodejs 新特性 async await 的使用 以及使用 async await 处理异步

1. let 和 var 2. const定义常量 3. 模板字符串 4. 属性简写 5. 方法简写 6. 箭头函数 7. 回调函数 7. Promise 8. async 和 await

leetcode 高薪_LeetCode 第 125 号问题:验证回文串

本文首发于公众号「五分钟学算法」&#xff0c;是图解 LeetCode 系列文章之一。个人网站&#xff1a;https://www.cxyxiaowu.com题目来源于 LeetCode 第 125 号问题&#xff1a;验证回文串。这道题目是 初级程序员 在面试的时候经常遇到的一道算法题&#xff0c;而且面试官喜欢…

从拉格朗日乘子法到SVM

前言 本文主要是讲了如何构建SVM的模型&#xff0c;并利用KKT条件构造其对偶型&#xff0c;从而求解问题&#xff0c;并讲述了SVM的硬间隔&#xff0c;软间隔和核函数三个境界。主要参考了周志华的《机器学习》&#xff0c;并在其中补充了自己的想法。由于内容较多&#xff0c…

nodejs 创建一个静态资源服务器 +路由

0、补充 1、Node.js 创建的第一个应用 1、引入 http 模块 var http require("http"); 2、创建服务器 接下来我们使用 http.createServer() 方法创建服务器&#xff0c;并使用 listen 方法绑定 3000 端口。 函数通过 request, response 参数来接收和响应数据。 co…

python输出字体的大小_Python密码学编程:文件的加密与解密

在之前的章节中&#xff0c;编写的程序只能操作较少的信息&#xff0c;这些信息往往是以字符串的形式直接写在代码中的。但本章中的程序可以对整个文件进行加密和解密&#xff0c;文件的大小可以包括成千上万个字符。本章要点open()方法。读、写文件。write()、close()及read()…

个人工作总结7

时间关系&#xff0c;只能等到编完了程序再做工作总结了&#xff0c;今天是第七天: 一、昨天干了什么&#xff1f; 服务器配置了一大圈&#xff0c;尝试了N1种办法&#xff0c;到最后也没有成功&#xff0c;但好像只差一点点&#xff0c;打算明天上移动应用开发咨询一下老师。 …