作者:張張張張
github地址:https://github.com/zhanghekai
【转载请注明出处,谢谢!】
【机器学习系列】之“西瓜数据集”决策树构建数学公式计算过程
【机器学习系列】之决策树剪枝和连续值、缺失值处理数学公式计算
【机器学习系列】之ID3、C4.5、CART决策树构建代码
一、剪枝处理
剪枝(pruning)是决策树学习算法对付“过拟合”的主要手段,可通过主动去掉一些分支来降低过拟合的风险。
-
“预剪枝(prepruning):”预剪枝是指在决策树生成过程中,对每个节点在划分前先进行估计,若当前节点的划分不能带来决策树泛化性能提升,则停止划分并将当前节点标记为叶节点。
-
“后剪枝(postpruning):”后剪枝则是先从训练集生成一颗完整的决策树,然后自底向上地对非叶节点进行考察,若将该结点对应的子树替换为叶节点能带来决策树泛化性能提升,则将该子树替换为叶节点。
本节采用“留出法”,预留一部分数用作“验证集”以进行性能评估,实验数据采用周志华《机器学习》一书中的“西瓜数据集”,如下表所示。
假定采用信息增益准则来进行划分特征选择,则从表4.2的训练集将会生成一颗决策树,如下图所示,为了便于讨论,我们对图中的部分节点做了编号。
注意事项:
- 先通过信息曾增益确定选择的特征
- 再计算精度,决定是否继续划分此节点(未用特征划分前的精度,与使用特征划分后的精度,进行比较)
- 若决定不划分该特征,则将该特征下的属性设置为叶节点,节点类别为属性数据集中类别最多的类别(若正、反类别数量相等,则可任意设置),类别标记用的是训练集数据
- 由于决策树的建立是深度优先,若决定不继续划分当前特征,则需要往回遍历
- 剪枝操作用到了测试集!即在构建树的过程中,一边用训练集构建,一边用验证集剪枝。
- 剪枝操作计算的是验证集在叶子节点上的精度(决策树的建立及特征的选择是在训练集上;节点精度的计算是在验证集上)
- 测 试 精 度 = 验 证 集 正 确 划 分 数 据 个 数 验 证 集 数 据 总 数 测试精度=\frac{验证集正确划分数据个数}{验证集数据总数} 测试精度=验证集数据总数验证集正确划分数据个数
- 根节点与总验证数据集的精度比较,其余特征节点与其父特征节点精度相比较
1.预剪枝
预剪枝判断的标准是看划分前后的泛化性能是否有提升:如果划分后泛化性能有提升则划分;否则,不划分。
-
经过信息增益计算后,第(1)个节点选择的特征是“脐部”:
★划分前:a。所有样本都在根节点,把该节点标记为叶节点,其类别标记为训练集中样本数量最多的类别,假设这个节点标记为好瓜。
b。用验证集对其性能进行评估,{4,5,8}被正确分类,其他被错误分类,因此精度为 3 7 × 100 \frac{3}{7} \times 100% =42.9% 73×100
★划分后:使用“脐部”特征划分后,将其下的属性标记为叶节点,类别分别为“好瓜”,“”好瓜“,”坏瓜“。此时验证集中编号为{4,5,8,11,12}的样本被正确分类,验证集精度为 5 7 × 100 \frac{5}{7} \times 100%=71.4% > 42.9% 75×100,所以,用”脐部“进行划分。
-
计算信息增益,对节点(2)进行数据划分,选取信息增益最大的特征,经计算后选择”色泽“特征。
★划分前:划分前的精度为该节点父节点的精度,即”脐部“特征的精度,为71.4%。
★划分后:
使用“色泽”特征划分后,将其下的属性标记为叶节点,类别分别为“好瓜”,“”好瓜“,”坏瓜“。此时验证集中编号为{4,8,11,12}的样本被正确分类,验证集精度为 4 7 × 100 \frac{4}{7} \times 100%= 57.1% < 71.4% 74×100,所以,不使用”色泽“特征划分,将该节点设置为叶子节点。
-
计算信息增益,对节点(3)进行数据划分,选取信息增益最大的特征,经计算后选择”根蒂“特征。
★划分前:划分前的精度为该节点父节点的精度,即”脐部“特征的精度,为71.4%。
★划分后:使用“根蒂”特征划分后,将其下的属性标记为叶节点,类别分别为“坏瓜”,“”好瓜“,”好瓜“。此时验证集中编号为{4,5,8,11,12}的样本被正确分类,验证集精度为 5 7 × 100 \frac{5}{7} \times 100%= 71.4% 75×100,该节点精度与其父节点精度相同,这个划分不能提升验证集精度,所以,不使用”根蒂“特征划分,将该节点设置为叶子节点。
-
计算信息增益,对节点(4)进行数据划分,由于其所含训练样本已属于同一类,所以不再进行划分,将其设置为叶节点
综上所述,经”预剪枝“操作后,生成的决策树如下图所示,其验证精度为71.4%。
总结:预剪枝使得决策树的很多分支都没有“展开”,这不仅降低了过拟合的风险,还显著减少了决策树的训练时间开销和测试时间开销.但另一方面,有些分支的当前划分虽不能提升泛化性能、甚至可能导致泛化性能暂时下降,但在其基础上进行的后续划分却有可能导致性能显著提高;预剪枝基于“贪心”本质禁止这些分支展开,给预剪枝决策树带来了欠拟合的风险。
2.后剪枝
后剪枝先从训练集生成一颗未剪枝的完整的决策树,如下图所示,然后自底向上的对非叶节点进行考察,若将该节点对应的子树转换为叶节点能够带来泛化性能的提升,即精度提升,则把该节点设置为叶子节点。
-
传入验证集,此时验证集中编号为{4,11,12}的样本被正确分类,该决策树的验证集精度为 3 7 × 100 \frac{3}{7} \times 100%= 42.9% 73×100
-
后剪枝算法首先考察上图中的节点(6),若将以其为根节点的子树删除,即相当于把节点(6)替换为叶节点,替换后的叶节点包括编号为{7,15}的训练样本,因此把该叶节点类别设置为”好瓜“,此时验证集中编号为{4,8,11,12}的样本被正确分类,验证集精度为 4 7 × 100 \frac{4}{7} \times 100%= 57.1% > 42.9% 74×100,所以将该节点进行剪枝,将其设置为叶节点。
-
然后考察节点(5),将其领衔的子树替换为叶节点,则替换后的叶节点包含编号为{6,7,15}的训练数据,叶节点类别表记为”好瓜“,此时验证集中编号为{4,8,11,12}的样本被正确分类,验证集精度为 4 7 × 100 \frac{4}{7} \times 100%= 57.1% 74×100,精度并没有提升,于是可以不进行剪枝。
-
对节点(2),若将其领衔的子树替换为叶节点,则替换后的叶节点包含编号为{1,2,3,14}的训练数据,叶节点标记为好瓜,此时验证集中编号为{4,5,8,11,12}的样本被正确分类,验证集精度为 5 7 × 100 \frac{5}{7} \times 100%= 71.4% > 57.1% 75×100,所以将该节点进行剪枝,将其设置为叶节点。
-
对节点(3),若将其领衔的子树替换为叶节点,则替换后的叶节点包含编号为{6,7,15,17}的训练数据,叶节点标记为好瓜,此时验证集中编号为{ 4,5,8,11,12 }的样本被正确分类,验证集精度为 5 7 × 100 \frac{5}{7} \times 100%= 71.4% 75×100,精度并没有提升,于是可以不进行剪枝。
-
对节点(1),若将其领衔的子树替换为叶节点,则替换后的叶节点包含编号为{1,2,3,6,7,10,14,15,16,17}的训练数据,叶节点标记为好瓜,此时验证集中编号为{ 4,5,8 }的样本被正确分类,验证集精度为 5 7 × 100 % = 42.9 % < 71.4 % \frac{5}{7} \times 100 \% = 42.9\% < 71.4\% 75×100%=42.9%<71.4%,精度未得到提高,所以不进行剪枝。
最终基于后剪枝策略从表4.2数据所生成的决策树如下图所示,其验证集精度为71.4%。
总结:
1.后剪枝决策树的欠拟合风险很小,泛化西宁嗯往往优于预剪枝决策树。但后剪枝过程是在生成完全决策树之后进行的,并且要自底向上地对树中的所有非叶节点进行逐一考察,因此其训练时间开销比未剪枝决策树和预剪枝决策树都要大得多。
2.预剪枝决策树精度没有提升,则进行剪枝操作;
后剪枝决策树精度没有提升,则不进行剪枝操作;
原因:减少多余的操作。
二、连续与缺失值
1.连续值处理
由于连续属性的可取值数目不再有限,因此,不能直接根据连续属性的可取值来对节点进行划分。此时,最简单的策略时采用“二分法(bi-partition)”对连续属性进行处理。
处理操作:给定样本集D和连续属性a,假定a在D上出现了n个不同的取值,将这些值从小到大进行排序,记为 a 1 , a 2 , . . . , a n {a^1,a^2,...,a^n} a1,a2,...,an。基于划分点 t 可将D分为子集 D t — D_t^— Dt—和 D t + D_t^+ Dt+,其中 D t — D_t^— Dt—包含哪些在属性a上取值不大于 t 的样本,而 D t + D_t^+ Dt+则包含哪些在属性a上取值大于 t 的样本。因此,对连续属性a,我们可考察包含n - 1个元素的候选划分点集合:
T a = { a i + a i + 1 2 ∣ 1 ≤ i ≤ n − 1 } T_a = \{\frac{a^i+a^{i+1}}{2} \quad|\quad 1\leq i \leq n-1 \} Ta={
2ai+ai+1∣1≤i≤n−1}
即把区间 [ a i , a i = 1 ) ] [a^i,a^{i=1})] [ai,ai=1)]的中位点 a i + a i + 1 2 \frac{a^i+a^{i+1}}{2} 2ai+ai+1做为候选划分点。然后,我们就可以像离散属性值一样来考察这些划分点,选取最优的划分点进行样本集合的划分。
我们以增添了两个连续属性“密度”和“含糖率”的西瓜数据集为例,如下表所示,用这个数据集来生成一颗决策树。
以信息增益构造树的规则为例:
将根节点视为叶节点时的信息增益为:
E n t ( D ) = − ∑ k = 1 2 p k l o g 2 p k = − ( 8 17 l o g 2 8 17 + 9 17 l o g 2 9 17 ) = 0.998 Ent(D)=-\sum_{k=1}^{2}p_klog_2p_k=-(\frac{8}{17}log_2 \frac{8}{17} + \frac{9}{17}log_2 \frac{9}{17}) = 0.998 Ent(D)=−k=1∑2pklog2pk=−(178log2178+179log2179)=0.998
★特征“密度”:
-
决策树开始学习时,根节点包含的17个训练样本在“密度”特征上取值均不同。我们先把“密度”这些值从小到大排序:
T s o r t = { 0.243 , 0.245 , 0.343 , 0.360 , 0.403 , 0.437 , 0.481 , 0.556 , 0.593 , 0.608 , 0.634 , 0.639 , 0.657 , 0.666 , 0.697 , 0.719 , 0.774 } T_{sort} = \{0.243,0.245,0.343,0.360,0.403,0.437,0.481,0.556,0.593,0.608,0.634,0.639,0.657,0.666,0.697,0.719,0.774\} Tsort={ 0.243,0.245,0.343,0.360,0.403,0.437,0.481,0.556,0.593,0.608,0.634,0.639,0.657,0.666,0.697,0.719,0.774}
-
根据上面 T a T_a Ta的计算公式,,依次计算相邻两位的平均值,计算好后总计 n - 1 位:
T m i d = { 0.244 , 0.294 , 0.351 , 0.381 , 0.420 , 0.459 , 0.518 , 0.574 , 0.600 , 0.621 , 0.636 , 0.648 , 0.661 , 0.681 , 0.708 , 0.746 } T_{mid} =\{0.244,0.294,0.351,0.381,0.420,0.459,0.518,0.574,0.600,0.621,0.636,0.648,0.661,0.681,0.708,0.746\} Tmid={ 0.244,0.294,0.351,0.381,0.420,0.459,0.518,0.574,0.600,0.621,0.636,0.648,0.661,0.681,0.708,0.746}
-
⨀ \bigodot ⨀当 t = 0.244时:
D t — = { 0.243 } D_t^— = \{0.243 \} Dt—={ 0.243}
D t + = { 0.245 , 0.343 , 0.360 , 0.403 , 0.437 , 0.481 , 0.556 , 0.593 , 0.608 , 0.634 , 0.639 , 0.657 , 0.666 , 0.697 , 0.719 , 0.774 } D_t^+ = \{0.245,0.343,0.360,0.403,0.437,0.481,0.556,0.593,0.608,0.634,0.639,0.657,0.666,0.697,0.719,0.774\} Dt+={ 0.245,0.343,0.360,0.403,0.437,0.481,0.556,0.593,0.608,0.634,0.639,0.657,0.666,0.697,0.719,0.774}
E n t ( D t — ) = − ( 0 l o g 2 0 + 1 l o g 2 1 ) = 0 Ent(D_t^—) = -(0 log_2 0 + 1 log_2 1) = 0 Ent(Dt—)=−(0log20+1log21)=0
E n t ( D t + ) = − ( 8 16 l o g 2 8 16 + 8 16 l o g 2 8 16 ) = 1 Ent(D_t^+) = -(\frac{8}{16} log_2 \frac{8}{16} + \frac{8}{16} log_2 \frac{8}{16}) = 1 Ent(Dt+)=−(168log2168+168log2168)=1
∴ G a i n ( D , 密 度 , 0.244 ) = 0.998 − ( 1 17 × 0 + 16 17 × 1 ) = 0.057 \therefore Gain(D,密度,0.244)=0.998-(\frac{1}{17} \times 0 + \frac{16}{17} \times 1) = 0.057 ∴Gain(D,密度,0.244)=0.998−(171×0+1716×1)=0.057
⨀ \bigodot ⨀当 t = 0.294时:
D t — = { 0.243 , 0.245 } D_t^— = \{0.243,0.245\} Dt—={ 0.243,0.245}
D t + = { 0.343 , 0.360 , 0.403 , 0.437 , 0.481 , 0.556 , 0.593 , 0.608 , 0.634 , 0.639 , 0.657 , 0.666 , 0.697 , 0.719 , 0.774 } D_t^+ = \{0.343,0.360,0.403,0.437,0.481,0.556,0.593,0.608,0.634,0.639,0.657,0.666,0.697,0.719,0.774\} Dt+={ 0.343,0.360,0.403,0.437,0.481,0.556,0.593,0.608,0.634,0.639,0.657,0.666,0.697,0.719,0.774}
E n t ( D t — ) = − ( 0 l o g 2 0 + 2 2 l o g 2 2 2 ) = 0 Ent(D_t^—) = -(0 log_2 0 + \frac{2}{2} log_2 \frac{2}{2}) = 0 Ent(D