R语言简单实现决策树算法

640?wx_fmt=jpeg

常用的分支准则方法有三种:信息增益、信息增益率、基尼系数。其实,这里问题就来了,决策树是可以不加限制的生长到有可能到很深的吗?当然是不行的,这就是这一节需要介绍的主要内容之一决策树的修剪,当然还会对决策树算法规律稍微总结一下,并用几个小例子说明R语言的具体实现。


01

决策树的修剪

单单根据决策树算法完成树的建立后,各个叶节点代表不同的种类,部分叶节点可能只包含少数样本,有可能还是一些异常数据,没有足够的支持度,增加了树的深度,过度适配也会导致分类错误率的增加。这就需要修剪决策树,原理是:从树的底部开始,检查每个节点和该节点的子决策树,看是否能将该子决策树去掉而该节点就自然成为了叶节点代替原来的子决策树,生成一个分类错误率更低、树的深度更低的决策树。

决策树的修剪分为

  • 事前修剪

  • 事后修剪

顾名思义,事前修剪就是在决策树的生长过程中,比如叶节点中数据数要大于3或者信息增益值要大于一个事先设定的阈值;否则,就停止分支。事后修剪就是在树的生长完成后进行修剪,引入测试组样本来验证决策树对于新输入数据的分类与预测结果。事后修剪法较前者效率略微低下,但可避免产生稀疏叶节点,对噪声的忍耐程度也更强。这里我们主要介绍事后修剪法。

事后修剪法考虑成本复杂度,我们以R(t)代表t为起始节点的决策树分类错误率。给定一个复杂系数a可以理解为代表决策树节点个数的影响,因为我们定义他们是正比例关系的,再给定一个未修剪的节点t,就可以将一决策树成本复杂性定义为决策树节点个数与分类错误率的函数Ra(t)。

640?wx_fmt=png

 Ai表示节点A的所有直接一级子节点,就不要往下深入了,m表示节点A的直接一节子节点个数,|Aierror|表示子节点Ai分类错误的样本数,|Ai|表示子节点 Ai的样本总数.这里Nleaf表示叶子节点个数,就是m。若有一个节点产生分支,在给定复杂系数a下,若分支后的成本复杂度大于分支前的成本复杂度,则进行剪枝,还是用上篇文章数据那个小例子加以说明。

640?wx_fmt=png

职员表现决策树(未修剪)

将其用Gini系数构建的未经修剪的完整的决策树,共有10个样本,11个叶节点。可以根据节点中哪种类别数据的数量最大决定类别,比如ID = 10的叶子节点,由于其包含2个优秀,一个普通,最终判别为“优秀”。如下

640?wx_fmt=png

拿ID = 8的节点为例,如果剪枝剪掉节点10、11,造成的错分成本为:

R(t = 8) = 1/4*(4/10) = 0.1

若未删除节点10、11,给定复杂系数a = 0.01下,节点8的叶节点个数Nleaf = 2,产生的加权平均分类错误率如下:

Ra(t = 8)=R(t = 8)+axNleaf

= (1/3*(3/10)+0)+0.01*2=0.12

注意:这里上一式的R(t = 8)与二式的R(t = 8)是不一样的,前者经过剪枝,直接算,后者因为没有剪枝,是一个加权平均分类错误率,需要根据子节点错误率进行占比加权。

由于,Raa(t = 8)>R(t = 8),所以需要进行剪枝。再拿节点5为例,前面强调过,虽然它有孙子节点,但我们只看直接子节点。

那么,同理

R(t = 5) = 1/5*(5/10) = 0.1

Ra(t = 5)=R(t = 5)+axNleaf

=(1/4*(4/10)+0)+0.01*2 = 0.12

同样,Raa(t = 5)>R(t = 5),所以需要进行剪枝。

最终剪枝结果是:把8、9、10、11这四个节点修剪了,形成了最终的决策树。

02

决策树规则提取

完成决策树的生长、修剪后,我们最终目的是需要利用决策树帮助我们做出决策,那么就需要决策树规则的提取。

主要步骤:从根节点出发,利用IF-THEN规则,走完每条到叶节点的路径,提取分类规则模型。

比如,从上面的决策树我们可以提取出规则:

IF
THEN

若学历为大专

表现为普通

若学历为研究所且资历小于5年

表现为优等

若学历为研究所且资历为10年以上且有相关经验

表现为优等

若学历为研究所且资历为10年以上且无相关经验

表现为普通

这就把决策树规则提取出来了,遇到含有较少样本的规则,可以选择在上级节点直接合并,使其更加轻量、耐用。

03

决策树算法小结

查了一些资料,常用的决策树算法分支原理以及它们分别适合做分类的数据类型小结如下:

640?wx_fmt=png

CART以Gini系数作为决定分支变量的准则,C4.5/C5.0以信息增益比作为决定分支变量的准则,CHAID是AID算法的延伸,它是根据卡方检定统计量的显著性检定,决定最佳的分支属性。

04

R语言小例子

R语言有一个决策树常用的一种包"rpart",这里用的是R语言里面help('rpart')的内容,用的数据是脊椎后凸儿童的矫正手术结果数据集(kyphosis),大概就是这么个意思(英语不太好!),旨在说明R语言实现决策树还是很方便的。

这个例子,在R里面help('rpart')命令是可以出来的。

我们首先看一下这份数据1

1> head(kyphosis)
2  Kyphosis Age Number Start
31   absent  71      3     5
42   absent 158      3    14
53  present 128      4     5
64   absent   2      5     1
75   absent   1      4    15
86   absent   1      2    16

有一个变量名叫Kyphosis,首字母大写,与数据集名kyphosis(首字母小写)不要混淆。我们可以猜到,用好像可以作为因子变量的第一列(实际是手术成功与否结果)作为目标变量,构建决策树模型!

代码很简单,如下:

 1rm(list = ls())
 2library(rpart)
 3attach(kyphosis)
 4#不加复杂系数限制模型
 5fit <- rpart(Kyphosis~Age+Number+Start)
 6#加复杂系数限制模型
 7fit2 <- rpart(Kyphosis~Age+Number+Start,control = rpart.control(cp = 0.05))
 8par(mfrow = c(1,2),xpd = NA)
 9plot(fit,main = '不加复杂系数限制')
10text(fit)
11plot(fit2,main = '加复杂系数限制')
12text(fit2,use.n = TRUE)

这样就构建了一个以变量Kyphosis(第一列)为目标变量的决策树模型,fit与fit2的区别,在于是否加复杂因子限制,加了复杂因子可能会剪枝,使决策树更简洁。这里也可以这样写

1fit2 <- rpart(Kyphosis~.,data = kyphosis,control = rpart.control(cp = 0.05))

只是省略分支变量,加上data = kyphosis指定应用到kyphosis这个数据集上,用"."代替一长串变量名,可以自动识别目标变量,就是指定的"~"前面的变量。

最终画出的两棵决策树如图:


640?wx_fmt=png

猜你喜欢

640?wx_fmt=jpeg

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大数据技术派

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值