决策树 -- 简介

        决策树(decision tree)一般都是自上而下的来生成的。每个决策或事件(即自然状态)都可能引出两个或多个事件,导致不同的结果,把这种决策分支画成图形很像一棵树的枝干,故称决策树。

决策树是一种有监管学习的分类方法。决策树的生成算法有 ID3 、C4.5 和 CART(Classification And Regression Tree)等,CART的分类效果一般优于其他决策树。

        决策树的决策过程需要从决策树的根节点开始,待测数据与决策树中的特征节点进行比较,并按照比较结果选择选择下一比较分支,直到叶子节点作为最终的决策结果。

        决策树一般流程

                1、收集数据

                2、准备数据(数值型数据必须离散化)

                3、分析数据

                4、训练数据

                5、学习数据,使用经验树计算错误率

       构建决策树由以下三部分所构成 

                1、特征选择

                2、决策树生成

                3、决策树剪枝

特征选择阶段

为了解释清楚各个数学概念,引入例子

        上表有15个样本数据表。数据包括贷款申请人的4个特征:年龄、有工作与否、有房子与否、信贷情况,其中最后一列类别的意思是:是否同意发放贷款,这个就是决策树最后要给出的结论,即目标属性——是否发放贷款,即决策树最末端的叶子节点只分成2类:同意发放贷款与不同意发放贷款。

信息熵(entropy)

        信息熵是用来衡量一个随机变量出现的期望值。如果信息的不确定性越大,熵的值也就越大,出现的各种情况也就越多。

        其中,S为所有事件集合,p为发生概率,c为特征总数。

        注意:熵是以2进制位的个数来度量编码长度的,因此熵的最大值是log2C。

其中pi表示第i个类别在整个训练数据中出现的概率,可以用属于此类别元素的数量除以训练数据(即样本数据)总数量作为估计。

具体问题具体分析:是否发放贷款,将9个发放归为一类,剩余6个不发放归为一类,这样进行分类的信息熵为:

信息增益(information gain)

        信息增益是指信息划分前后的熵的变化,也就是说由于使用这个属性分割样例而导致的期望熵降低。也就是说,信息增益就是原有信息熵与属性划分后信息熵(需要对划分后的信息熵取期望值)的差值,具体计算法如下:

        其中,第二项为属性A对S划分的期望信息。

具体问题具体分析

        年龄为已知条件的条件熵为

       以年龄为条件的信息增益为

        

有工作的信息增益

       有房子的信息增益

       信贷情况的信息增益

        最后比较各特征的信息增益值,对于特征A3有自己房子的信息增益值最大,所以选择特征A3作为最优特征。

由于特征A3(有自己房子)的信息增益值最大,所以选择特征A3作为根节点的特征。它将训练数据集划分为两个子集D1(A3取值为是)和D2(A3取值为否)。由于D1只有同一类样本点,可以明确要贷款给D1,所以它成为一个叶节点,节点类标记为“是”。

对于D2则需要从特征A1(年龄),A2(有工作)和A4(信贷情况)中选择新的特征。计算各个特征的信息增益:


选择信息增益最大的特征A2(有工作)作为节点特征。A2有2个取值,一个对应“是”(有工作)的子节点,包含3个样本,他们属于同一类,所以这是一个叶节点,类标记为“是”;另一个对应“否”(无工作)的子节点,包含6个样本,属于同一类,这也是一个叶节点,类标记为“否”。

换句话有15个贷款人,经过是否有房这一筛选条件,有房子的6个人能够贷款。剩余9个人需要进一步筛选,以是否有工作为筛选条件,有工作的3个人可以贷款,无工作的6个人不能够贷款。

        该决策树只用了两个特征(有两个内部结点),以有自己的房子作为首要判决条件,然后以有工作作为判决条件是否可以贷款。

决策树生成阶段

决策树学习比较典型的有三种算法:ID3算法、 C4.5算法和CART算法。

一、ID3算法

        ID3算法由Ross Quinlan发明,建立在“奥卡姆剃刀”的基础上:越是小型的决策树越优于大的决策树(be simple简单理论)。

        ID3算法中根据信息增益评估和选择特征,每次选择信息增益最大的特征作为判断模块建立子结点。

        ID3算法可用于划分标称型数据集,没有剪枝的过程,为了去除过度数据匹配的问题,可通过裁剪合并相邻的无法产生大量信息增益的叶子节点(例如设置信息增益阀值)。

       使用信息增益的话其实是有一个缺点,那就是它偏向于具有大量值的属性。就是说在训练集中,某个属性所取的不同值的个数越多,那么越有可能拿它来作为分裂属性,而这样做有时候是没有意义的。

ID3算法步骤:

二、C4.5算法

        C4.5算法用信息增益率来选择属性,继承了ID3算法的优点。并在以下几方面对ID3算法进行了改进:

  • 用信息增益率来选择属性,克服了用信息增益选择属性偏向选择多值属性的不足;
  • 在构造树的过程中进行剪枝;
  • 能够完成对连续属性进行离散化;
  • 能够对不完整的数据进行处理。

        C4.5算法产生的分类规则易于理解、准确率较高;但效率低,因树构造过程中,需要对数据集进行多次的顺序扫描和排序。也是因为必须多次数据集扫描,C4.5只适合于能够驻留于内存的数据集。

        在实现过程中,C4.5算法在结构与递归上与ID3完全相同,区别只在于选取决决策特征时的决策依据不同,二者都有贪心性质:即通过局部最优构造全局最优。

C4.5算法步骤:

三、CART算法

        CART,即分类和回归树(classification and regression tree),也是一种应用很广泛的决策树学习方法。这是一种可以处理离散特征值和连续特征值的决策树,处理离散特征值使用分类决策树,处理连续特征值使用回归决策树。

        作为分类树时,其本质与ID3、C4.5并有多大区别,只是选择特征的依据不同而已。另外,CART算法建立的决策树一般是二叉树,即特征值只有yes or no的情况(个人认为并不是绝对的,只是看实际需要)。当CART用作回归树时,以最小平方误差作为划分样本的依据。

        基尼指数 (Gini)

分类树采用基尼指数选择最优特征。                                                                                                                                                                假设有K个类,样本点属于第k类的概率为pk,则概率分布的基尼指数定义为:

对于给定的样本集合D,其基尼指数为:


Ck是  D中 属于第k类 的样本子集,K是 类的个数。

CART分类树的算法步骤: 


决策树剪枝阶段

先剪枝:  
        通过提前停止树的构造,如通过决定在给定的节点不再分裂或划分训练元组的子集,而对树剪枝,一旦停止,该节点即成为树叶。在构造树时,可以使用诸如统计显著性、信息增益等度量评估分裂的优劣,如果划分一个节点的元组低于预先定义阈值的分裂,则给定子集的进一步划分将停止。但选取一个适当的阈值是困难的,较高的阈值可能导致过分简化的树,而较低的阈值可能使得树的简化太少。

后剪枝:

        它由完全生长的树剪去子树,通过删除节点的分支,并用树叶替换它而剪掉给定节点的子树,树叶用被替换的子树中最频繁的类标记。

  其中C4.5算法使用悲观剪枝方法,CART算法则为代价复杂度剪枝算法(后剪枝)。

  悲观剪枝法的基本思路是:设训练集生成的决策树是T,用T来分类训练集中的N的元组,设K为到达某个叶子节点的元组个数,其中分类错误地个数为J。由于树T是由训练集生成的,是适合训练集的,因此J/K不能可信地估计错误率。所以用(J+0.5)/K来表示。设S为T的子树,其叶节点个数为L(s)

        为到达此子树的叶节点的元组个数总和

        为此子树中被错误分类的元组个数之和。在分类新的元组时,则其错误分类个数为

        其标准错误表示为:

        当用此树分类训练集时,设E为分类错误个数,当下面的式子成立时,则删掉子树S,用叶节点代替,且S的子树不必再计算。

ID3算法 -- 实例

根据头发和声音怎么判断一位同学的性别。

头发 声音 性别
  1. from math import log
  2. import operator
  3. def calcShannonEnt(dataSet): # 计算数据的熵(entropy)
  4. numEntries=len(dataSet) # 数据条数
  5. labelCounts={}
  6. for featVec in dataSet:
  7. currentLabel=featVec[-1] # 每行数据的最后一个字(类别)
  8. if currentLabel not in labelCounts.keys():
  9. labelCounts[currentLabel]=0
  10. labelCounts[currentLabel]+=1 # 统计有多少个类以及每个类的数量
  11. shannonEnt=0
  12. for key in labelCounts:
  13. prob=float(labelCounts[key])/numEntries # 计算单个类的熵值
  14. shannonEnt-=prob*log(prob,2) # 累加每个类的熵值
  15. return shannonEnt
  16. def createDataSet(): # 创造示例数据
  17. dataSet = [['长', '粗', '男'],
  18. ['短', '粗', '男'],
  19. ['短', '粗', '男'],
  20. ['长', '细', '女'],
  21. ['短', '细', '女'],
  22. ['短', '粗', '女'],
  23. ['长', '粗', '女'],
  24. ['长', '粗', '女']]
  25. labels = ['头发','声音'] #两个特征
  26. return dataSet,labels
  27. def splitDataSet(dataSet,axis,value): # 按某个特征分类后的数据
  28. retDataSet=[]
  29. for featVec in dataSet:
  30. if featVec[axis]==value:
  31. reducedFeatVec =featVec[:axis]
  32. reducedFeatVec.extend(featVec[axis+1:])
  33. retDataSet.append(reducedFeatVec)
  34. return retDataSet
  35. def chooseBestFeatureToSplit(dataSet): # 选择最优的分类特征
  36. numFeatures = len(dataSet[0])-1
  37. baseEntropy = calcShannonEnt(dataSet) # 原始的熵
  38. bestInfoGain = 0
  39. bestFeature = -1
  40. for i in range(numFeatures):
  41. featList = [example[i] for example in dataSet]
  42. uniqueVals = set(featList)
  43. newEntropy = 0
  44. for value in uniqueVals:
  45. subDataSet = splitDataSet(dataSet,i,value)
  46. prob =len(subDataSet)/float(len(dataSet))
  47. newEntropy +=prob*calcShannonEnt(subDataSet) # 按特征分类后的熵
  48. infoGain = baseEntropy - newEntropy # 原始熵与按特征分类后的熵的差值
  49. if (infoGain>bestInfoGain): # 若按某特征划分后,熵值减少的最大,则次特征为最优分类特征
  50. bestInfoGain=infoGain
  51. bestFeature = i
  52. return bestFeature
  53. def majorityCnt(classList): #按分类后类别数量排序,比如:最后分类为2男1女,则判定为男;
  54. classCount={}
  55. for vote in classList:
  56. if vote not in classCount.keys():
  57. classCount[vote]=0
  58. classCount[vote]+=1
  59. sortedClassCount = sorted(classCount.items(),key=operator.itemgetter(1),reverse=True)
  60. return sortedClassCount[0][0]
  61. def createTree(dataSet,labels):
  62. classList=[example[-1] for example in dataSet] # 类别:男或女
  63. if classList.count(classList[0])==len(classList):
  64. return classList[0]
  65. if len(dataSet[0])==1:
  66. return majorityCnt(classList)
  67. bestFeat=chooseBestFeatureToSplit(dataSet) #选择最优特征
  68. bestFeatLabel=labels[bestFeat]
  69. myTree={bestFeatLabel:{}} #分类结果以字典形式保存
  70. del(labels[bestFeat])
  71. featValues=[example[bestFeat] for example in dataSet]
  72. uniqueVals=set(featValues)
  73. for value in uniqueVals:
  74. subLabels=labels[:]
  75. myTree[bestFeatLabel][value]=createTree(splitDataSet\
  76. (dataSet,bestFeat,value),subLabels)
  77. return myTree
  78. if __name__=='__main__':
  79. dataSet, labels=createDataSet() # 创造示列数据
  80. print(createTree(dataSet, labels)) # 输出决策树模型结果

输出结果为:

  1. {'声音': {'细': '女', '粗': {'头发': {'短': '男', '长': '女'}}}}

      这个结果的意思是:首先按声音分类,声音细为女生;然后再按头发分类:声音粗,头发短为男生;声音粗,头发长为女生。 

Python机器学习算法 — 决策树(Decision Tree)的更多相关文章

  1. 【机器学习算法-python实现】决策树-Decision tree(1) 信息熵划分数据集

    (转载请注明出处:http://blog.csdn.net/buptgshengod) 1.背景 决策书算法是一种逼近离散数值的分类算法,思路比較简单,并且准确率较高.国际权威的学术组织,数据挖掘国际 ...

  2. 【机器学习算法-python实现】决策树-Decision tree(2) 决策树的实现

    (转载请注明出处:http://blog.csdn.net/buptgshengod) 1.背景      接着上一节说,没看到请先看一下上一节关于数据集的划分数据集划分.如今我们得到了每一个特征值得 ...

  3. 机器学习算法实践:决策树 (Decision Tree)(转载)

    前言 最近打算系统学习下机器学习的基础算法,避免眼高手低,决定把常用的机器学习基础算法都实现一遍以便加深印象.本文为这系列博客的第一篇,关于决策树(Decision Tree)的算法实现,文中我将对决 ...

  4. 数据挖掘 决策树 Decision tree

    数据挖掘-决策树 Decision tree 目录 数据挖掘-决策树 Decision tree 1. 决策树概述 1.1 决策树介绍 1.1.1 决策树定义 1.1.2 本质 1.1.3 决策树的组 ...

  5. (ZT)算法杂货铺——分类算法之决策树(Decision tree)

    https://www.cnblogs.com/leoo2sk/archive/2010/09/19/decision-tree.html 3.1.摘要 在前面两篇文章中,分别介绍和讨论了朴素贝叶斯分 ...

  6. 机器学习-决策树 Decision Tree

    咱们正式进入了机器学习的模型的部分,虽然现在最火的的机器学习方面的库是Tensorflow, 但是这里还是先简单介绍一下另一个数据处理方面很火的库叫做sklearn.其实咱们在前面已经介绍了一点点sk ...

  7. 决策树decision tree原理介绍_python sklearn建模_乳腺癌细胞分类器(推荐AAA)

    sklearn实战-乳腺癌细胞数据挖掘(博主亲自录制视频) https://study.163.com/course/introduction.htm?courseId=1005269003& ...

  8. Python机器学习算法 — 朴素贝叶斯算法(Naive Bayes)

    朴素贝叶斯算法 -- 简介 朴素贝叶斯法是基于贝叶斯定理与特征条件独立假设的分类方法.最为广泛的两种分类模型是决策树模型(Decision Tree Model)和朴素贝叶斯模型(Naive Baye ...

  9. 决策树Decision Tree 及实现

    Decision Tree 及实现 标签: 决策树熵信息增益分类有监督 2014-03-17 12:12 15010人阅读 评论(41) 收藏 举报  分类: Data Mining(25)  Pyt ...

随机推荐

  1. QueryParser

    [概述] 其他工具类使用比较方便,但不够灵活.QueryParser也实现了较多的匹配方式. [QueryParser的应用] /** * 使用QueryParser进行查询 * @throws Pa ...

  2. 用C# ASP.net将数据库中的数据表导出到Excel中

    需要用到组件GridView和一个button即可. 给GridView添加一个数据源, 选择你想要的数据库中的表的字段,添加成功后GridView中就显示数据. 再添加一个button,双击控件添加 ...

  3. Rsync文件同步服务器配置

    rsync 是一个Unix/Linux系统下的文件同步和传输工具.rsync是用 “rsync 算法”提供了一个客户机和远程文件服务器的文件同步的快速方法.可以用来做备份或镜像.一.配置文件rsync ...

  4. 前端开发:JavaScript---DOM & BOM

    DOM:Document Object Model  文档对象类型 模态框案例 <!DOCTYPE html> <html lang="en"> <h ...

  5. tyvj1031 热浪

    背景 USACO OCT09 9TH 描述 德克萨斯纯朴的民眾们这个夏天正在遭受巨大的热浪!!!他们的德克萨斯长角牛吃起来不错,可是他们并不是很擅长生產富含奶油的乳製品.Farmer John此时以先 ...

  6. 洛谷——P1007 独木桥

    P1007 独木桥 题目背景 战争已经进入到紧要时间.你是运输小队长,正在率领运输部队向前线运送物资.运输任务像做题一样的无聊.你希望找些刺激,于是命令你的士兵们到前方的一座独木桥上欣赏风景,而你留在 ...

  7. java基础标识符,关键字,常量

    1关键字1.1关键字的概述Java的关键字对java的编译器有特殊的意义,他们用来表示一种数据类型,或者表示程序的结构等,关键字不能用作变量名.方法名.类名.包名.2标识符2.1什么是标识符就是程序员 ...

  8. Check ini style config tool

    INI style config is like below [section] # comment key = value Sometimes we want to check the config ...

  9. 在ASP.NET Core 中使用Cookie中间件 (.net core 1.x适用)

    在ASP.NET Core 中使用Cookie中间件 ASP.NET Core 提供了Cookie中间件来序列化用户主题到一个加密的Cookie中并且在后来的请求中校验这个Cookie,再现用户并且分 ...

  10. hibernate之多对一单向关联

    一个工作组(Group)里能够有多个用户(User),一个User仅仅属于一个Group,这是典型的多对一的关系. 在多对一的关系中正确的数据库设计是在多的这方(在这里是User这方)加一个Group ...