决策树id3算法编程c语言,R语言实现决策树ID3算法

一、ID3算法

信息熵。信息熵是用来描述信息的纯度,或者确定性的。已经确定的东西,当然就没有什么信息可以发现了。越是确定的信息,这个值越小,如果信息是均匀分布,这个值就会很大。相反,要是都确定这个值就会很小。计算公式如下

0818b9ca8b590ca3270a3433284dd417.png

Pi 可以看作一个类别的概率。

信息增益。信息增益是指信息熵的有效减少量。熵变少了,不确定性就小了,我们就又收获了一点信息。也就是说信息增益越大,我们越能获得多的信息。具体来说计算公式如下

0818b9ca8b590ca3270a3433284dd417.png

决策树。要构建一棵决策树,要解决的问题就是当前找哪个变量来分类。有了信息增益这个概念,我们就可以选择信息增益最大的这个变量来分类。找出信息增益最大的变量,相当于有了一个节点。在该节点不同分支上,再递归的找信息增益最大的变量,最终就构成了一棵树。

二、举例说明

摘抄一个《数据挖掘概念与技术》中的例子:

0818b9ca8b590ca3270a3433284dd417.png

这是一张表。记录了人的ID,年龄,收入,是否是学生,信用等级和 这个人是否会购买电脑。共14条数据。我们先计算原本的信息熵。书中用的是H来表示:

0818b9ca8b590ca3270a3433284dd417.png     14是这里共有14条记录,其中5个人没买电脑,9个人买了。在当前这个集合中,信息熵就是0.94.

这时候我们开始计算各个变量的信息增益。从年龄开始。首先计算年龄为yonth的样本,把他们都抽出来,一共有5个人,其中买了电脑的2个没买的三个,在这种情况下的信息熵是

0818b9ca8b590ca3270a3433284dd417.png。然后再看年龄为middle_aged的人,他们所有人都买了电脑,如果按公式计算会发现log2(0)这样的错误,此时规定,如果碰到已2为底0为幂来求对数这样的错误情况,就把改项变为0 ,另外一项是 1*log2(1),这一项也为0 。 所以年龄为middle_aged这情况下,信息是100%确定的,此时熵为0. 再看年龄为senior的,计算结果和youth一样,都是0.971 。我们算出了年龄下每一种情况的熵,就可以计算年龄这个变量的信息熵了。

0818b9ca8b590ca3270a3433284dd417.png。有两个熵之后,相减就是信息增益

0818b9ca8b590ca3270a3433284dd417.png。类似的我们还可以计算其他几个信息增益Gain(income)=0.029,Gain(stduent)=0.151,Gain(credit_rating)=0.048。 增益最大的是年龄,所以我们选择年龄为第一个分类变量得到下图:

0818b9ca8b590ca3270a3433284dd417.png

按年龄分成了三组数据。我们递归的对每组数据做同样的事情,最终就会得到一棵树,如下图

0818b9ca8b590ca3270a3433284dd417.png

一棵树就构建出来了。

我们递归的停止条件。一是当前已经都分好类了,也就是信息熵为0,比如middle_aged这个子集,所有人都会买电脑,已经不需要再挖了。二是,我们已经没有变量再分了。比如不是学生有可能买也有可能不买,那么上面的树最左下角的no其实就是不确定的,这时候,我们要门增加数据量和变量。要么对这课树进行剪枝,认为不是学生这种情况下,都不会买。一般设置一个阈值,比如不是学生的人有80%的人都不买电脑,我们就把这个节点下的分支剪掉,当作不是学生就一定不买。

三、R程序编写

首先编写一些普遍的方法

#计算一列数据的信息熵

calculateEntropy 

sum 

entropy 

return(entropy)

}

#计算两列数据的信息熵

calculateEntropy2 

var 

varnames 

array 

for(name in varnames){

array 

}

return(sum(array*p))

}

开始遍历构建树

buildTree 

#如果熵为0,停止递归

if(length(unique(data$result)) == 1){

cat(data$result[1])

return()

}

#如果已经没有别的变量,但还不能完全分类,需要剪枝,这里简单处理一下。

if(length(names(data)) == 1){

cat("...")

return()

}

#开始计算

entropy 

labels 

label 

temp 

subentropy 

for(i in 1:(length(data)-1)){

temp2 

if(temp2 

temp 

label 

}

subentropy 

}

cat(label)

cat("[")

nextLabels 

for(value in unlist(unique(data[label]))){

cat(value,":")

buildTree(subset(data,data[label]==value,select=nextLabels))

cat(";")

}

cat("]")

}

使用如下数据,预测如何选择隐形眼睛的种类:lenses.txt 内容如下

young    myope    no    reduced    no lenses

young    myope    no    normal    soft

young    myope    yes    reduced    no lenses

young    myope    yes    normal    hard

young    hyper    no    reduced    no lenses

young    hyper    no    normal    soft

young    hyper    yes    reduced    no lenses

young    hyper    yes    normal    hard

pre    myope    no    reduced    no lenses

pre    myope    no    normal    soft

pre    myope    yes    reduced    no lenses

pre    myope    yes    normal    hard

pre    hyper    no    reduced    no lenses

pre    hyper    no    normal    soft

pre    hyper    yes    reduced    no lenses

pre    hyper    yes    normal    no lenses

presbyopic    myope    no    reduced    no lenses

presbyopic    myope    no    normal    no lenses

presbyopic    myope    yes    reduced    no lenses

presbyopic    myope    yes    normal    hard

presbyopic    hyper    no    reduced    no lenses

presbyopic    hyper    no    normal    soft

presbyopic    hyper    yes    reduced    no lenses

presbyopic    hyper    yes    normal    no lenses

data 

sep="\t",stringsAsFactors=F)

names(data) 

buildTree(data)

#tearRate[reduced :no lenses;normal :astigmatic[no :age[young :soft;pre :soft;presbyopic

#:perscript[myope :no lenses;hyper :soft;];];yes :perscript[myope :hard;hyper :age[young :hard;

#pre :no lenses;presbyopic :no lenses;];];];]

程序会输出下面的字符串,稍微整理一下(好吧是大整),就得到了树结构:

tearRate[

reduced :no lenses;

normal :astigmatic[

no :age[

young :soft;

pre :soft;

presbyopic :perscript[

myope :no lenses;

hyper :soft;]

;];

yes :perscript[

myope :hard;

hyper :age[

young :hard;

pre :no lenses;

presbyopic :no lenses;

];

];

];

]

0818b9ca8b590ca3270a3433284dd417.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值