(《机器学习》完整版系列)第4章 线性模型——4.1 决策树算法(不是规划论中的决策树,深度优先或广度优先)

决策树(注意与规划论中的决策树的区别)是重要的基础算法之一,其中一条发展路径为由“树”到“森林”(如,随机森林算法)。 这里围绕该“树”进行讨论:由样本属性取不同的值产生“分裂”,从而分叉形成“树”,树需要剪枝修整。

决策树算法

基本算法

【西瓜书图4.2】描述了决策树的基本算法,为理解该算法,我们作如下说明。

1.树的生长:属性个数 d d d决定树的深度,每一次向下生长(倒树)一层消耗掉一个属性 a ∗ a_* a(第8句及第14句体现),这一层的宽度(分叉数)由该属性 a ∗ a_* a的取值数决定(第9句体现)。 宽度用“ f o r \mathrm{for} for循环”实现(第9句),而深度由递归实现(第14句)。

2.树的叶子:在树的生长过程中,遇到叶子则为该方向的递归终结,叶子有三种情况,对应于算法中的三个 r e t u r n \mathrm{return} return(分别在第3、6、12句),三种情况的解释在【西瓜书图4.2】下面的一段文字中。

3.决策点:在树的生长过程中,每一次向下生长都要“决策”消耗掉哪个属性 a ∗ a_* a(第8句),称为“划分选择”,而不是随便选择一个属性。 故该树称为“决策树”。

4.局部图:树的非叶结点由一个数据集和未使用的属性集组成,我们设待分裂的结点为 ( D , A ) (D,A) (D,A),这里是为方便而记: ( D , A ) (D,A) (D,A)为任一待分裂结点中的情形(变量),而不是指算法初始的 ( D , A ) (D,A) (D,A),实际上它为初始集的子集(因分裂而减少)。 当然,你也可以将这里改为 ( D ′ , A ′ ) (D',A') (D,A)以示区别。

将树的生长点展开为两个步骤:选择属性 a ∗ a_* a和依该属性的值 a ∗ 1 , a ∗ 2 , ⋯   , a ∗ v a_*^1,a_*^2,\cdots,a_*^v a1,a2,,av横向扩展分支,得到结果如图4.1所示。

图4.1 决策树的生长

图4.1 决策树的生长

其中,对 D D D依该属性的值作了划分: D = D 1 ⋃ D 2 ⋃ ⋯ ⋃ D v D=D^1\bigcup D^2\bigcup\cdots\bigcup D^v D=D1D2Dv

基于“栈”或“队列”

本小节从编程角度讨论决策树基本算法的变形。

(1)基于“栈”的深度优先搜索。

我们先将上述图4.1变为如下图4.2。
图4.2 深度优先搜索

图4.2 深度优先搜索

决策树基本算法是递归算法,它实际上是深度优先树搜索,下面我们先看看等效的“栈”方法表达的深度优先树搜索。
针对图4.2,我们需要构造针对结点操作的“入栈”和“出栈”函数,之后再用如下递归函数(伪代码)进行决策树的生成:

在这里插入图片描述

对应的意义如图4.2所示。

上述算法中需要“栈”(stack)有一定的容量(深度):当为二叉树时,每向一下层(while一次)的“栈”操作为pop一次、push两次(for语句)(直到最后叶子不push),这两操作相抵后在“栈”中占位为1,即“栈”的深度为树的深度;当树为多叉树时,for语句使得“栈”的深度大大地大于树的深度(push的次数更多)。 即当“栈”设置过浅时,会产生溢出。

(2)基于“队列”的广度优先搜索。

在上述算法中,将stack(栈)改为queue(队列),则对应的stack.push改为queue.in(入队列)、stack.pop改为queue.out(出队列)。

由于队列是“先进先出”的方式,故while是对“层”进行扫描形成新的“层”,即它是广度优先算法。

在上述广度优先算法的基础上,增加对树的深度控制阈值 M a x D e p t h \mathrm{MaxDepth} MaxDepth,生成结点时标上其深度:

(1)出队的结点 D D D(设深度为 l l l)为“for产生的结点”的父结点,故结点 D a k D_a^k Dak的深度为 l + 1 l+1 l+1

(2)判断是否是叶子结点,增加一个为叶子的条件:深度达到 M a x D e p t h \mathrm{MaxDepth} MaxDepth的百叶子结点强制改为叶子结点。

为加强控制溢出,在上述广度优先算法中增加结点计数器 c o u n t \mathrm{count} count及其阈值 M a x N o d e \mathrm{MaxNode} MaxNode,作如下修改:

(1)while之前,对计数器初始化 c o u n t = 1 \mathrm{count}=1 count=1

(2)for中生成结点 D a k D_a^k Dak时计数器 c o u n t \mathrm{count} count加1;

(3)计数器 c o u n t \mathrm{count} count加1时判断是否达到阈值 M a x N o d e \mathrm{MaxNode} MaxNode,一旦达到,则跳出循环while;

(4)跳出循环while后,将队列中的元素全部视为叶子结点处理。

特点:在多叉树时,由于宽度各层不固定,故 M a x D e p t h \mathrm{MaxDepth} MaxDepth不易控制所需容量,而直接对结点个数计数,其阈值 M a x N o d e \mathrm{MaxNode} MaxNode可直接控制所需内存容量。

本文为原创,您可以:

  • 点赞(支持博主)
  • 收藏(待以后看)
  • 转发(他考研或学习,正需要)
  • 评论(或讨论)
  • 引用(支持原创)
  • 不侵权

上一篇:3.4 纠错输出码(奇想:用编码来分类)
下一篇:4.2 划分选择与剪枝(此事“信息量好大”,暗指该事件不平常)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值