当前课程知识点:R语言数据分析 >  下部:博术 >  第12章 既是世间法、自当有分别 >  12.5 决策树(II)

返回《R语言数据分析》慕课在线视频课程列表

12.5 决策树(II)在线视频

下一节:12.6 随机森林

返回《R语言数据分析》慕课在线视频列表

12.5 决策树(II)课程教案、知识点、字幕

大家好

欢迎来到《R语言数据分析》课程

今天继续和大家交流决策树相关的内容

在我们前面课程里面讲到了

当我一棵完全生长了决策树

因为它太过茂密的时候

很多属性考虑太多 分枝太多

这个时候容易怎么样

容易产生过拟合的现象

就是对我这个训练集来讲

它可能是很准确的

但是它的推广泛化能力可能相对比较差了

这个时候我们就涉及到决策树剪枝的过程

好 我们看看所谓决策树剪枝是什么意思

这是一个我们已经生长好的树

所谓剪枝的话它相当于什么

相当于把某一些子树

比如说这都是子树对吧

都是子树

将某些子树

我收缩为一个节点

比如说现在我们这里面一直往下

细分 细分 细分……

一直往这里细分的时候

我细分到这个节点的时候

我还要继续细分什么

看看我这个数学是否是大于等于92

是的话是理科

否的话是文科

假如剪枝的话怎么剪

到这一步我就不再做分裂了

我直接判断什么

直接判断我这个相应的节点类标签就是文科

好 同样的

假如你在往上剪枝的话

将这一部分再继续怎么

这个子树继续收缩为一个节点

或者说再往上走

这其实(就)是所谓决策树剪枝的过程

就将子树收缩为一个节点这么一个过程

我们前面讲到了所谓决策树剪枝的目的

是为了提高它的泛化能力

对于我新的未来的测试集

我同样是有更好的性能的

也就要求我们这个模型不要太复杂

也就所谓的结构风险最小化

我们可以定义一个[代价]函数

它由两部分组成

第一部分就是我这个[模型]本身的一个误差

第二部分

用来衡量我这个模型的复杂程度

当然对一棵树模型来讲

它有很多衡量它的复杂程度的方法

比如我的层级

比如我结点的个数

当然我们这里面

通过叶子结点的个数

来衡量整个模型的复杂度

好 这两部分相加的时候

我们有一个权值是α

毫无疑问 这个α是什么呢

α是用来权衡这个拟合程度

和这个模型复杂度的就平衡它们

当我的α比较小的时候

那我其实

倾向于我这个树相对是比较茂盛一点

当我这个α比较大的时候

为了实现我这个[代价]函数最小

那我这个树相对比较小一点好

极端的情况之下

比如α等于0的时候

毫无疑问我整个这个树就整体树应该是最优的

用通过这个损失函数

我们这个目标函数来讲的话

就整体树应该最优

但假如我这个α不断增加 不断增加

增加得非常大的时候

大到某一个程度

或者说比如说我这个α取无穷的时候

毫无疑问那怎么样

我这个时候应该就是单个节点应该就是最优的

我就不再做任何分裂

这个时候我复杂程度最小对吧

所以我们针对不同的α

我这边整个最好的树它有不同的最优子树

但应该说更准确的讲应该

是α落入不同的区间的时候

它对应着不同的最优子树

这什么意思呢

因为我这个α在增加的时候

比如从0增加到0.0001

然后从0.0001继续往上增加的时候

并不是每增加一个值 一个微小值

然后我这边都就直接导致我这边要剪掉某一个分支

而是说什么它大到一定程度的时候

比如由α等于零的时候变成α1的时候

这时候我才需要剪掉某一个分枝

剪掉某个子树

从而保证我这个损失函数是最小

我们看一看

具体的例子

还是以我们这个决策树为例

我们现在有不同的α的取值

我们把它放到一个数轴上面来

毫无疑问刚开始这个点是一个α=0

这个时候我整个整体树是最优的

然后我这个α不断往这边增长

α的值不断增加的时候

为了保证我这个损失函数最小

这个目标函数最小

那怎么样呢

我增加增加增加一定程度

比如说这个增加到α1的时候

我就需要剪掉一部分的树

这时候我这个复杂度

因为它剪枝完之后复杂度减小

我相应的这个损失函数是最小的

也就是说这个时候我在哪

我在0到α1之间

这个时候是整体树最优的

当我一旦达到α1之后

再下一个值之前

我把这棵树减掉之后它是最优的

而且把这部分收缩为一点

这个子树是最优的

同样假如我这个α继续增大的话

增加到α2

那毫无疑问我这个时候

我这一部分还得

继续剪 继续收缩为一个节点

也就说在这个α2到

未来的一个节点α3之前

这个树

应该收缩完之后收缩成这么一棵树的时候

它应该是一个最优子树

就相对我们前面定义的这个损失函数来讲

同样我要再继续往上增加的时候

我这一块可以继续收缩

所以我们可以看得出来

它其实在不同的区间里面

对应着不同的最优子树

那这个时候其实我们就

从零增加到无穷大的时候

我并不需要考虑遍历

从零到无穷大的所有数值

而是 其中有若干个

若干个端点若干个切分点

切分成不同的区间

在不同区间里面生成了不同的最优子树

那我想找到最终性能表现最好的那棵怎么办

我再把所有这个子树这么多一个集合

说一个子树的序列进行一个交叉验证就可以

看看哪个子树它的泛化性能最好

那我就最终把那一棵树作为什么

作为我剪枝之后的树

好 那这个α除了α0之外

α1 α2 α3一直到αn

我如何确定呢

是需要我人工来确定吗

不需要

它是结合这棵树本身 结合这个数据信息本身

我可以确定他

咱们看看具体过程

对我们T0这个完全生长的树

它内部的任意节点T

假如说我把这个节点这个相应的子树

我收缩成一个节点的话

就是说以T为单节点的树的损失函数

我们可以这样定义

按照我们刚才的损失函数

一个是这个错误率

一个表示这个复杂程度的

好 因为这个时候它只有一个节点

毫无疑问这个叶子节点的个数就是1

所以α后面没有了

只有一个α对吧

假如这个相应这个内部节点

以及它相应的这个子树我不收缩的话

那它相应损失函数是多少

这个Cα(Tt)当然也是包含两部分

一部分是表示这个错误率

另外一部分表示这个复杂程度

也就是这个子树没有收缩的时候

它叶子节点的个数

好 我们现在比较这两个损失函数

就这个Cα(Tt)和Cα(t)

假如我们这个α比较小

甚至说这个α为零的时候

毫无疑问谁更小一点

应该是Cα(Tt)更小一点

当我这个α充分小的时候

毫无疑问是Cα(Tt)是小于Cα(t)

但是假如我这个α不断增加

α 不断增大的时候

毫无疑问怎么样

增加到某一个α的时候

这个Cα(Tt)就和Cα(t)相等

假如我再进一步增加的话

毫无疑问它就反向

这个不等式就反向了

好 我们现在关注一下

当取α某个值的时候

Cα(Tt)等于Cα(t)

等于这个时候也就说我

我令这个α等于下面这个公式

这两个相等的时候

我把这两个式子相减

左右相减毫无疑问就可以得到

相应的α可以求出来

好 当我α取这个值的时候

我们可以考虑一下

我们这个时候是否应该剪枝

这两棵树 一个是生长的 一个是收缩的

这两棵子树

毫无疑问

当它的损失函数相等的时候

我肯定要

我肯定要取

取这个相对比较简单的那棵

按照这个奥卡姆的剃刀原理

那好 假如我有一个相同的损失函数(取值)

然后剪完了之后

也就收缩成一个节点之后的怎么样

它的结点数更少

毫无疑问

我应该剪枝

因为这个为单节点的数是更可取的

也就是说这个时候的α

当α增加到这个值的时候

从零慢慢增加慢慢增加

一直增加到什么

C(t)-C(Tt) 然后除以|Tt|-1

当它增加到这个时候

毫无疑问我就可以剪掉相应的这棵子树了

好 这是我们对于某个节点来讲是这样的

那好假如我面对所有的

面对我整个这个生长树里面任意节点的话

我来怎么剪 具体剪的过程我们再看一下

我对任意节点我先计算一下

就令刚才这个α等于多少

将它定义为g(t)

将它定义为g(t)

我将所有的节点的这个g(t)我都算出来

除了叶子节点之外的所有的内部节点我都算出来

算完之后因为我这个α的从小往大增加

然后我根据它增加的到

α1到α2到αn的时候

我分别来进行

得到相应的最优子树

然后进行剪枝

那好毫无疑问

我这个内部节点里面

我可以找到一个最小的那一个

找到g(t)最小的那一个

找到它之后我怎么样

我将它收掉

将那个子树

剪完之后

我令剪完之后的那个树

为T1

毫无疑问这个T1

它是当这个α1

当这个α1

当α的取值大于等于α1的时候

怎么样这个T1

毫无疑问属于这个最优子树

假如是α0的话

α0到α1之间

这个时候还是完全生长的树是最好的

然后它增加增加增加增加到α1的时候

毫无疑问应该T1是最好对不对

那好可以

可以继续增加α继续增长的时候

那毫无疑问

我将那个T1作为新的一棵树

针对这个T1来讲

我再计算里面

它的内部的任意节点

它的相应的

这个g(t)的值

再找出一个最小的一个

再进行剪枝

再收缩成一个单个节点

那这个时候相应的α就是什么

就是α2了对不对

那这个时候α2

它对应的这个区间里面

所对应的这个最优子树是谁

就是T2 对不对

所以按照这个步骤不断的这样剪枝下去

当然它是有限的

因为它内部节点数也是有限

毫无疑问怎么样

我就可以得到什么

T0 T1 T2 Tn

得到有限个最优子树的序列对吧

这就和我们刚才讲到的这个

相应的α0是0

因为刚开始已经有了

就是直到α1 α2 一直到αn

相对应的最优子树序列求到了

一旦得到这个最优子树之后

也就是说α取值不一样的时候

我所有的最优子树我都知道了

那好

一直剪下去之后

我得到了这么一个相应的α的序列

也得到一个相应的子树的序列

最后我就通过一个交叉验证的方法来看一看

究竟哪一个子树泛化能力是最强的

测试误差是最小的 就可以了

当然 这个时候怎么办

我们可以看得出来

机器学习里面 到后面做选择的时候

很大一部分都是 通过实验的方法

而不是一个纯粹理论推导的方法来计算

好 这是一个剪枝的方法

就是通过代价复杂度 通过定义这么一个函数

一个损失函数 来进行剪枝

我们看看具体算法

输入的时候是一个完全生长的一个决策树T0

然后我要输出的话就是要剪枝之后的

一个决策树Tα

我有这么几个步骤

具体要做剪枝的话

首先是设K=0

这个时候 T=T0了

当前这个数是T等于T0

并且我令这个α等于无穷大

自下而上对内部的各个节点计算

我们刚才这个g(t)

也就这个我们想得到这个α的值

计算一下

将这个α的值设为什么

设为所有节点里面最小的那一个

然后怎么样

我对这个g(t)等于α的这个内部节点进行剪枝

并且按照这个叶子结点的个数

少数服从多数的原则

这里边又回到我们

之前讲到的有生于无

通过“少数服从多数”方式来进行

叶子节点的标签的表决

得到一棵树T

我们设K=K+1

然后αK=α

TK=T

这个时候就由T0生成了T1

由α0又进一步递推到α1了

如此迭代下去

就假如它这目前这个T还不是什么根节点

及两个叶子结点所组成的树的话

我再回到这第二个步骤

再进行下一轮的迭代

就在针对T来讲

我又在找内部节点的每一个节点

它相应的g(t)的值

一直迭代下去之后怎么样

得到了α1 α2 αn

也得到相应的T0 T1 T2 Tn

通过交叉验证的方法

找到最优的那一棵子树

这是所谓的通过代价复杂度的方法进行剪枝

好 咱们看看在R里面是如何实现的

R里面我们首先可以通过printcp这个函数来看一看

关于这个代价复杂度相应的一些信息

这个刚才我们建好的模型

就这个完全生长的这个树imodel

这其中

有着一个CPtable

我们刚才讲了

通过不同的剪枝的话

它最后生成一棵子树序列

那这里面最终要看选择哪棵树的话

我怎么做的

交叉验证的方法对不对

交叉验证方法的时候

我们看一下

这里面有个xerror什么意思

就是X交叉的意思对吧

交叉验证

通过交叉验证的方法来看

目前这个子树它相应的错误率

当然因为你的交叉验证的话

每一折不一样

它同样还有一个

标准差的问题

也就说最终我们选择哪一棵子树最好的时候

一般就判断

这个交叉验证的结果

我们当然希望它的结果是最小的

并且这个偏差也是相对比较小的

就是在这个子树上它的

减掉之后进行交叉验证的时候

发现

总体上平均值它是最小

同时它波动相对小

相对比较稳定

好 我们看一下

可以通过这个plotcp来看一看具体的

我们相应的一些那个

在不同的子树下面它相应的表现

plotcp它得这么一个图

这边有不同的树的规模size of tree

那好这个我们看得出来所谓的偏差主要

看箱线图一样看它长短

越长的话 表示偏差越大

当然这个交叉验证的那个平均值的话

就是看这个具体的点了

我们当然希望找到最低的这个点

就是我这个偏差是

是我这交叉验证它测试的误差是最小的

当然对于我们这个数据集来讲

毫无疑问它就相当于没有剪枝

我这个叶子节点为14的时候

它是最优的

这个size of tree

是指叶子节点的意思

就是当我的叶子节点为14的时候

其实也就是我们原始这棵树

没有进行剪枝的时候效果最好

当然即便我们这棵树针对我们这个问题来讲

它没有进行剪枝

但是假如我们采用决策树进行建模的话

除了树的生长之外

剪枝应该是一个必须考虑的步骤

咱们看一看这个具体如何剪枝

我们刚才已经看了一下大概的性能表现

我们要剪枝的话

可以利用这里面这个函数

imodel到里面的相应得到一个结果叫cptable

利用这里面的信息进行剪枝

具体的利用过程是

它具体如何来利用cptable的信息

我们刚才讲了这里面有个交叉验证的结果

那其实我就想找到什么

究竟哪一个CP值和我对应到了

相应的最小的测试误差

找到它之后怎么样

我将这个相应的CP值拿过来得到它

就从这个数据框里面得到

相应的这个CP值

得到之后我调用这个prune()

就是剪枝这个函数

对imodel的之前已经完全生长的树进行剪枝

根据这个CP值进行剪枝就可以了

然后这是一个最后剪枝的结果

好 这就是我们在树生长之后

再进行剪枝的一个最基本的原理

以及R里面一个最基本的

实现的一个相应的一些函数

好 在我们进行了生长和剪枝之后

基本上说我们这个树的模型的建立

就已经完成了

咱们来看看这棵树具体的它的一个

可视化的效果

除了我们前面看到这个控制台的输出之外

我们还希望看到这个树究竟长什么样子

咱们看一看如何来绘制这个决策树

假如是用rpart这个包的话

里面有两个函数是最基本的

一个是plot(imodel)

再加上什么 text(imodel)

这个时候

生成这么一棵树的结构

相对比较简单

只是线条表示不同的分枝

上面有相应的属性的分裂

属性不同在取值的时候

它走不同的方向

满足它走左边

不满足走右边

咱们可以调用专门的什么rpart.plot

这个包里面相应的这个函数

这个函数名称也叫rpart.plot

我们可以绘制一下这个最后的模型

看它长什么样子

当然这里边有一些具体参数的设置

我们可以查看一下相应的帮助文档

看看每个参数设置都是什么含义

这是最后我们绘制的效果

显然我们这个通过rpart.plot绘制的图形

就相对于这个rpart里面这基本的函数的话

那效果就好得多了

基本上已经属于这个商业级或者工业级的一个结果

我们这个结果应该是可以

直接放到我们分析报告里面去的

好 这就是我们生成完这个树之后

调用这个rpart.plot进行绘图

需要补充的什么

这里面其实要绘这么个图形的话

它其实里面参数设置

还是相对比较复杂的

当然其实我也建议大家是这种

就是拿一个已有的模板

比如说我们现在已经查找这个

rpart.plot相应的这个一些文档

看以前已有的示例

在这示例的基础之上再做相应的调整

也就是说站在别人肩膀上再进一步

假如你自己需要调整

这里面比如说我这个字体的大小 颜色

对其中某一些参数进行调整也可以

而不是从零开始来设rpart.plot那么多的参数

这就是我们关于rpart.plot

绘图的一个最基本的一个介绍

当然我们也讲了

其实每一个决策树

在一次做判断的时候都会看成

一条条决策规则所组成的

就是一条路径下来其实就一条决策规则

我们说看这个树之外我们还希望

把决策规则导出来

怎么导我们需要借助一个包

这个包的名字叫rattle

这么一个包加载之后里面专门有个

asRules就将我们这棵树

我将它转换成规则

这个规则就比较容易读了

比如数学小于85.5并且性别为女

那是文科

包括类似下面的这些

就是如何得到不同的属性组合

最后判断它是否是文理分科

这些结论性的意见的话

可能更加具有可读性

好 这就是[决策规则] 一个导出的过程

导完之后我们也可以将这个规则

放到我们的数据分析报告里面去

当然我们前面讲到的这个模型的验证也好

包括我们那个决策树的一个构建也好

不管是训练集上的表现

还是测试集上的表现

其实都是通过一个

留出法的方法来实现

按照我们前面的那个分析的套路怎么样

在后面我们继续要做一个什么

就一个交叉验证 k折交叉检验

这个时候还是调用我们前面的框架

对于每一折进行一个训练和测试

就是kfolds当前这一则然后进行训练

划分出训练集测试集

并且对什么

调用rpart这个包

进行一个模型的训练

当然也有我们相应的一些剪枝的过程

然后对这个训练集进行一个预测

也是调用这个predict()这个函数

大家注意这个参数type等于class

这个type需要设置一下

否则的话它输出的话就是叶子节点上

不同类别的这个分类的比例了

或者说概率

不是这个具体类标签

一旦得到这个预测结果之后

再调用我们前面定义的这个函数叫imetrics

我们将这个方法的名称设为rpart

类别是什么

训练集上的一个表现

将这个具体预测结果和实际结果传递过去

将当前这一折训练集上的表现

rbind叠加到global_performance

总体性能指标里面去

同样

对于我们这个测试集也是一样

也得到相应的结果

并且叠加到我们总体的全局变量

global_performance里面去

这个得到结果之后

我们可以在最后所有算法讲完之后

我们再看哪一个模型

哪个算法它最终的性能表现最好

当然我们可以看一看

目前这个global_performance

对于rpart来讲

它的一些结果

同样 也是包含多少呢

也是包含这么20条记录

因为它是总共有10折

然后什么

每一折有什么训练集 有测试集

它相应的性能指标我们都可以看得出来

比如说它的错误率是0.30

这一折的话错误率多少

训练集是0.18 但测试集是0.25等等

当然最终的表现的话我们

都得看它的一个总体的一个平均值

在训练集上的平均值

在测试集上平均值

本次课到此结束

谢谢大家

R语言数据分析课程列表:

上部:问道

-第1章 气象万千、数以等观

--第1章 气象万千、数以等观

--第1章 作业

-第2章 所谓学习、归类而已

--2.1 所谓学习、归类而已(I)

--2.2 所谓学习、归类而已(II)

--2.3 所谓学习、归类而已(III)

--2.4 所谓学习、归类而已(IV)

--第2章 作业

-第3章 格言联璧话学习

--第3章 格言联璧话学习

--第3章 作业

-第4章 源于数学、归于工程

--第4章 源于数学、归于工程

--第4章 作业

-讨论题

--如何发挥人工智能的头雁效应

中部:执具

-第5章 工欲善其事、必先利其器

--第5章 工欲善其事、必先利其器

--第5章 作业

-第6章 基础编程——用别人的包和函数讲述自己的故事

--6.1 编程环境

--6.2Mini案例

--6.3 站在巨人的肩膀上

--6.4 控制流

--6.5 函数(I)

--6.6 函数(II)

--第6章 作业

-第7章 数据对象——面向数据对象学习R语言

--7.1 向量与因子(I)

--7.2 向量与因子(II)

--7.3 矩阵与数组(I)

--7.4 矩阵与数组(II)

--7.5 列表与数据框(I)

--7.6 列表与数据框(II)

--第7章 作业

-第8章 人人都爱tidyverse

--第8章 人人都爱tidyverse

--第8章 作业

-第9章 最美不过数据框

--第9章 最美不过数据框

--第9章 作业

下部:博术

-第10章 观数以形

--10.1 一维数据空间(I)

--10.2 一维数据空间(II)

--10.3 二维数据空间

--10.4 高维数据空间

--第10章 作业

-第11章 相随相伴、谓之关联

--11.1 导引

--11.2 关联规则(I)

--11.3 关联规则(II)

--11.4 关联规则(III)

--第11章 作业

-第12章 既是世间法、自当有分别

--12.1 导引

--12.2 近邻法(I)

--12.3 近邻法(II)

--12.4 决策树(I)

--12.5 决策树(II)

--12.6 随机森林

--12.7 朴素贝叶斯

--12.8 逻辑斯蒂回归

--12.9 人工神经网络(I)

--12.10 人工神经网络(II)

--12.11 支持向量机

--第12章 作业

-第13章 方以类聚、物以群分

--13.1 导引

--13.2 划分方法

--13.3 层次方法

--第13章 作业

-第14章 庐山烟雨浙江潮

--第14章 庐山烟雨浙江潮

--第14章 作业

12.5 决策树(II)笔记与讨论

也许你还感兴趣的课程:

© 柠檬大学-慕课导航 课程版权归原始院校所有,
本网站仅通过互联网进行慕课课程索引,不提供在线课程学习和视频,请同学们点击报名到课程提供网站进行学习。