分类算法3:决策树及R语言实现

注:(及本人的一些学习感悟)本文是通过参考李航老师的《统计学习方法》总结的,其中的一些插图也来自该书,非常感谢李航老师的这本书,让我对机器学习有了一个很清晰的认知。之前学任何东西都三心二意,很容易放弃,《统计学习方法》是bn学姐介绍给我的,刚开始看的一头雾水,果断放弃了,认为这本书是浪费我美好的青春年华,后来发现所有的书都是浪费我美好的青春年华,于是我把我的这种感受告诉了班主任:wz老师,他简单的对我说了四个字:书怕三磨,当时真是觉得好丢人,于是静下心来读了本书中的一些内容,对机器学习有了一个初步的认识,后来又读了第二遍,如今是第三遍读此书,已经深深的被李航老师深入浅出的解释震撼了,同时也验证了wz老师的那四个字,也让我对学习这件事有了更加深刻的认识。

正文

决策树是一种基本的分类与回归方法,这里只介绍用于分类的决策树。前面已经说过,只要是分类,它的本质就是出发于特征,结束于类别。

决策树主要3步骤:

step1:特征选择;
step2:决策树的生成;
step3:决策树的修剪。

决策树思想主要来源于由Quinlan在1986年提出的ID3算法和1993年提出的C4.5算法,以及有Breiman等人在1984年提出的CART算法。本文主要介绍前两个算法的生成树!

决策树定义:
分类决策树模型是巴拉巴拉一大堆,主要挑点有用的说一说。决策树由节点(node),和有向边(directed edge)组成。节点又由两种类型:内部节点(internal node)和叶节点(leaf node)。内部节点表示一个特征或者属性,叶节点表示一个类。

下面来结合图形来理解决策树的伟大思想吧!!!!

在这里插入图片描述
圆表示内部节点,方框表示叶节点。
决策树的工作机制:从根节点出发,对数据的某一特征进行测试,根据测试结果,将数据分配到其子节点,这时,每一个子节点对应着该特征的一个取值,如此不断递归,直到达到叶节点为止,最后将数据分到叶节点的类中。

决策树学习
之所以加黑,是因为重要啦!
还和之前一样,两个必不可少的向量:(1)特征向量;(2)类别向量.
决策树学习的目的是根据训练集构造一个决策树模型,使它能够对数据正确分类。
但是这里存在一个问题,就是能对训练数据集正确分类的决策树可能会有很多个,也可能一个也没有,所以我们的目的就是要得到一个与训练数据集矛盾较小,同时具有很好的泛化能力的决策树。
决策树学习用损失函数表示这一目标,在理论中,我们通常用到的损失函数有平方损失函数,绝对损失函数和0-1损失函数。当损失函数确定以后,学习问题就变为在损失函数意义下选择最优决策树的问题。决策树学习的算法通常是一个递归的选择最有特征,并根据该特征对训练数据集进行分割,使得对各个子数据集有一个最好的分类的过程,这一过程对应着对特征空间的划分,也对应着决策树的构建。
下面是这一算法的详细过程:

start:构建根节点(将所有数据都放在根节点,选择一个最优的特征,按照这一特征将训练数据集分割成子集,使得各个子集有一个在当前条件下最好的分类)
then:如果这些子集已经能够基本被正确分类,那么构建叶节点,并将这些子集分到所对应的叶节点中去;
then:如果还有子集不能被基本正确分类,那么就对这些子集选择新的最优特征,巴拉巴拉,继续上述步骤~
end:最后,每个子集都被分到叶节点上,即都有了明确的类,这就生成了一颗决策树!

看上去是不是觉得很完美呢?哈哈,别忘了,这只是对训练集而言,分类效果特别好,如果对于测试集,那可就未必了。(通常会出现过拟合现象,所有就有了大家熟知的剪枝操作)。

什么是剪枝呢?下面详细介绍:
剪枝就是对决策树自上而下进行修剪,让树变得简单,从而使它具有更好的泛化能力。具体来说,就是去掉过于细分的叶节点,使其回退到父节点,甚至更高的节点,然后将父节点或者更高的节点改为新的叶节点。
如果特征数量很多,也可以在决策树学习开始的时候,对特征进行选择,只留下对训练数据有足够分类能力的特征。
由于决策树表示一个条件概率分布,所以深浅不同的决策树对应着不同复杂程度的概率模型。决策树的生成对应于模型的局部选择,决策树的剪枝对应于模型的全局选择,。决策树的生成只考虑局部最优,决策树的剪枝要考虑全局最优。

决策树学习常用的算法上面已经提过,即:ID3、C4.5与CART,下面介绍前两个算法~

两个问题:
(1)特征选择的;
(2)决策树生成
下面来解决这两个问题:
先来解决第一个问题:
通常特征选择的准则是信息增益或信息增益比。
为了便于说明,先给出熵与条件熵的定义:
:在信息论与概率论中,熵是表示随机变量不确定性的度量,设X是一个取有限个值的离散随机变量,其概率分布为:
P ( X = x i ) = p i , i = 1 , 2 , . . . , n . P(X=x_i)=p_i,i=1,2,...,n. P(X=xi)=pi,i=1,2,...,n.,则随机变量 X X X的熵定义为:
H ( x ) = − ∑ i = 1 n p i log ⁡ p i H(x)=-\sum_{i=1}^{n}p_i\log{p_i} H(x)=i=1npilogpi
显然,熵越大,随机变量的不确定性就越大!
条件熵:条件熵 H ( Y ∣ X ) H(Y|X) H(YX)表示在已知随机变量 X X X的条件下随机变量 Y Y Y的不确定性。
H ( Y ∣ X ) = ∑ i = 1 n p i H ( Y ∣ X = x i ) H(Y|X)=\sum_{i=1}^{n}p_iH(Y|X=x_i) H(YX)=i=1npiH(YX=xi)
信息增益表示得知特征 X X X的而使得类 Y Y Y的信息的不确定性减少的程度。
定义:信息增益特征A对训练数据集D的信息增益 g ( D , A ) = H ( D ) − H ( D ∣ A ) g(D,A)=H(D)-H(D|A) g(D,A)=H(D)H(DA).
通常,熵与条件熵之差称为互信息,决策树学习中的信息增益等价于训练数据集中类与特征的互信息。
决策树学习应用信息增益准则选择特征,显然,对于D来说,信息增益依赖于特征,不同的特征往往具有不同的信息增益,信息增益大的特征具有更强的分类能力。故:
根据信息增益选择特征的方法是:对训练数据集D,计算其每个特征的信息增益,并比较他们的大小,选择信息增益最大的特征。

信息增益比
特征A对训练数据集D的信息增益比 g R ( D , A ) g_R(D,A) gR(D,A)定义为:
g R ( D , A ) = g ( D , A ) H ( D ) g_R(D,A)=\frac{g(D,A)}{H(D)} gR(D,A)=H(D)g(D,A)

上述工作终于完成了我们的第一步:特征选择工作。(写的手累~~,但是很有动力哦,谁让我是一个求知若渴的好孩纸呢^^)

加下来开始万里长征第二步:决策树的生成。

用上面提到的两种算法:ID3、C4.5算法分别生成决策树!

ID3算法
该算法的核心是在决策树各个节点上应用信息增益准则选择特征,递归地构建决策树。
具体方法:从根节点开始,对节点计算所有可能的特征的信息增益,选择信息增益最大的特征最为节点的特征,由该特征的不同取值建立子节点,巴拉巴拉,开始递归!
在这里插入图片描述
从上图,我们可以看出,它只有两个内部节点。
C4.5算法
C4.5算法是ID3算法的改进,它是用信息增益比来选择特征的。

不论是C4.5算法还是ID3算法,它们只有树的生成,没有树的剪枝,所以非常容易出现过拟合。
好了,万里长征第二步也走完了,距离成功之差一步之遥,此时必须要有耐心!

万里长征第三步----决策树的剪枝
上述已经讲过为什么要剪枝,这里就不在多说,直接上干货。
决策树的剪枝往往通过极小化决策树整体的损失函数来实现。设树 T T T的叶节点个数为 ∣ T ∣ |T| T t t t是树的叶节点,该叶节点有 N t N_t Nt个样本点,其中 k k k类的样本点有 N t k N_{tk} Ntk个, k = 1 , 2 , . . . , K k=1,2,...,K k=1,2,...,K H t ( T ) H_t(T) Ht(T)为叶节点 t t t上的熵, α ≥ 0 \alpha \geq 0 α0为参数,则决策树学习的损失函数可定义为:
在这里插入图片描述
其中, C ( T ) C(T) C(T)表示模型与训练的拟合程度, ∣ T ∣ |T| T表示模型的复杂度,参数 α \alpha α控制两者之间的影响。较大的 α \alpha α促使选择较简单的树,较小的 α \alpha α促使选择较复杂的树, α = 0 \alpha=0 α=0意味着只考虑模型与训练数据的拟合程度,不考虑模型的复杂度。剪枝就是当 α \alpha α确定时,选择损失函数最小的模型,即损失函数最小的子树。当 α \alpha α确定时,子树越大,往往与训练数据的拟合效果较好,但是模型复杂度就越高,相反则反之。损失函数正好表示了对两者的平衡。在其他领域中,也经常会碰到类似的问题,如本人最近在做的非参数统计中的一个关于窗宽(带宽)选择的问题,当窗宽较小时,偏差会减小,相反则反之,在这里我们通常用均方误差MSE来刻画两者的变化程度, M S E = V a r + B i a s 2 MSE = Var + Bias^2 MSE=Var+Bias2,后续会陆续更新一部分非参数与半参数统计方面的理论知识,其在机器学习中也有着很广泛的作用。之前有写过一篇核函数的初步认识的博客,点击这里就可以查看哦
好了,言归正传,可以看出,决策树生成只考虑了通过提高信息增益或信息增益比对训练数据集进行更好的拟合,而决策树的剪枝通过优化损失函数还考虑了减小模型复杂度,决策树的生成学习局部的模型,决策树的剪枝学习整体的模型。

树的剪枝算法:
输入:生成树算法产生的整个树 T T T,参数 α \alpha α
输出:修剪后的子树 T α T_{\alpha} Tα.
(1)计算每个节点的熵;
(2)递归地从树的叶节点向上回缩.
在这里插入图片描述
下面通过上述的理论公式来解释这棵树的修剪过程。设一个叶节点回缩到其父节点之前与之后的整体书分别为 T B T_B TB T A T_A TA,其对应的损失函数值分别是 C α ( T B ) C_{\alpha}(T_B) Cα(TB) C α ( T A ) C_{\alpha}(T_A) Cα(TA),如果, C α ( T A ) ≤ C α ( T B ) C_{\alpha}(T_A)\leq C_{\alpha}(T_B) Cα(TA)Cα(TB),则进行剪枝,即将父节点变为新的叶节点。依次递归得到损失函数最小的子树作为我们最终的决策树。

R语言实现
这里依旧是用鸢尾花数据集。(下面的R程序参考自开心果汁的CSDN博客,链接详见参考文献【2】)。

这里我们使用了R的party包,party包使用的理论方法与上述有所差异。算了,还是先给出程序再详细解释吧~

##  决策树的生成,以鸢尾花数据集为例

## 加载包

library(party)
library(grid)
library(mvtnorm)
library(modeltools)
library(stats4)
library(strucchange)
library(zoo)

## 鸢尾花数据集

iris

##  构建训练集和测试集

train_ord <- sample(nrow(iris),120,replace = FALSE)
train <- iris[train_ord,]
test <- iris[-train_ord,]

##  构建树

tree <- ctree(Species ~., data = train)

##检测预测值

preTable <- table(predict(tree), train$Species)

##准确率----0.9583333

accurary <- sum(diag(preTable))/sum(preTable)

##画决策树

plot(tree)
plot(iris_ctree, type="simple")  ## 简化决策树
## 在测试集上测试决策树

testPred <- predict(tree, newdata = test)
preTatable1<-table(testPred, test$Species)

##准确率------0.9666667

accurary<-sum(diag(preTatable1))/sum(preTatable1)

运行结果:

在这里插入图片描述
从运行结果可以看出,训练集中的38个setosa均预测正确,41个versicolor中有37个预测正确,有4个预测为virginica,在41个virginica中,有40个预测正确,1个错误预测为versicolor。我们计算了其准确率为0.9583333。(公式:预测正确的样本数/样本总数)

依据训练集画出的决策树如下:
在这里插入图片描述
简化后的决策树:
在这里插入图片描述
如果第一棵树看的有点云里雾里,不如来看第二棵简化后的树,(注:这里的简化不是剪枝,上述没有进行剪枝工作,该包也无需剪枝工作!)
(看结果看叶节点就可以了,无需看内部节点)首先,节点2直接把所有的38个setosa都预测正确了,并且给出了其正确率为1,其他两个都为0;节点7给出了37个样本中有0.027被错误预测为versicolor,0.973真确预测为virginica,节点5,6是同样的道理,我们不妨来简单计算一下:
370.027=0.999=1;
37
0.973=36.001=36;
380.974=37.012=37;
38
0.026=0.988=1;
70.429=3.003=3;
7
0.571=3.997=4.
将它们按类别加起来:
setosa:38=38;刚好是setosa的样本量;并且全部分类正确!
versicolor:36+1+4=41,刚好是virginica的样本量;40个正确,1个错误,因为4个的概率大于0.5!
virginica:1+37+3=41,刚好是virginica的样本量;37个正确,4个错误!

接下来,在测试集上测试了生成的决策树,结果如下:
在这里插入图片描述
从运行结果可以看出,12个setosa全部预测正确;9个versicolor有8个预测正确,1个错误预测为virginica;9个virginica全部预测正确!
其预测准确度为:0.9666667

需要说明的是,使用party包无需剪枝,其理论与上面讲述的理论有所差异,但是殊途同归,R中除了party包外,还有rpart包,该包是基于上述理论的,故需要有剪枝工作,方便起见,这里使用了前者。

满足大家的好奇心!!!

我想,对于大多数孩子,从小到大,一直被父母家人以及其他人拿来与 别人家的孩子做比较。反正我是一直比不过别人家的孩子的,小时候比学习比不过,现在比找女朋友也比不过~~俱往矣,数风流人物,还看别人家的孩子。开玩笑,其实也不能怪父母这些人,比较仿佛是人类与生俱来的天性,别忘了,小时候我们也经常和别人家的孩子比玩具的!
铺垫了这么多,我就是想拿决策树和k近邻,以及朴素贝叶斯做个比较辣!想必这才是这篇文章最吸引人的地方!同样的数据集,同样大小的训练集和测试集,看看哪种方法在这个数据集上效果比较好吧!

朴素贝叶斯结果:
在这里插入图片描述
准确率:(13+8+8)/30=0.9666667 = 决策树准确率

k近邻结果:

在这里插入图片描述
好了,随便一算,k近邻的准确度居然是1!

总结:不同的算法,其实并没有绝对的好坏之分,在实际生活中选择算法时,我们要考虑诸多因素,如数据量大小,机器的优良性等等!

ok,决策树到此暂时为止,希望能对大家有所收获,后续有空会陆续更新上面提到的rpart包,以及party包更详细的介绍!



参考文献
【1】李航,统计学习方法,清华大学出版社.
【2】开心果汁,CSDN,url:https://blog.csdn.net/u013421629/article/details/77720318+

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值