R语言学习笔记—决策树分类
一、简介
决策树分类算法(decision tree)通过树状结构对具有某特征属性的样本进行分类。其典型算法包括ID3算法、C4.5算法、C5.0算法、CART算法等。每一个决策树包括根节点(root node),内部节点(internal node)以及叶子节点(leaf node)。
根节点:表示第一个特征属性,只有出边没有入边,通常用矩形框表示。
内部节点:表示特征属性,有一条入边至少两条出边,通常用圆圈表示。
叶子节点:表示类别,只有一条入边没有出边,通常用三角表示。
决策树算法主要用于分类,也可用于回归,当决策树的输出变量是分类变量时,是分类树;当决策树输出变量是连续变量时,是回归树。虽然回归树的因变量是连续的,但叶节点数是有穷的,因此输出值也是这个叶节点上观测值的平均。
二、基本思想
决策树算法基本思想可以归纳如下:
第一步,对特征空间按照特征属性进行划分;
第二步,对分类后的子集递归第一步。
分类过程看起来很简单,但是要想得到【完全纯净】的子集,也就是每一个子集中的样本都属于同一个分类,还需要一个评价指标对分类效果好坏进行评估——熵。
熵,是系统一种无组织、无序的状态,广泛应用于信息论中。熵值越大,表明数据的纯度越低。当熵等于0,表明样本数据都是同一个类别。其计算公式如下:
其中,P(Xi)表示概率,b此处取值为2。熵的单位为比特bite。
信息增益(information gain):代表的是一次划分对数据纯度的提升效果,也就是划分以后,熵减少越多,说明增益越大,那么这次划分也就越有价值,增益的计算公式如下:
其中D表示样本集,假定属性a有v个可能的取值(离散或连续)。进行最有划分属性时,比如先找到了属性a,对a进行评价,接下来对其他属性重复a的过程,分别得到一个评分,选择评分最高的那个,即信息增益最大的作为最有划分属性。简言之,信息增益就是分割属性前的熵值与分割后的熵值进行差异比较。
需要注意的是,计算子集的熵之和需要乘上各个子集的权重,权重的计算方法是子集的规模占分割前父集的比重。如,分割前的熵为e,分割子集为a和b,大小分别为m和n,熵分别为e1和e2,则信息增益为e-e1*m/(m+n)-e2*n/(m+n)。
三、ID3算法实现
分类的本质是对特征空间的划分。根据决策树的基本思想,其算法实现主要有以下三步:
1.选择特征属性,样本分割。
2.计算信息增益,选取最大增益作为决策树的子节点。
3.递归执行上两步,直至分类完成。
下面将介绍ID3算法在R语言中实现过程。
一组14天天气数据(指标包括outlook,temperature,humidity,windy),并已知这些天气是否打球(play)。如果给出新一天的气象指标数据:sunny,cool,high,TRUE,判断一下会不会去打球。
Outlook |
temperature |
humidity |
windy |
play |
Sunny |
hot |
high |
FALSE |
no |
Sunny |
hot |
high |
TRUE |
no |
Overcast |
hot |
high |
FALSE |
yes |
Rainy |
mild |
high |
FALSE |
yes |
Rainy |
cool |
normal |
FALSE |
yes |
Rainy |
cool |
normal |
TRUE |
no |
Overcast |
cool |
normal |
TRUE |
yes |
Sunny |
mild |
high |
FALSE |
no |
Sunny |
cool |
normal |
FALSE |
yes |
Rainy |
mild |
normal |
FALSE |
yes |
Sunny |
mild |
normal |
TRUE |
yes |
Overcast |
mild |
high |
TRUE |
yes |
Overcast |
hot |
normal |
FALSE |
yes |
Rainy |
mild |
high |
TRUE |
no |
在没有给定任何天气信息时,根据历史数据,我们只知道新的一天打球的概率是9/14,不打的概率是5/14。此时的熵为:
属性有4个:outlook,temperature,humidity,windy。我们首先要决定哪个属性作为树的根节点。
统计在不同天气状况下打球和不打球的次数:
outlook |
temperature |
humidity |
windy |
play |
|||||||||
yes |
no |
yes |
no |
yes |
no |
yes |
no |
yes |
no |
||||
sunny |
2 |
3 |
hot |
2 |
2 |
high |
3 |
4 |
FALSE |
6 |
2 |
9 |
5 |
overcast |
4 |
0 |
mild |
4 |
2 |
normal |
6 |
1 |
TRUR |
3 |
3 |
||
rainy |
3 |
2 |
cool |
3 |
1 |
代码:
##决策树模型之ID3算法 #从粘贴板读取表格数据
weather <- read.table("clipboard",T)
#查看数据结构
str(weather)
#将windy指标转换成因子型
weather$windy <- as.factor(weather$windy)
#未分割前信息熵
q <- matrix(table(weather$play),nrow = 1,dimnames = list('play',unique(weather$play)))/
sum(matrix(table(weather$play),nrow = 1))
e <- -sum(q*log2(q))
#计算各特征属性的信息熵
myfun <- function(x,y){
t <- table(x,y)
m <- matrix(t,nrow = length(levels(x)),2,dimnames = list(levels(x),levels(y)))
#权重计算
n <- apply(m,1,sum)/sum(m)
#分割后各子集的熵
freq <- -rowSums((m/rowSums(m))*log2(m/rowSums(m)))
#分割后的最终熵
entropy <- sum(n*freq,na.rm = T)
return(entropy)
}
#计算信息增益information gain
y <- weather[,5]
gain <- vector()
for (i in 1:(length(weather)-1)) {
x <- weather[,i]
gain[i] <- e-myfun(x,y)
}
names(gain) <- colnames(weather[,1:4])
gain
运行结果:
根据各特征属性的信息增益比较得到,outlook信息增益最大,即熵变化越大,所以决策树的根节点应选择outlook。
接下来选择各子节点N1,N2,N3的特征属性。
用属性outlook划分样本后,三个属性值sunny,overcast,rainy把样本划分为三部分,在每一部分下分别计算gain(temperature)、gain(humidity)、gain(windy)
代码:
#选择子节点特征属性
level <- levels(weather$outlook)
son_gain <- data.frame()
for(j in 1:length(level)){
son_q <- matrix(table(weather[weather$outlook==level[j],]$play),nrow = 1,
dimnames = list('play',unique(weather$play)))/
sum(matrix(table(weather[weather$outlook==level[j],]$play),nrow = 1))
son_e[j]<- -sum(son_q*log2(son_q))
}
for (j in 1:length(level)) {
for (i in 1:length(level)) {
sl <- weather[weather$outlook==level[j],]
son_x <- sl[,i+1]
son_y <- sl[,5]
son_gain[j,i] <- son_e[j]-myfun(x=son_x,y=son_y)
}
}
colnames(son_gain) <- colnames(weather[,-c(1,5)])
rownames(son_gain) <- level
son_gain
信息增益结果:
根据上述结果,在Sunny分支上,humidity的信息增益最大,即熵减少得越快,因此应当将humidity作为子节点N1处的特征属性。
此时,humidity=normal以及humidity=high最终得到的分类结果均为同一中类别,无需在humidity节点下进行再分类,该节点为叶子节点。
同样在rainy分支下的子节点N3应选择windy。且在该节点下无需再进行分类。
在overcast分支下,所有的样本都属于同一个分类,因此该节点为叶子节点。
最终的分类树为:
R语言学习笔记—决策树分类的更多相关文章
- R语言学习笔记之: 论如何正确把EXCEL文件喂给R处理
博客总目录:http://www.cnblogs.com/weibaar/p/4507801.html ---- 前言: 应用背景兼吐槽 继续延续之前每个月至少一次更新博客,归纳总结学习心得好习惯. ...
- R语言学习笔记(二)
今天主要学习了两个统计学的基本概念:峰度和偏度,并且用R语言来描述. > vars<-c("mpg","hp","wt") &g ...
- R语言学习笔记:因子
R语言中的因子就是factor,用来表示分类变量(categorical variables),这类变量不能用来计算而只能用来分类或者计数. 可以排序的因子称为有序因子(ordered factor) ...
- R语言学习笔记:小试R环境
买了三本R语言的书,同时使用来学习R语言,粗略翻下来感觉第一本最好: <R语言编程艺术>The Art of R Programming <R语言初学者使用>A Beginne ...
- R语言学习笔记:基础知识
1.数据分析金字塔 2.[文件]-[改变工作目录] 3.[程序包]-[设定CRAN镜像] [程序包]-[安装程序包] 4.向量 c() 例:x=c(2,5,8,3,5,9) 例:x=c(1:100) ...
- R语言学习笔记—K近邻算法
K近邻算法(KNN)是指一个样本如果在特征空间中的K个最相邻的样本中的大多数属于某一个类别,则该样本也属于这个类别,并具有这个类别上样本的特性.即每个样本都可以用它最接近的k个邻居来代表.KNN算法适 ...
- R语言学习笔记—朴素贝叶斯分类
朴素贝叶斯分类(naive bayesian,nb)源于贝叶斯理论,其基本思想:假设样本属性之间相互独立,对于给定的待分类项,求解在此项出现的情况下其他各个类别出现的概率,哪个最大,就认为待分类项属于 ...
- R语言学习笔记——C#中如何使用R语言setwd()函数
在R语言编译器中,设置当前工作文件夹可以用setwd()函数. > setwd("e://桌面//")> setwd("e:\桌面\")> s ...
- R语言学习笔记-机器学习1-3章
在折腾完爬虫还有一些感兴趣的内容后,我最近在看用R语言进行简单机器学习的知识,主要参考了<机器学习-实用案例解析>这本书. 这本书是目前市面少有的,纯粹以R语言为基础讲解的机器学习知识,书 ...
随机推荐
- 2 Docker 镜像基础
Docker 镜像可以从docker.io 下载,也可以自己通过Dockerfile来构建镜像,我有时从国外下载镜像时,网速不行,我就改成国内的镜像,修改如下: # vim /etc/docker/d ...
- POJ 2528 Mayor's poster
主要是参考了这个博客 地址戳这儿 题目大意:n(n<=10000) 个人依次贴海报,给出每张海报所贴的范围li,ri(1<=li<=ri<=10000000) .求出最后还能看 ...
- 利用describe( )中的count来检查数据是否缺省
#-*- coding: utf-8 -*- #在python的pandas库中,只需要读入数据,然后使用describe()函数就可以查看数据的基本情况 import pandas as pd in ...
- Linux 系统性能监控命令详解
Linux 系统性能监控命令详解 CPU MEMORY IO NETWORK LINUX进程内存占用查看方法 系统负载过重时往往会引起其它子系统的问题,比如:->大量的读入内存的IO请求(pag ...
- javascript对象和函数的几种常见写法
/** * Created by chet on 15/12/17. */ var En= function (button,func) { //dosth,不能return alert(button ...
- 随手练——HDU-2037 、P-2920 时间安排(贪心)
普通时间安排 HDU-2037 :http://acm.hdu.edu.cn/showproblem.php?pid=2037 选取结束时间早的策略. #include <iostream> ...
- iOS获取当前连接的wifi信息
导入框架CaptiveNetwork #import <SystemConfiguration/CaptiveNetwork.h> 获取当前连接的wifi信息 // 只能获取当前的SSID ...
- 【Step By Step】将Dotnet Core部署到Docker下
一.使用.Net Core构建WebAPI并访问Docker中的Mysql数据库 这个的过程大概与我之前的文章<尝试.Net Core—使用.Net Core + Entity FrameWor ...
- java中的作用域
在说明这四个关键字之前,我想就class之间的关系做一个简单的定义,对于继承自己的class,base class可以认为他们都是自己的子女,而对于和自己一个目录下的classes,认为都是自己的朋友 ...
- 转发: Angular装饰器
Angular中的装饰器是一个函数,它将元数据添加到类.类成员(属性.方法)和函数参数. 用法:要想应用装饰器,把它放在被装饰对象的上面或左边. Angular使用自己的一套装饰器来实现应用程序各部件 ...