决策树之 C4.5 算法

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u013761665/article/details/51840361

前言

由于 C4.5 算法是建立在 ID3 算法基础之上的,所以在讲解 C4.5 的时候,会有很多与 ID3 重合的内容,这里就不过多冗余地说明了。本文旨在阐明 ID3 存在的问题,以及 C4.5 的改进方案。如果你对于 ID3 中的相关数学公式及概念还有些迷惑,欢迎移步至《决策树之 ID3 算法》。


版权说明

著作权归作者所有。
商业转载请联系作者获得授权,非商业转载请注明出处。
本文作者:Q-WHai
发表日期: 2016年7月6日
本文链接:http://blog.csdn.net/lemon_tree12138/article/details/51840361
来源:CSDN
更多内容:分类 >> 数据挖掘


C4.5

决策树构建分析

我们说 C4.5 算法是对 ID3 算法的改进,既然是改进,那么必然是解决了一些问题,而且这些问题还是比较突出的。
1. 解决了信息增益(IG)的缺点
2. 解决了连续变量问题

IG 的缺点及解决方案

上一篇说 ID3 算法时,了解到 IG 是描述某一个特征属性的存在与否,对总体信息熵的变化量影响。通过 IG 的公式(如果你不记得 IG 的公式,欢迎移步至《决策树之 ID3 算法》),可以推测出,当某一个时刻总的信息熵固定时,只要条件熵(就是某一特征属性的信息熵) Entropy(S|T) 越小,那么 IG 的值就越大。通过条件熵的计算公式,又可以推测出,如果某一个特性属性的取值越多,那么这个条件熵的值就会越小。从而,采用 IG 最大法选择构建决策,在某一程度上可以理解成选择多取值的特征属性。对于这个问题,C4.5 的做法是引入分裂信息,然后计算信息增益率(IGR)。

IGR=IGIV
(其中,IG 为信息增益,IV 为分裂信息)
IV=ip(vi)log2p(vi)
(其中, vi 为某一特征属性下的第 i 个分支属性)

连续变量问题

在 ID3 中,我们不能解决连续变量问题,比如把之前的温度属性的值修改成一些整数类型的变量时,ID3 的做法就是对每一个不同值的变量进行分开计算,这样就出现了一个问题,ID3 构建的决策树中产生了过多的分支。这个时候,你可能会想说,如果把这些值修改成某一个域值,让小于等于这个域值的数据放在决策树的左边,大于这个域值的数据放在决策树的右边。C4.5 中就是这么干的,只是 C4.5 在寻找这个域值时,更加合理。

训练数据集

假设我们如下训练数据集

Day OutLook Temperature Humidity Wind PlayGolf
1 Sunny 85 85 False No
2 Sunny 80 90 True No
3 Overcast 83 78 False Yes
4 Rainy 70 96 False Yes
5 Rainy 68 80 False Yes
6 Rainy 65 70 True No
7 Overcast 64 65 True Yes
8 Sunny 72 95 False No
9 Sunny 69 70 False Yes
10 Rainy 75 80 False Yes
11 Sunny 75 70 True Yes
12 Overcast 72 90 True Yes
13 Overcast 81 75 False Yes
14 Rainy 71 80 True No

决策树构建过程

根据 C4.5 算法的原理及步骤绘制出如下过程图:
这里写图片描述

计算步骤

虽然上图中需要计算的量有很多,但是,有很量的计算在《决策树之 ID3 算法》一文中,讲解得也很详细了,所以这里我不再说明。需要说明的只有两个地方:IV 和 连续变量的域值计算。

IV(T) & IGR(T)

从上面的分裂信息的计算公式中,可以看到分裂信息的计算是针对某一个特征属性内部而言的。比如现在针对特征属性 OutLook 这一特征属性而言有如下分裂信息的分布情况:

Sunny Overcast Rainy
结果总数 5 4 5

那么 OutLook 的分裂信息 IV(OutLook) 就可以这样来计算:
IV(OutLook)=514log2514414log2414514log2514=1.577406
于是,再有
IGR(OutLook)=IGIV=0.246751.577406=0.156428

连续变量的域值

上面说的都是针对离散变量问题的解决思路及过程,如果某一个特征属性的变量值不能或是不合适使用离散变量来处理,又该怎么做呢?比如在之前 ID3 算法的文章中使用的温度属性,这个属性的变量值使用连续变量应该更合适一些,最基本的逻辑就是温度达到多少算是 Hot,达到多少算是 Cool 呢?这个不好衡量,可是如果使用连续变量就要合理得多。
可是 ID3 算法在对连续变量的处理上,表现很糟糕。在 C4.5 中是通过如下方法解决的。
假设我们选择了温度属性,则被提取的关键数据为:[[85, No], [80, No], [83, Yes], [70, Yes], [68, Yes], [65, No], [64, Yes], [72, No], [69, Yes], [75, Yes], [75, Yes], [72, Yes], [81, Yes], [71, No]]
现在我们对这批数据进行从小到大进行排序,排序后数据集就变成:
[[64, Yes], [65, No], [68, Yes], [69, Yes], [70, Yes], [71, No], [72, No], [72, Yes], [75, Yes], [75, Yes], [80, No], [81, Yes], [83, Yes], [85, No]]
绘制成如下图例:
这里写图片描述
当我们拿到一个已经排好序的(温度,结果)的列表之后,分别计算被某个单元分隔的左边和右边的分裂信息,计算结果如下:
比如现在计算 index = 4 时的分裂信息。则:
IV(v4)=IV([4,1],[5,4])=514IV([4,1])+914IV([5,4])
IV(v4)=514(45log24515log215)+914(59log25949log249)=0.89

这里写图片描述
这时就可以选取最大分裂信息的位置当成此时的域值,也就是 68。
然后,此时温度的分裂就是按照小于等于 68 和大于 68 进行划分。

决策树构建结果

通过上面的训练数据集及 C4.5 构建算法,我们构建了一棵如下的 C4.5 决策树。
这里写图片描述


Ref


GitHub download

此处为本文的算法实现,采用的编程语言为 Java。算法也是在不断重构及优化,如果你对此感兴趣,欢迎 star.
- https://github.com/MachineLeanring/MachineLearningC4.5

猜你喜欢

转载自blog.csdn.net/u013761665/article/details/51840361