在2006年12月召开的 IEEE 数据挖掘国际会议上(ICDM, International Conference on Data Mining),与会的各位专家选出了当时的十大数据挖掘算法( top 10 data mining algorithms ),能够参见文献【1】。本博客已经介绍过的位列十大算法之中的算法包括:node
本文主要介绍机器学习中的决策树模型。决策树模型是一类算法的集合,在数据挖掘十大算法中,具体的决策树算法占有两席位置,即C4.5和CART算法,本文都会介绍到它们。算法
欢迎关注白马负金羁的博客 http://blog.csdn.net/baimafujinji,为保证公式、图表得以正确显示,强烈建议你从该地址上查看原版博文。本博客主要关注方向包括:数字图像处理、算法设计与分析、数据结构、机器学习、数据挖掘、统计分析方法、天然语言处理。数据结构
分类(Classification)任务就是肯定对象属于哪一个预约义的目标类。分类问题不只是一个广泛存在的问题,并且是其余更加复杂的决策问题的基础,更是机器学习和数据挖掘技术中最庞大的一类算法家族。咱们前面介绍过的不少算法(例如SVM,朴素贝叶斯等)均可以用来解决分类问题。做为本文的开始,咱们首先来简单回顾一下什么是分类。dom
假设咱们如今有以下表所示的一个属性集(feature set),它收集了几个病患的症状和对应的病症。症状包括头疼的程度、咳嗽的程度、体温以及咽喉是否肿痛,这些症状(feature)的组合就对应一个病症的分类(Cold 仍是 Flu)。机器学习
分类问题的本质就是当给定这样一个数据集后,要求咱们训练出(或创建)一个模型f。当出现一组新的特征向量时,要求咱们预测(或判断)拥有这样一组特征向量的对象应当属于哪一个类别。就咱们如今给出的例子而言,假设你是一名医生,如今收治了一位新的病患,而后你经过问诊得知他的一些症状(包括头疼的程度、咳嗽的程度、体温以及咽喉是否肿痛),而后你就要根据你已经创建好的模型来判断该病人得的究竟是Cold(普通感冒)仍是Flu(流行性感冒)。学习
分类问题的类别数目能够是两类也能够是多类。二分类问题是最简单的分类问题,而多分类问题模型能够在二分类模型的基础上进行构建。咱们在前面文章中一直使用的鸢尾花数据集就是一个典型的多分类问题,问题的最终目标是判断给定一朵花,它应该属于setosa、versicolor和virginica中的哪一类。测试
决策树是一种用于对实例进行分类的树形结构。决策树由节点(node)和有向边(directed edge)组成。节点的类型有两种:内部节点和叶子节点。其中,内部节点表示一个特征或属性的测试条件(用于分开具备不一样特性的记录),叶子节点表示一个分类。大数据
一旦咱们构造了一个决策树模型,以它为基础来进行分类将是很是容易的。具体作法是,从根节点开始,地实例的某一特征进行测试,根据测试结构将实例分配到其子节点(也就是选择适当的分支);沿着该分支可能达到叶子节点或者到达另外一个内部节点时,那么就使用新的测试条件递归执行下去,直到抵达一个叶子节点。当到达叶子节点时,咱们便获得了最终的分类结果。优化
下图是一个决策树的示例(注意咱们仅用了两个feature就对数据集中的5个记录实现了准确的分类): ui
Hunt算法是一种采用局部最优策略的决策树构建算法,它同时也是许多决策树算法的基础,包括ID三、C4.5和CART等。该算法的具体执行步骤以下:
在Hunt算法中,经过将训练记录相继划分红较纯的子集,以递归方式创建决策树。设 Dt 是与结点 t 相关联的训练记录集,而y={y1,y2,⋯,yc}是类标号,Hunt算法的递归定义以下:
(1) 若是 Dt 中全部记录都属于同一个类,则 t 是叶结点,用 yt 标记。
(2) 若是 Dt 中包含属于多个类的记录,则选择一个属性测试条件(attribute test condition),将记录划分红较小的子集。对于测试条件的每一个输出,建立一个子女结点,并根据测试结果将 Dt 中的记录分布到子女结点中。而后,对于每一个子女结点,递归地调用该算法。
为了演示这方法,咱们选用文献【2】中的一个例子来加以说明:预测贷款申请者是会按时归还贷款,仍是会拖欠贷款。对于这个问题,训练数据集能够经过考察之前贷款者的贷款记录来构造。在下图所示的例子中,每条记录都包含贷款者的我的信息,以及贷款者是否拖欠贷款的类标号。
该分类问题的初始决策树只有一个结点,类标号为“拖欠货款者=否”(见图a),意味大多数贷款者都按时归还贷款。然而,该树须要进一步的细化,由于根结点包含两个类的记录。根据“有房者”测试条件,这些记录被划分为较小的子集,如图b所示。接下来,对根结点的每一个子女递归地调用Hunt算法。从下图给出的训练数据集能够看出,有房的贷款者都按时偿还了贷款,所以,根结点的左子女为叶结点,标记为“拖欠货款者二否”(见图b)。对于右子女,咱们须要继续递归调用Hunt算法,直到全部的记录都属于同一个类为止。每次递归调用所造成的决策树显示在图c和图d中。
若是属性值的每种组合都在训练数据中出现,而且每种组合都具备惟一的类标号,则Hunt 算法是有效的。可是对于大多数实际状况,这些假设太苛刻了,所以,须要附加的条件来处理如下的状况:
此外,在上面这个算法过程当中,你可能会疑惑:咱们是依据什么原则来选取属性测试条件的,例如为什第一次选择“有房者”来做为测试条件。事实上,若是咱们选择的属性测试条件不一样,那么对于同一数据集来讲所创建的决策树可能相差很大。以下图所示为基于前面预测病人是患了Cold仍是Flu的数据集所构建出来的另外两种状况的决策树:
事实上,在构建决策树时咱们须要关心的问题包括:
我会在接下来的部分回答上述这些问题。
构建一棵最优的决策树是一个NP难问题!因此咱们只能采用一些启发式策略来解决:
如今新的问题来了:如何评估节点的Impurity?一般可使用的指标有以下三个(实际应用时,只要选其中一个便可):
第一个能够用来评估节点Impurity的指标是Gini系数。对于一个给定的节点 t,它的Gini系数计算公式以下:
其中,p(j | t) is the relative frequency of class j at node t(即表示给定节点 t 中属于类 j 的记录所占的比例)。经过这个计算公式你能够看出:
说到这里,咱们插一句题外话(若是你对这部分Background无感能够跳过)。你在生活中有没有听过基尼系数这个名词?是的,基尼系数原本是经济学里的一个概念。基尼系数是1943年美国经济学家阿尔伯特·赫希曼根据劳伦茨曲线所定义的判断收入分配公平程度的指标。基尼系数是比例数值,在0和1之间,是国际上用来综合考察居民内部收入分配差别情况的一个重要分析指标。其具体含义是指,在所有居民收入中,用于进行不平均分配的那部分收入所占的比例。基尼系数最大为“1”,最小等于“0”。前者表示居民之间的收入分配绝对不平均,即100%的收入被一个单位的人所有占有了;然后者则表示居民之间的收入分配绝对平均,即人与人之间收入彻底平等,没有任何差别。但这两种状况只是在理论上的绝对化形式,在实际生活中通常不会出现。所以,基尼系数的实际数值只能介于0~1之间,基尼系数越小收入分配越平均,基尼系数越大收入分配越不平均。国际上一般把0.4做为贫富差距的警惕线,大于这一数值容易出现社会动荡。
选择最佳划分的度量一般是根据划分后子女结点不纯性的程度。不纯的程度越低,类分布就越倾斜。例如,类分布为 (0, 1)的结点具备零不纯性,而均衡分布(0.5, 0.5)的结点具备最高的不纯性。如今咱们回过头来看一个具体的计算例子。如今咱们一共有6个records,以二元分类问题不纯性度量值的比较为例,下图的意思表示有四个节点,而后分别计算了每个节点的GINI系数值(注意决策树中每个内节点都表示一种分支判断,也就能够将6个records分红几类,咱们这里讨论的是二元分类因此是分红两个子类):
从上面的例子能够看出,第一个结点,具备最低的不纯性度量值,接下来节点的不纯度度量值依次递增。为了肯定测试条件的效果,咱们须要比较父结点(划分前)的不纯程度和子女结点(划分后) 的不纯程度,它们的差越大,测试条件的效果就越好。增益Δ是一种能够用来肯定划分效果的标准:
其中,I(.) 是给定结点的不纯性度量,N是父结点上的记录总数,k是属性值的个数,N(vj)是与子女结点 vj 相关联的记录个数。决策树构建算法一般选择最大化增益Δ的测试条件,由于对全部的测试条件来讲,I(parent)是一个不变的值,因此最大化增益等价于最小化子女结点的不纯性度量的加权平均值。
考虑下面这个划分的例子。假设有两种方法将数据划分红较小的子集。划分前,Gini系数等于0.5,由于属于两个类(C0和C1)的记录个数相等。若是选择属性A来划分数据,节点N1的Gini系数为1−(4/7)2−(3/7)2=0.4898,而N2的Gini系数为1−(2/5)2−(3/5)2=0.48,派生节点的Gini系数的加权平均为(7/12)×0.4898+(5/12)×0.48=0.486。同理,咱们还能够计算属性B的Gini系数的加权平均为(7/12)×0.408+(5/12)×0.32=0.371。由于属性B具备更小的Gini系数,因此它比属性A更可取。
标称属性能够产生二元划分也能够产生多路划分,以下图所示。二元划分的Gini系数的计算与二元属性相似。对于车型属性第一种二元分类,{运动,豪华}的Gini系数是0.4922,而{家用}的Gini系数是0.375。这个划分的Gini系数加权平均是:
相似地,对第二种二元划分{运动}和{家用,豪华},Gini系数加权平均是0.167。第二种划分的Gini系数相对更低,由于其对应的子集的纯度更高。对于多路划分,须要计算每一个属性值的Gini系数。Gini({家用})=0.375,Gini({运动})=0,Gini({豪华})=0.219,因此多路划分的Gini系数加权平均值为:
多路划分的Gini系数比两个二元划分都小。这是由于二元划分实际上合并了多路划分的某些输出,天然下降了子集的纯度。
考虑下图所示的例子,其中测试条件“年收入≤v”用来划分拖欠贷款分类问题的训练记录。用穷举方法肯定 v 的值,将N个记录中全部的属性值都做为候选划分点。对每一个候选v,都要扫描一次数据集,统计年收入大于和小于v的记录数,而后计算每一个候迭的Gini系数,并从中选择具备最小值的候选划分点。这种方法的计算代价显然是高昂的,由于对每一个候选划分点计算 Gini系数须要O(N)次操做,因为有N个候选,总的计算复杂度为O(N2)。为了下降计算复杂度, 按照年收入将训练记录排序,所须要的时间为O(NlogN),从两个相邻的排过序的属性值中选择中间值做为候选划分点,获得候选划分点55, 65, 72等。不管如何,与穷举方法不一样,在计算候选划分点的Gini指标时,不需考察全部N个记录。
对第一个候选v=55,没有年收入小于$55K的记录,因此年收入<$55K的派生结点的Gini系数是0;另外一方面,年收入≥$55K的样本记录数目分别为3(类Yes)和7(类No)。如此一来,该结点的Gini系数是0.420。该候选划分的Gini系数的加权平均就等于0×0+1×0.42=0.42。
对第二个候选v=65,经过更新上一个候选的类分布,就能够获得该候选的类分布。更具体地说,新的分布经过考察具备最低年收入(即$60K)的记录的类标号获得。由于该记录的类标号是No因此类No的计数从0增长到1(对于年收入≤$65K),和从7降到6(对于年收入> $65K),类Yes的分布保持不变。新的候选划分点的加权平均Gini系数为0.4。
重复这样的计算,直到算出全部候选的Gini系数值。最佳的划分点对应于产生最小Gini系数值的点,即v=97。该过程代价相对较低,由于更新每一个候选划分点的类分布所需的时间是一个常数。该过程还能够进一步优化:仅考虑位于具备不一样类标号的两个相邻记录之间的候选划分点。例如,由于前三个排序后的记录(分别具备年收入$60K、 $70K和$75K)具备相同的类标号,因此最佳划分点确定不会在$60K和$75K之间,所以,候选划分点 v = $55K、 $65K、 $72K、 $87K、 $92K、 $110K、$122K、 $172K 和 $230K都将被忽略,由于它们都位于具备相同类标号的相邻记录之间。该方法使得候选划分点的个数从11个降到2个。
正如咱们前面已经提到的,评估节点的Impurity能够是三个标准中的任何一个。并且咱们已经介绍了Gini系数。
下面来谈谈另一个可选的标准:信息熵(entropy)。在信息论中,熵是表示随机变量不肯定性的度量。熵的取值越大,随机变量的不肯定性也越大。
设X是一个取有限个值的离散随机变量,其几率分布为
则随机变量X的熵定义为
在上式中,若是pi=0,则定义0log0=0。一般,上式中的对数以2为底或以e为底,这时熵的单位分别是比特(bit)或纳特(nat)。由定义可知,熵只依赖于 X 的分布,而与 X 的取值无关,因此也能够将X 的熵记做 H(p),即
条件熵H(Y|X)表示在已知随机变量X的条件下随机变量Y的不肯定性,随机变量X给定的条件下随机变量Y的条件熵(conditional entropy)H(Y|X),定义为X给定条件下Y的条件几率分布的熵对X的数学指望:
就咱们当前所面对的问题而言,若是给定一个节点 t,它的(条件)熵计算公式以下:
其中,p(j | t) is the relative frequency of class j at node t(即表示给定节点 t 中属于类 j 的记录所占的比例)。经过这个计算公式你能够看出:
仍是来看一个具体的计算例子,以下图所示(基本状况与前面介绍Gini系数时的例子相似,咱们再也不赘述):
以此为基础,咱们要来定义信息增益(Information Gain)以下:
其中,Parent Node, p is split into k partitions; ni is number of records in partition i.
与以前的状况相同,决策树构建算法一般选择最大化信息增益的测试条件来对节点进行划分。
使用信息增益的一个缺点在于:信息增益的大小是相对于训练数据集而言的。在分类问题困难时,即训练数据集的经验熵比较大时,信息增益会偏大。反之,信息增益会偏小。使用信息增益比(Information gain ratio)能够对这一问题进行校订。
因而,Higher entropy partitioning (large number of small partitions) is penalized!
给定一个节点t,它的分类偏差定义为:
由此公式可知:
话很少说,仍是一个简单的算例:
下图给出了二分类模型中,熵、Gini系数、分类偏差的比较状况。若是咱们采用二分之一熵12H(p)的时候,你会发现它与Gini系数将会至关接近。
咱们最后再来看一个Gini系数和分类偏差对比的例子:
来计算一下加权平均的Gini系数:
再来计算一下分类偏差:
可见在这个例子中,Gini improves ! However,Missclassification unchanged! 咱们会在下一篇文章中继续介绍关于ID三、C4.5和CART算法的内容,其中会更加具体地用到本文所介绍的各类纯度评判标准。
(未完,待续…)
【1】Wu, X., Kumar, V., Quinlan, J.R., Ghosh, J., Yang, Q., Motoda, H., McLachlan, G.J., Ng, A., Liu, B., Philip, S.Y. and Zhou, Z.H., 2008. Top 10 algorithms in data mining. Knowledge and information systems, 14(1), pp.1-37. (http://www.cs.uvm.edu/~icdm/algorithms/10Algorithms-08.pdf)
【2】Pang-Ning Tan, Michael Steinbach, Vipin Kumar, 数据挖掘导论,人民邮电出版社
【3】李航,统计学习方法,清华大学出版社
【4】明尼苏达大学Prof Vipin Kumar 和墨尔本大学Prof Rao Kotagiri的课程幻灯片材料
若是你对机器学习和数据挖掘感兴趣,你还能够参考个人高能资源帖:
【5】机器学习与数据挖掘网上资源搜罗
【6】机器学习与数据挖掘的学习路线图