周志华-机器学习-笔记(三)-决策树

基本流程

  决策树的功能和结构:一颗决策树包含一个根结点、若干个内部结点和若干个叶结点;叶结点对应于决策结果,其它每个结点则对应于一个属性测试;每个结点包含的样本集合根据属性测试的结果被划分到子结点中;根结点包含样片全集。
  决策树学习的目的:为了产生一棵泛化能力强,即处理未见示例能力强的决策树。
这里写图片描述
  决策树的生成是一个递归过程,但有递归就必定有导致递归返回的情况,要不然递归就会一直无限下去。
  (1)当前结点包含的样本全属于同一类别,无需划分;
  (2)当前属性集为空,或是所有样本在所有属性上取值相同,无法划分;
  (3)当前结点包含的样本集合为空,不能划分。
  在第(2)种情形下,我们把当前结点标记为叶结点,并将该类别设定为该结点所含样本最多的类别。
  在第(3)种情形下,同样把当前结点标记为叶结点,但将其类别设定为与其父节点所包含样本最多的类别。

划分选择

  由图4.2可看出,决策树学习的关键是第8行,即如何选择最优划分属性。随着划分过程的不断进行,我们希望决策树的分支节点所包含的样本尽可能属于同一类别,即结点的“纯度”(purity)越来越高。

信息增益

  “信息熵”(information entropy)是度量样本集合纯度最常用的一种指标。假定当前样本集合 D D 中第k类样本所占的比例为 pk(k=1,2,...,|y|) p k ( k = 1 , 2 , . . . , | y | ) ,则 D D 的信息熵定义为:

Ent(D)=k=1|y|pklog2pk

Ent(D) E n t ( D ) 的值越小,则 D D 的纯度越高。
  假定离散属性a V V 个可能的取值{a1,a2,...,aV},则使用 a a 来对样本集D进行划分,就会产生 V V 个分支结点,其中第v个分支结点包含了 D D 中所有在属性a上取值为 av a v 的样本,记为 Dv D v 。我们可以计算出 Dv D v 的信息熵为 Ent(Dv) E n t ( D v ) ,考虑到不同的分支结点所包含的样本数不同,给各个分支结点赋予权重 DvD D v D ,于是算出用属性 a a 对样本D进行划分所获得的“信息增益”(information gain):

Gain(D,a)=Ent(D)v=1V|Dv||D|Ent(Dv) G a i n ( D , a ) = E n t ( D ) − ∑ v = 1 V | D v | | D | E n t ( D v )

信息增益越大,则意味着使用属性 a a 来进行划分所获得的“纯度提升”越大。因此,我们用信息增益来进行决策树的划分属性选择,即图4.2算法第8行选择属性a=argmaxGain(D,a),aA

增益率

  信息增益准则对可取值数目较多的属性有所偏好,为了减少这种偏好可能带来的不利影响,使用“增益率”(gain ratio)来选择最优划分属性。其定义为:

Gain_ratio(D,a)=Gain(D,a)IV(a) G a i n _ r a t i o ( D , a ) = G a i n ( D , a ) I V ( a )
其中
IV(a)=v=1V|Dv||D|log2|Dv||D| I V ( a ) = − ∑ v = 1 V | D v | | D | log 2 ⁡ | D v | | D |
称为属性 a a 的“固有值”(intrinsic value)。通常属性a的可能取值数目越多(即 V V 越大),则IV(a)的值通常越大。
  增益率准则对可取值数目较少的属性有所偏好,故在使用增益率准则时,想从候选划分属性中找出信息增益高于平均水平的属性,再从中选择增益率最高的。

尼基指数

  CART决策树,Classification and Regression Tree,是一种著名的决策树学习算法,分类和回归任务都可用。它就使用“尼基指数”(Gini index)来选择划分属性。数据集 D D 的纯度用尼基值来度量:

Gini(D)=k=1|y|kkpkpk=1k=1|y|pk2

   Gini(D) G i n i ( D ) 反映了数据集 D D 中随机抽取两个样本,其类别标记不一致的概率。因此,Gini(D)越小,则数据集 D D 的纯度越高。
  属性a的尼基指数定义为

Gini_index(D,a)=v=1V|Dv||D|Gini(Dv) G i n i _ i n d e x ( D , a ) = ∑ v = 1 V | D v | | D | G i n i ( D v )

  我们在候选属性 A A 中,选择尼基指数最小的属性作为最优划分属性,即a=argminGini_index(D,a),aA

剪枝处理

  剪枝(pruning)是决策树学习算法对付“过拟合”的主要手段。决策树剪枝的基本策略有“预剪枝”(prepruning)和”后剪枝”(post-pruning)。预剪枝是指在决策树生成过程中,对每个结点在划分前先进行估计,若当前结点的划分不能带来决策树泛化性能提升,则停止划分并将当前结点标记为叶结点;后剪枝是先从训练集生成一颗完整的决策树,然后自底向上地对非叶结点进行考察,若将该结点对应的子树替换为叶结点能带来决策树泛化性能提升,则将该子树替换为叶结点。
  判断决策树泛化性能提升的方法有很多(留出法、自助法等),这里使用留出法讨论。对西瓜数据集随即划分成下图的两个部分:
这里写图片描述

预剪枝

  基于信息增益准则,如果对表4.2的数据集生成决策树,如下图所示:
这里写图片描述
  预剪枝处理的决策树如下图:
这里写图片描述

后剪枝

  基于表4.2的数据我们得到图4.5的决策树,用验证集验证可知该决策树的进度为 42.9% 42.9 % 。后剪枝需要从低往上,一个结点一个结点验证。得到的决策树如下
这里写图片描述
其验证精度为 71.4% 71.4 %

  预剪枝与后剪枝比较:后剪枝决策树通常比预剪枝决策树保留了更多的分支,所以后剪枝决策树的欠拟合风险很小,泛化性能往往优于预剪枝决策树。
  但后剪枝决策树需要对每个非叶结点逐一进行考察,因此其训练时间开销比未剪枝和预剪枝决策树都要大得多。

连续与缺失值
连续值处理

  在现实学习任务中常会遇到连续属性(例如,形容一种特性的程度),所以有必要讨论如何在决策树学习中使用连续属性。二分法(bi-partition)是对连续属性进行处理的最简单策略,是一种连续属性离散化技术。
  给定样本集 D D 和连续属性a,假定 a a D上出现了 n n 个不同的取值,将这些值从小到大进行排序,记为{a1,a2,...,an}。然后基于划分点 t t 可以将D分为子集 Dt D t − (属性 a a 上取值不大于t的样本),和 D+t D t + (属性 a a 上取值大于t的样本)。
  由于对于任意相邻的属性取值 ai a i ai+1 a i + 1 来说, t t 在区间[ai,ai+1)中取任意值所产生的划分结果相同。因此,对于连续属性 a a ,包含n1个元素的候选划分点集合

Ta={ai+ai+12|1in1} T a = { a i + a i + 1 2 | 1 ≤ i ≤ n − 1 } ,
然后,就可以想离散属性值一样来考察这些划分点,选择最优的划分点进行样本集合的划分。有:
Gain(D,a)=maxGain(D,a,t),tTa G a i n ( D , a ) = m a x G a i n ( D , a , t ) , t ∈ T a

=maxEnt(D)λ{,+}|Dλt||D|Ent(|Dλt) = m a x E n t ( D ) − ∑ λ ∈ { − , + } | D t λ | | D | E n t ( | D t λ ) ,
其中 Gain(D,a,t) G a i n ( D , a , t ) 是样本集 D D 基于划分点t二分后的信息增益。于是选择使 Gain(D,a,t) G a i n ( D , a , t ) 最大化的划分点。

缺失处理

  现实任务中常常会遇到不完整的样本,即样本的某些属性值缺失。如果我们放弃这些不完整的样本,无疑是对数据信息的极大的浪费。下表是含有不完整样本的西瓜数据集
这里写图片描述
  对此,我们需要解决两个问题:(1)如何在属性值缺失的情况下进行划分属性选择?(2)给定划分属性,若样本在该属性上的值缺失,如何对样本进行划分?
  给定训练集 D D 和属性a,令 Dˇ D ˇ 表示 D D 中在属性a上没有缺失值的样本子集。
  对于问题(1),我们仅可根据 Dˇ D ˇ 来判断属性 a a 的优劣。假定属性a V V 个可取值{a1,a2,...,aV},令 Dvˇ D v ˇ 表示 Dˇ D ˇ 在属性 a a 上取值为av的样本子集; Dkˇ D k ˇ 表示 Dˇ D ˇ 中属于第 k k (k=1,2,...|y|)的样本子集。于是有, Dˇ=|y|k=1Dˇk D ˇ = ∪ k = 1 | y | D ˇ k ,它表示 checkDk,(k=1,2,...,|y|) c h e c k D k , ( k = 1 , 2 , . . . , | y | ) 的所有并集;和 Dˇ=Vv=1Dˇv D ˇ = ∪ v = 1 V D ˇ v ,它表示 checkDv,(v=1,2,...,V) c h e c k D v , ( v = 1 , 2 , . . . , V ) 的所有并集。
  假定我们为每个样本 x x 赋予一个权重wx,并定义

ρ=xDˇwxxDwx ρ = ∑ x ∈ D ˇ w x ∑ x ∈ D w x
pˇk=xDkˇwxxDˇwx(1k|y|) p ˇ k = ∑ x ∈ D k ˇ w x ∑ x ∈ D ˇ w x ( 1 ≤ k ≤ | y | )
rˇk=xDvˇwxxDˇwx(1vV) r ˇ k = ∑ x ∈ D v ˇ w x ∑ x ∈ D ˇ w x ( 1 ≤ v ≤ V )
对属性 a a 来说,ρ表示无缺失值样本所占的比例; pkˇ p k ˇ 表示无缺失值样本中第 k k 类所占的比例;rvˇ表示无缺失值样本中在属性 a a 上取值av的样本所占的比例。并且有, |y|k=1pkˇ=1 ∑ k = 1 | y | p k ˇ = 1 Vv=1rvˇ=1 ∑ v = 1 V r v ˇ = 1
  根据上述定义,可将信息增益的计算式(4.2)推广为
Gain(D,a)=ρ×Gain(Dˇ,a)=ρ×(Ent(Dˇ)v=1VEnt(Dvˇ)) G a i n ( D , a ) = ρ × G a i n ( D ˇ , a ) = ρ × ( E n t ( D ˇ ) − ∑ v = 1 V E n t ( D v ˇ ) )
其中 Ent(Dˇ)=|y|k=1pkˇlog2pkˇ E n t ( D ˇ ) = − ∑ k = 1 | y | p k ˇ log 2 ⁡ p k ˇ
   对于问题(2),若样本 x x 在划分属性a上的取值已知,则将 x x 划入与其取值对应的子结点,且样本权值在子结点中保持为wx;若样本 x x 在划分属性a上的取值未知,则将 x x 同时划入所有子结点,且样本权值在与属性值av对应的子结点中调整为 rvˇwx r v ˇ ⋅ w x ,这相当于让同一个样本以不同的概率划入到不同的子结点中去。

多变量决策树

  若把每个属性是为坐标空间中的一个坐标轴,则d个属性对应d维空间中的一个数据点。决策树所形成的的分类边界有一个明显的特点:轴平行(axis-parallel),即它的分类边界由若干个与坐标轴平行的分段组成。
这里写图片描述
  若是在多变量情况下,决策树会相当复杂,由于要进行大量的属性测试,预测时间开销会很大。但若能使用斜的划分边界,则决策树模型将大为简化。
这里写图片描述
  “多变量决策树”(multivariate decision tree)就是能实现这样的“斜划分”甚至更复杂划分的决策树。
  以实现斜划分的多变量决策树为例,在此类决策树中,非叶结点不再是仅对某个属性,而是对属性的线性组合进行测试;使得每个非叶结点是一个形如 di=1wiai=t ∑ i = 1 d w i a i = t 的线性分类器,其中 wi w i 是属性 ai a i 的权重, wi w i t t <script type="math/tex" id="MathJax-Element-303">t</script>可在该结点所含的样本集和属性集上学得。
这里写图片描述

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
周志华是一位著名的机器学习专家,他在《机器学习》一书中详细介绍了决策树算法。下面是决策树算法的伪代码: 1. 定义决策树节点类: class DecisionTreeNode: def __init__(self): self.feature = None # 当前节点选择的特征 self.threshold = None # 特征的阈值 self.label = None # 叶子节点的类别标签 self.left_child = None # 左子树 self.right_child = None # 右子树 2. 定义决策树构建函数: def build_decision_tree(data, labels): # 创建新节点 node = DecisionTreeNode() # 如果所有样本属于同一类别,则将当前节点标记为叶子节点,并返回 if all_same_class(labels): node.label = labels return node # 如果没有特征可用,则将当前节点标记为叶子节点,并返回 if no_more_features(): node.label = majority_class(labels) return node # 选择最优特征和阈值 best_feature, best_threshold = choose_best_feature(data, labels) node.feature = best_feature node.threshold = best_threshold # 根据最优特征和阈值划分数据集 left_data, left_labels, right_data, right_labels = split_data(data, labels, best_feature, best_threshold) # 递归构建左子树和右子树 node.left_child = build_decision_tree(left_data, left_labels) node.right_child = build_decision_tree(right_data, right_labels) return node 3. 定义决策树预测函数: def predict(node, sample): if node.label is not None: return node.label if sample[node.feature] <= node.threshold: return predict(node.left_child, sample) else: return predict(node.right_child, sample) 以上是决策树算法的伪代码,其中包括了决策树节点类的定义、决策树构建函数和决策树预测函数。通过递归地选择最优特征和阈值来构建决策树,并使用构建好的决策树进行样本的预测。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值