决策树算法
决策树的创建
创建决策树的问题可以用递归的形式表示:
1、首先选择一个属性放置在根节点,为每一个可能的属性值产生一个分支:将样本拆分为多个子集,一个子集对应一种属性值;
2、在每一个分支上递归地重复这个过程,选出真正达到这个分支的实例;
3、如果在一个节点上的所有实例拥有相同的类别,停止该部分树的扩展。
问题:对于给定样本集,如何判断应该在哪个属性上进行拆分?每次拆分都存在多种可能,哪个才是较好的选择呢?
理想情况:在拆分过程中,当叶节点只拥有单一类别时,将不必继续拆分。
目标时寻找较小的树,希望递归尽早停止。
当前最好的拆分属性产生的拆分中目标类的分布应该尽可能地单一,多数类占优。
如果能测量每一个节点的纯度,就可以选择能产生最纯子节点的那个属性进行拆分;
决策树算法通常按照纯度的增加来选择拆分属性。
纯度的概念
纯度度量:
当样本中没有两项属于同一类:0;当样本中所有项都属于同一类:1。
最佳拆分可以转化为选择拆分属性使纯度度量最大化的优化问题。
纯度的度量:
拆分增加了纯度,但如何将这种缓增加量化呢,或者如何与其他拆分进行比较呢?
用于评价拆分分类目标变量的纯度度量包括:
基尼(Gini,总体发散性) CART
熵(entropy,信息量)
信息增益(Gain)
信息增益率 ID3,C4.5,C5.0
改变拆分准则(splitting criteria)导致树的外观互不相同
决策树的停止:
决策树是通过递归分割建立而成,递归分割是一种把数据分割成不同小的部分的迭代过程。
如果有以下情况发生,决策树将停止分割:
该群数据的每一批数据都已经归类到同一类别。
该群数据已经没有办法再找到新的属性来进行节点分割。
该群数据已经没有任何尚未处理的数据。
决策树剪枝
决策树学习可能遭遇模型过度拟合的问题,过度拟合是指模型过度训练,导致模型记住的不是训练集的一般性,反而是训练集的局部特性。
树的修剪有几种解决的方法,主要为先剪枝和后剪枝方法。
先剪枝的方法
在先剪枝方法中,通过提前停止树的构造而对树“剪枝”。一旦停止,节点成为树叶。
确定阈值法,测试组修剪法。
后剪枝的方法
后剪枝方法是由“完全生长”的树剪去分枝。通过删除节点的分支,剪掉叶节点。
案例数修剪,成本复杂性修剪法。
决策树1:
install.packages("rpart")
library(rpart)
trIn <- c(sample(1:50,40), #训练集序号
sample(51:100,40),
sample(101:150,40))
traiD <- iris[trIn,] #训练集样本
textD <- iris[-trIn,] #测试集样本
#fit = rpart(Species~., traid, method='class')
fit <- rpart(Species~Sepal.Length+Sepal.Width+Petal.Length+Petal.Width,
data=traiD,method="class")
re <- predict(fit,textD)
re <- cbind(re,rep(1,nrow(re)))
tab <- colnames(re)
for(i in 1:nrow(re)){
re[i,4] <- tab[which.max(re[i,1:3])]
}
result <- re[,4]
table(textD[,5],result)
决策树2:
library(rpart)
par(family='STXihei')#图形设置,以免出现中文乱码
#fit <- rpart(Species~Sepal.Length + Sepal.Width + Petal.Length
# data = iris,method="class")
fit = rpart(Species~.,iris,method = 'class')
#method:根据树末端因变量的数据类型选择分割方法
par(mfrow=c(1,2))
plot(fit,uniform=T,branch=0,margin=0.2,main='Classificat')
text(fit,use.n=T,fancy=F,col="blue")
#这种会更漂亮一些
install.packages("rpart.plot")
library(rpart.plot)
rpart.plot(fit,branch=1,branch.type=2,type=1,extra=102,
shadow.col="gray",box.col="green",
border.col="blue",split.col="red",
split.cex=1.2,main="Kyphosis决策树")
printcp(fit)
par(mfrow=c(1,1))
#第二种方式
install.packages("rattle")
install.packages("RColorBrewer")
library(rpart)
library(rattle)
library(rpart.plot)
library(RColorBrewer)
model <- rpart(Species ~ Sepal.Length +
Sepal.Width + Petal.Length +
Petal.Width,data = iris, method = "class")
fancyRpartPlot(model)