一、简介

决策树分类算法(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语言学习笔记—决策树分类的更多相关文章

  1. R语言学习笔记之: 论如何正确把EXCEL文件喂给R处理

    博客总目录:http://www.cnblogs.com/weibaar/p/4507801.html ---- 前言: 应用背景兼吐槽 继续延续之前每个月至少一次更新博客,归纳总结学习心得好习惯. ...

  2. R语言学习笔记(二)

    今天主要学习了两个统计学的基本概念:峰度和偏度,并且用R语言来描述. > vars<-c("mpg","hp","wt") &g ...

  3. R语言学习笔记:因子

    R语言中的因子就是factor,用来表示分类变量(categorical variables),这类变量不能用来计算而只能用来分类或者计数. 可以排序的因子称为有序因子(ordered factor) ...

  4. R语言学习笔记:小试R环境

    买了三本R语言的书,同时使用来学习R语言,粗略翻下来感觉第一本最好: <R语言编程艺术>The Art of R Programming <R语言初学者使用>A Beginne ...

  5. R语言学习笔记:基础知识

    1.数据分析金字塔 2.[文件]-[改变工作目录] 3.[程序包]-[设定CRAN镜像] [程序包]-[安装程序包] 4.向量 c() 例:x=c(2,5,8,3,5,9) 例:x=c(1:100) ...

  6. R语言学习笔记—K近邻算法

    K近邻算法(KNN)是指一个样本如果在特征空间中的K个最相邻的样本中的大多数属于某一个类别,则该样本也属于这个类别,并具有这个类别上样本的特性.即每个样本都可以用它最接近的k个邻居来代表.KNN算法适 ...

  7. R语言学习笔记—朴素贝叶斯分类

    朴素贝叶斯分类(naive bayesian,nb)源于贝叶斯理论,其基本思想:假设样本属性之间相互独立,对于给定的待分类项,求解在此项出现的情况下其他各个类别出现的概率,哪个最大,就认为待分类项属于 ...

  8. R语言学习笔记——C#中如何使用R语言setwd()函数

    在R语言编译器中,设置当前工作文件夹可以用setwd()函数. > setwd("e://桌面//")> setwd("e:\桌面\")> s ...

  9. R语言学习笔记-机器学习1-3章

    在折腾完爬虫还有一些感兴趣的内容后,我最近在看用R语言进行简单机器学习的知识,主要参考了<机器学习-实用案例解析>这本书. 这本书是目前市面少有的,纯粹以R语言为基础讲解的机器学习知识,书 ...

随机推荐

  1. 2 Docker 镜像基础

    Docker 镜像可以从docker.io 下载,也可以自己通过Dockerfile来构建镜像,我有时从国外下载镜像时,网速不行,我就改成国内的镜像,修改如下: # vim /etc/docker/d ...

  2. POJ 2528 Mayor's poster

    主要是参考了这个博客 地址戳这儿 题目大意:n(n<=10000) 个人依次贴海报,给出每张海报所贴的范围li,ri(1<=li<=ri<=10000000) .求出最后还能看 ...

  3. 利用describe( )中的count来检查数据是否缺省

    #-*- coding: utf-8 -*- #在python的pandas库中,只需要读入数据,然后使用describe()函数就可以查看数据的基本情况 import pandas as pd in ...

  4. Linux 系统性能监控命令详解

    Linux 系统性能监控命令详解 CPU MEMORY IO NETWORK LINUX进程内存占用查看方法 系统负载过重时往往会引起其它子系统的问题,比如:->大量的读入内存的IO请求(pag ...

  5. javascript对象和函数的几种常见写法

    /** * Created by chet on 15/12/17. */ var En= function (button,func) { //dosth,不能return alert(button ...

  6. 随手练——HDU-2037 、P-2920 时间安排(贪心)

    普通时间安排 HDU-2037 :http://acm.hdu.edu.cn/showproblem.php?pid=2037 选取结束时间早的策略. #include <iostream> ...

  7. iOS获取当前连接的wifi信息

    导入框架CaptiveNetwork #import <SystemConfiguration/CaptiveNetwork.h> 获取当前连接的wifi信息 // 只能获取当前的SSID ...

  8. 【Step By Step】将Dotnet Core部署到Docker下

    一.使用.Net Core构建WebAPI并访问Docker中的Mysql数据库 这个的过程大概与我之前的文章<尝试.Net Core—使用.Net Core + Entity FrameWor ...

  9. java中的作用域

    在说明这四个关键字之前,我想就class之间的关系做一个简单的定义,对于继承自己的class,base class可以认为他们都是自己的子女,而对于和自己一个目录下的classes,认为都是自己的朋友 ...

  10. 转发: Angular装饰器

    Angular中的装饰器是一个函数,它将元数据添加到类.类成员(属性.方法)和函数参数. 用法:要想应用装饰器,把它放在被装饰对象的上面或左边. Angular使用自己的一套装饰器来实现应用程序各部件 ...