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分支下,所有的样本都属于同一个分类,因此该节点为叶子节点。

最终的分类树为:

 

猜你喜欢

转载自www.cnblogs.com/wxyz94/p/8977264.html