4.1 基本流程
决策树:基于树结构进行分类决策的机器学习方法。一颗决策树一般包含一个根结点、若干个内部结点和若干个叶结点。
- 根结点:包含样本全集。
- 内部结点:对应于一个属性测试。每个结点包含的样本集合根据属性测试的结果被划分到子结点中。
- 叶结点:对应于决策属性。从根结点到每个叶结点的路径对应了一个判定测试序列。
基本算法:
-
输入:训练集D = {(x1, y1), (x2, y2), ..., (xm, ym)};
属性集A = {a1, a2, ..., ad}. -
过程:函数TreeGenerate(D, A)
- 生成结点node;
- if D中样本全属于同一类型C then
- 将node标记为C类叶结点; return
- end if
- if A = ∅ OR D中样本在A上取值相同 then
- 将node标记为叶结点, 其类别标记为D中样本数最多的类; return
- end if
- 从A中选择最优划分属性a*;
- for a*的每一个值 do
- 为node生成一个分支; 令Dv表示D中在a*上取值为的样本子集;
- if Dv为空 then
- 将分支结点标记为叶结点, 其类别标记为D中样本最多的类; return
- else
- 以TreeGenerate(Dv, A \ {a*})为分支结点
- end if
- end for
- 输出:以node为根结点的一颗决策树
以下为TreeGenerate函数的运行步骤:
第1行:生成根结点。
第2-4行:对应第一种递归返回,当前结点包含的样本全属于同一类别C,无需划分。将此结点标记为C类叶结点。(当前结点里全都是好瓜/全都是坏瓜)
第5-7行:对应第二种递归返回,当前属性集为空,或是所有样本在所有属性上取值相同,无法划分。将此结点划分为叶结点,其类别标记为D中样本数最多的类,利用了当前结点的后验分布。(当前结点中好瓜比较多则标记为好瓜类,反之亦然)
第8行:在所有的属性中挑选出一个最适合划分的属性a* ,挑选方法在4.2节讨论。(如在西瓜的属性中挑选出纹理属性作为a * )
第9行-10行 :将根结点按照最优属性a* 的值划分为多个内部结点。(按照纹理属性生成纹理清晰分支、纹理稍糊分支、纹理模糊分支)
第11-16行:若当前结点包含的样本集合为空,对应第三种递归返回,不能划分。将此结点划分为叶结点,其类别标记为D中样本数最多的类,把父结点的样本分布作为当前结点的先验分布。(训练集中没有纹理模糊的瓜, 若训练集中好瓜比较多,则假设纹理模糊的瓜都是好瓜)若当前结点样本集合不为空,则递归调用TreeGenerate函数生成分支结点,输入参数变为Dv和A \ {a* }。(去除纹理属性后在当前结点继续往下分支,分支方法从第1行开始执行。)
决策树的生成是一个递归过程,函数本身只执行生成一次分支,但通过在函数里调用函数的本身,使得分支再往下生成分支直至分类完成。
4.2 划分选择
4.2.1 信息增益
信息熵:度量样本集合纯度最常用的一种指标。假定当前样本集合D中第k类样本所占的比例为pk (k = 1, 2, ..., |y|),则D的信息熵定义为 。(通过好瓜与坏瓜的比例计算熵)
- Ent(D)的值越小,则D的纯度越高。(信息熵代表的是某件事情(一堆西瓜)到底是那种情况(好坏瓜比例)的不确定性。所以熵越小,越能确定好坏瓜的比例,即纯度越高)
- 若p = 0,则plog2p = 0。
- Ent(D)的最小值为0,最大值为log2|y|。
信息熵的公式定义可参考YJango的视频
https://www.bilibili.com/video/av41539594
关于信息熵的上下限计算可参考南瓜书
https://datawhalechina.github.io/pumpkin-book/#/chapter4/chapter4
信息增益:假定离散属性a有V个可能的取值{a1, a2, ..., aV},若使用a来对样本集D进行划分,则会产生V个分支结点,其中第v个分支结点包含了D中所有在属性a上取值为av的样本,记为Dv。考虑到不同的分支结点所包含的样本数不同,给分支结点赋予权重|Dv|/|D|,即样本数越多的分支结点影响越大,于是可计算出用属性a对样本集D进行划分所获得的信息增益。(先选定一个属性,如色泽,可将训练集分成青绿、乌黑、浅白三类。分别计算三个小类的里好瓜和坏瓜的不确定性,即信息熵。而后计算三个小类信息熵的加权和)
- 信息增益 = 根结点的信息熵 - 所有分支结点的信息熵的加权和。
- 信息增益越大,则意味着使用属性a来进行划分所获得的纯度提升越大。(因为根结点的信息熵是确定的,通过比较信息增益,可以比较出每个属性的信息熵加权和,信息增益越大,信息熵加权和越小,则不确定性越小,说明此属性更能帮助减少不确定性)
- 可在算法第8行进行选择属性 ,即ID3算法。
- 信息增益准则对可取值数目较多的属性有所偏好。(使用色泽属性只能取三个值,乌黑、青绿、浅白,但如果使用编号属性则能取最多的值,此时一个样本就是一个子集,好瓜坏瓜是确定的,熵为0,信息增益最大,但没有意义)
书上有详细的计算过程,此处省略
代码思路:
- 使用numpy包创建数据集。
- 创建基础函数,用以计算信息熵、信息增益。
- 创建寻找最优属性的函数,比较各属性的信息增益,选取信息增益最大的属性。
- 创建树生成函数,具体可参考4.1的基本算法,在第8行使用上述函数。
- 使用matplotlib包进行树的可视化。
4.2.2 增益率
增益率:
固有值:
- 属性a的可能取值数目越多(即V越大),则IV(a)的值通常会越大。(增益率本质上是在信息增益的基础之上乘上一个惩罚参数()。特征个数较多时,惩罚参数较小;特征个数较少时,惩罚参数较大。可以解决信息增益对可取数值较多的属性的偏好带来的不利影响。)
- 增益率准则对可取数目较少的属性有所偏好。(可取数目较少的属性的惩罚参数小。)
- C4.5算法并不是直接选择增益率最大的候选划分属性,而是使用了一个启发式:先从候选划分属性中找出信息增益高于平均水平的属性,再从中选择增益率最高的。
代码思路:
- 使用numpy包创建数据集。
- 创建基础函数,用以计算信息熵、信息增益、信息增益率。
- 创建寻找最优属性的函数,先找出信息增益高于平均水平的属性,再从中选择增益率最高的。
- 创建树生成函数,具体可参考4.1的基本算法,在第8行使用上述函数。
- 使用matplotlib包进行树的可视化。
4.2.3 基尼指数
基尼值:度量数据集的纯度的指标。假定当前样本集合D中第k类样本所占的比例为pk (k = 1, 2, ..., |y|),
- Gini(D)反映了从数据集中随机抽取两个样本,其类别标记不一样的概率。
- Gini(D)越小,则数据集D的纯度越高。(如果数据集中好瓜比例很大,则此数据集纯度较高,此时随机抽取两个瓜,两个都为好瓜的概率大于一好一坏,即类别标记不一样的概率小,基尼值小。)
基尼指数:假定离散属性a有V个可能的取值{a1, a2, ..., aV},若使用a来对样本集D进行划分,则会产生V个分支结点,其中第v个分支结点包含了D中所有在属性a上取值为av的样本,记为Dv。考虑到不同的分支结点所包含的样本数不同,给分支结点赋予权重|Dv|/|D|,即样本数越多的分支结点影响越大,于是可计算出用属性a对样本集D进行划分所获得的基尼指数。
- 可在算法第8行进行选择属性 ,即CART决策树。(先选定一个属性,如色泽,可将训练集分成青绿、乌黑、浅白三类。分别计算三个小类的Gini(D),而后计算三个小类Gini(D)的加权和。对属性集A中的每个属性都进行一遍计算,选择那个使得划分后基尼指数最小的属性作为最优划分属性)
代码思路:
- 使用numpy包创建数据集。
- 创建基础函数,用以计算数据集的基尼值和属性的基尼指数。
- 创建寻找最优属性的函数,比较各属性的基尼指数,选取基尼指数最小的属性。
- 创建树生成函数,具体可参考4.1的基本算法,在第8行使用上述函数。
- 使用matplotlib包进行树的可视化。
4.3 剪枝处理
剪枝: 通过主动去掉一些分支来降低过拟合的风险。
决策树桩:仅有一层划分的决策树。
4.3.1 预剪枝
预剪枝:在决策树生成过程中,对每个结点在划分前先进行估计,若当前结点的划分不能带来决策树泛化性能提升,则停止划分并将当前结点标记为叶结点。
- 降低了过拟合的风险,还显著减少了决策树的训练时间开销和测试时间开销。
- 有欠拟合风险。有些分支的当前划分虽不能提升泛华性能、甚至可能导致泛化性能暂时下降,但在其基础上进行的后续划分却又可能导致性能显著提高。
书上有详细的过程,此处略。
代码思路:
- 创建一个基础函数,用以计算划分前与划分后的进度并进行比较。
- 参考4.1的代码,在第14行后使用上述函数。如果划分后的精度相比划分前的精度下降,则直接作为叶结点返回。
4.3.2 后剪枝
后剪枝:先从训练集生成一颗完整的决策树,然后自底向上地对非叶结点进行考察,若将该结点对应的子树替换为叶结点能带来决策树泛化性能提升,则将该子树替换为叶结点。
- 后剪枝决策树通常比预剪枝决策树保留了更多的分支,一般情形下,后剪枝决策树的欠拟合风险很小,泛化性能往往优于预剪枝决策树。
- 后剪枝过程是在生成完全决策树之后进行的,并且要自底向上地对树中所有非叶结点进行逐一考察,因此其训练时间开销比未剪枝决策树和预剪枝决策树都要大得多。
书上有详细的过程,此处略。
代码思路:
在生成分支结点的时候计算若直接生成叶结点的精度,在树生成完毕后自下而上进行比较,若精度有所提高则生成叶结点。
4.4 连续与缺失值
4.4.1 连续值处理
二分法:将连续属性离散化。
- 给定样本集D和连续属性a,假定a在D上出现了n个不同的取值,将这些值从小到大进行排序,记为{a1, a2, ..., an}(如西瓜的密度,由小到大排序)。
- 基于划分点t可将D分为子集和,其中包含那些在属性a上取值不大于t的样本,而则包含那些在属性a上取值大于t的样本。(若划分点t为密度=0.5,则子集包含所有密度小于0.5的西瓜样本,子集包含所有密度大于0.5的西瓜样本)
- 显然,对相邻的属性取值ai与ai+1来说,t在区间[ai, ai+1)中取任意值所产生的划分结果相同。(假设两个相邻取值为密度0.5和密度0.7,则t在0.5~0.7之间任取值都会将0.5和0.7两个瓜划分开来,其划分结果相同)
- 因此,对连续属性a,我们可考察包含n-1个元素的候选划分点集合,即把区间[ai, ai+1)的中位点作为候选划分点。(按照从小到大的排序,将每两个相邻的密度值的中位点作为候选划分点t,由此得到一个t的合集Ta)
- 然后,我们就可像离散属性值一样来考察这些划分点,选取最优的划分点来进行样本集合的划分。(假设Ta中有密度=0.381和密度=0.45,按密度=0.381为划分点生成决策树的分支,然后计算其信息增益,再计算密度=0.45划分的信息增益,选择信息增益最大的划分点。此时的信息增益代表密度属性的信息增益,再与其他属性(色泽、根蒂等)的信息增益进行比较。当密度的信息增益最大时,使用划分点划分,如将西瓜分成密度大于0.381、小于0.381两类。)
- 若当前结点划分属性为连续属性,该属性还可作为其后代结点的划分属性。
关于(4.8)式可参考南瓜书
https://datawhalechina.github.io/pumpkin-book/#/chapter4/chapter4?id=_46
4.4.2 缺失值处理
如何在属性值缺失的情况下进行划分属性选择:
- 给定训练集D和属性a,令表示D中在属性a上没有缺失值的样本子集。(假设属性a为色泽,将色泽属性没有缺失的西瓜挑出作为子集)
- 假定属性a有V个可取值{a1, a2, ..., aV},令表示中在属性a上取值为av的样本子集,表示中属于第k类(k = 1, 2, ..., |y|)的样本子集,则显然有,。(如表示中色泽青绿的集合,表示中好瓜的集合,表示中坏瓜的集合,则有是和的并集,也是、、的并集,)
- 假定我们为每个样本x赋予一个权重wx(在决策树学习的开始阶段,根结点中各样本的权重初始化为1),并定义
直观的看,对属性a,ρ表示无缺失值样本所占比例(色泽属性没有缺失的西瓜数量占所有西瓜的比例),表示无缺失值样本中第k类所占的比例(表示色泽属性没有缺失的西瓜中好瓜的比例,表示色泽属性没有缺失的西瓜中坏瓜的比例),则表示无缺失值样本中在属性a上取值av的样本所占的比例(表示色泽属性没有缺失的西瓜中,青绿西瓜所占的比例)。显然。 - 基于上述定义,我们可将信息增益的计算式(4.2)推广为
其中。
信息增益 = 无缺失值样本所占比例 x (无缺失值集合的信息熵 - 无缺失值集合中按属性值划分后所有分支结点的信息熵的加权和)
(即忽略掉属性值缺失的样本,按照无缺失值的集合的好坏瓜比例来计算属性的信息增益,再乘上无缺失值样本占所有样本的比例,即为该属性的信息增益,而后对比其他属性的信息增益进行划分。)
给定划分属性,若样本在该属性上的值缺失,如何对样本进行划分:
- 若样本x在划分属性a上的取值已知,则将x划入 与其取值对应的子结点,且样本权值在子结点中保持为wx。
- 若样本x在划分属性a上的取值未知,则将x同时划入所有子结点,且样本权值在与属性值av对应的子结点中调整为·wx;直观地看,这就是让同一个样本以不同的概率划入到不同的子结点中去。
4.5 多变量决策树
若我们把每个属性视为坐标空间中的一个坐标轴,则d个属性描述的样本就对应了d维空间中的一个数据点,对样本分类则意味着在这个坐标空间中寻找不同类样本之间的分类边界。
单变量决策树:
- 因为每一段分类边界的划分都直接对应了某个属性取值,所以其分类边界都与轴平行。
- 但在学习任务的真实分类边界比较复杂时,必须使用很多段划分才能获得较好的近似。(下图黑线)
- 此时的决策树会想当复杂,由于要进行大量的属性测试,预测时间开销会很大。
多变量决策树:
- 能实现“斜划分”甚至更复杂划分的决策树。(下图红线)
- 实现斜划分的多变量决策树中,非叶结点不再是仅对某个属性,而是对属性的线性组合进行测试。换言之,每个非叶结点是一个形如的线性分类器,其中wi是属性ai的权重,wi可在该结点所含的样本集和属性集上学得。(如下图决策树)