女主宣言

今天小主为大家分享一篇转自简书的文章:关于数据分析、机器学习领域“决策树”的概念,读完这篇文章相信在我们日常工作中会有一定的启发。

PS:丰富的一线技术、多元化的表现形式,尽在“HULK一线技术杂谈”,点关注哦!

介绍

文章的结构:

  • 是什么?

  • 有什么算法?

  • 数学原理?

  • 编码实现算法?

1

是什么?

简单地理解,就是根据一些 feature 进行分类,每个节点提一个问题,通过判断,将数据分为几类,再继续提问。这些问题是根据已有数据学习出来的,再投入新数据的时候,就可以根据这棵树上的问题,将数据划分到合适的叶子上。

2

有什么算法?

常用的几种决策树算法有ID3、C4.5、CART:

ID3:选择信息熵增益最大的feature作为node,实现对数据的归纳分类。
C4.5:是ID3的一个改进,比ID3准确率高且快,可以处理连续值和有缺失值的feature。
CART:使用基尼指数的划分准则,通过在每个步骤最大限度降低不纯洁度,CART能够处理孤立点以及能够对空缺值进行处理。

3

数学原理?

ID3: Iterative Dichotomiser 3

下面这个数据集,可以同时被上面两颗树表示,结果是一样的,而我们更倾向于选择简单的树。
那么怎样做才能使得学习到的树是最简单的呢?

下面是 ID3( Iterative Dichotomiser 3 )的算法:

例如下面数据集,哪个是最好的 Attribute?

用熵Entropy来衡量:
E(S) 是数据集S的熵
i 指每个结果,即 No,Yes的概率

E越大意味着信息越混乱,我们的目标是要让E最小。
E在0-1之间,如果P+的概率在0.5, 此时E最大,这时候说明信息对我们没有明确的意义,对分类没有帮助。

但是我们不仅仅想要变量的E最小,还想要这棵树是 well organized。
所以用到 Gain:信息增益

意思是如果我后面要用这个变量的话,它的E会减少多少。

例如下面的数据集:

1. 先计算四个feature的熵E,及其分支的熵,然后用Gain的公式计算信息增益。

2. 再选择Gain最大的特征是 outlook。

3. 第一层选择出来后,各个分支再继续选择下一层,计算Gain最大的,例如分支 sunny 的下一层节点是 humidity。

C4.5

ID3有个局限是对于有大量数据的feature过于敏感,C4.5是它的一个改进,通过选择最大的信息增益率 gain ratio 来选择节点。而且它可以处理连续的和有缺失值的数据。

P’ (j/p) is the proportion of elements present at the position p, taking the value of j-th test.

例如 outlook 作为第一层节点后,它有 3 个分支,分别有 5,4,5 条数据,则 SplitInfo(5,4,5) = -5/14log(5,14)-4/14log(4,14)-5/14(5,14) ,其中 log(5,14) 即为 log2(5/14)。

下面是一个有连续值和缺失值的例子:

连续值
第一步计算 Gain,除了连续值的 humudity,其他步骤和前文一样。

要计算 humudity 的 Gain 的话,先把所有值升序排列:
{65, 70, 70, 70, 75, 78, 80, 80, 80, 85, 90, 90, 95, 96}
然后把重复的去掉:
{65, 70, 75, 78, 80, 85, 90, 95, 96}
如下图所示,按区间计算 Gain,然后选择最大的 Gain (S, Humidity) = 0.102

因为 Gain(S, Outlook) = 0 .246,所以root还是outlook:

缺失值
处理有缺失值的数据时候,用下图的公式:

例如 D12 是不知道的。

  1. 计算全集和 outlook 的 info,

2.  其中几个分支的熵如下,再计算出 outlook 的 Gain:

比较一下 ID3 和 C4.5 的准确率和时间:

accuracy :

execution time:

4

编码实现算法?

接下来以 C4.5 的代码为例:

  1. 定义数据:

def createDataSet():
    dataSet = [[0, 0, 0, 0, 'N'],
               [0, 0, 0, 1, 'N'],
               [1, 0, 0, 0, 'Y'],
               [2, 1, 0, 0, 'Y'],
               [2, 2, 1, 0, 'Y'],
               [2, 2, 1, 1, 'N'],
               [1, 2, 1, 1, 'Y']]
    labels = ['outlook', 'temperature', 'humidity', 'windy']
    return dataSet, labels

2. 计算熵:

def calcShannonEnt(dataSet):
    numEntries = len(dataSet)
    labelCounts = {}
    for featVec in dataSet:
        currentLabel = featVec[-1]
        if currentLabel not in labelCounts.keys():
            labelCounts[currentLabel] = 0
        labelCounts[currentLabel] += 1      # 数每一类各多少个, {'Y': 4, 'N': 3}
    shannonEnt = 0.0
    for key in labelCounts:
        prob = float(labelCounts[key])/numEntries
        shannonEnt -= prob * log(prob, 2)
    return shannonEnt

3. 选择最大的gain ratio对应的feature:

def chooseBestFeatureToSplit(dataSet):
    numFeatures = len(dataSet[0]) - 1                         #feature个数
    baseEntropy = calcShannonEnt(dataSet)              #整个dataset的熵
    bestInfoGainRatio = 0.0
    bestFeature = -1
    for i in range(numFeatures):
        featList = [example[i] for example in dataSet]  #每个feature的list
        uniqueVals = set(featList)                                   #每个list的唯一值集合                 
        newEntropy = 0.0
        splitInfo = 0.0
        for value in uniqueVals:
            subDataSet = splitDataSet(dataSet, i, value)  #每个唯一值对应的剩余feature的组成子集
            prob = len(subDataSet)/float(len(dataSet))
            newEntropy += prob * calcShannonEnt(subDataSet)
            splitInfo += -prob * log(prob, 2)
        infoGain = baseEntropy - newEntropy                #这个feature的infoGain
        if (splitInfo == 0): # fix the overflow bug
            continue
        infoGainRatio = infoGain / splitInfo                     #这个feature的infoGainRatio      
        if (infoGainRatio > bestInfoGainRatio):              #选择最大的gain ratio
            bestInfoGainRatio = infoGainRatio
            bestFeature = i                                              #选择最大的gain ratio对应的feature
    return bestFeature

4. 划分数据,为下一层计算准备:

def splitDataSet(dataSet, axis, value):
    retDataSet = []
    for featVec in dataSet:
        if featVec[axis] == value:                      #只看当第i列的值=value时的item
            reduceFeatVec = featVec[:axis]              #featVec的第i列给除去
            reduceFeatVec.extend(featVec[axis+1:])
            retDataSet.append(reduceFeatVec)            
    return retDataSet

5. 多重字典构建树:

def createTree(dataSet, labels):
    classList = [example[-1] for example in dataSet]         # ['N', 'N', 'Y', 'Y', 'Y', 'N', 'Y']
    if classList.count(classList[0]) == len(classList):
        # classList所有元素都相等,即类别完全相同,停止划分
        return classList[0]                                  #splitDataSet(dataSet, 0, 0)此时全是N,返回N
    if len(dataSet[0]) == 1:                                 #[0, 0, 0, 0, 'N']
        # 遍历完所有特征时返回出现次数最多的
        return majorityCnt(classList)
    bestFeat = chooseBestFeatureToSplit(dataSet)             #0-> 2   
        # 选择最大的gain ratio对应的feature
    bestFeatLabel = labels[bestFeat]                         #outlook -> windy     
    myTree = {bestFeatLabel:{}}                   
        #多重字典构建树{'outlook': {0: 'N'
    del(labels[bestFeat])                                    #['temperature', 'humidity', 'windy'] -> ['temperature', 'humidity']        
    featValues = [example[bestFeat] for example in dataSet]  #[0, 0, 1, 2, 2, 2, 1]     
    uniqueVals = set(featValues)
    for value in uniqueVals:
        subLabels = labels[:]                                #['temperature', 'humidity', 'windy']
        myTree[bestFeatLabel][value] = createTree(splitDataSet(dataSet, bestFeat, value), subLabels)
            # 划分数据,为下一层计算准备
    return myTree

6. 可视化决策树的结果:

dataSet, labels = createDataSet()
labels_tmp = labels[:]
desicionTree = createTree(dataSet, labels_tmp)
treePlotter.createPlot(desicionTree)

总结

决策树(decision tree)是一类常见的机器学习方法。决策树是一个预测模型;他代表的是对象属性与对象值之间的一种映射关系。树中每个节点表示某个对象,而每个分叉路径则代表的某个可能的属性值,而每个叶结点则对应从根节点到该叶节点所经历的路径所表示的对象的值。决策树仅有单一输出,若欲有复数输出,可以建立独立的决策树以处理不同输出。 数据挖掘中决策树是一种经常要用到的技术,可以用于分析数据,同样也可以用来作预测。

扫描下方二维码了解更多内容

决策树的python实现相关推荐

  1. python决策树实例_机器学习中的决策树及python实例

    一棵树在现实生活中有许多枝叶,事实上树的概念在机器学习也有广泛应用,涵盖了分类和回归.在决策分析中,决策树可用于直观地决策和作出决策.决策树,顾名思义,一个树状的决策模型.尽管数据挖掘与机器学习中常常 ...

  2. 决策树 python 结果画图_scikit-learn决策树的python实现以及作图

    decsion tree(决策树) 其中每个内部结点表示在一个属性上的测试,每个分支代表一个属性的输出,而每个树叶结点代表类或类的分布.树的最顶层是根节点 连续变量要离散化 机器学习中分类方法的一个重 ...

  3. python实现决策树归纳_决策树【python实现】

    决策树思维导图.jpg 0.周董歌词中的决策树 为什麼 别人在那看漫画 我却在学画画 对著钢琴说话 别人在玩游戏 我却靠在墙壁背我的ABC 拿王牌谈个恋爱 而我不想被你教坏 还是听妈妈的话吧 晚点再恋 ...

  4. 数据挖掘决策树python_机器学习之决策树ID3(python实现)

    机器学习中,决策树是一个预测模型:代表对象属性和对象值之间的一种映射关系.树中每个节点表示某个对象,而每个分叉表示某个可能的属性,每个叶子节点则对应从根节点到该叶子节点所经历的路径所表示的对象的值.决 ...

  5. 决策树剪枝python实现_决策树剪枝问题python代码

    决策树在生长过程中有可能长得过于茂盛,对训练集学习的很好,但对新的数据集的预测效果不好,即过拟合,此时生成的模型泛化能力较差.因此,我们需要对决策树进行剪枝,使得生成的模型具有较强的泛化能力. 为了检 ...

  6. 决策树 基于python实现ID3,C4.5,CART算法

    实验目录 实验环境 简介 决策树(decision tree) 信息熵 信息增益(应用于ID3算法) 信息增益率(在C4.5算法中使用) 基尼指数(被用于CART算法) 实验准备 数据集 算法大体流程 ...

  7. 决策树留一法python代码_机器学习模型2 决策树-基于Python sklearn的实现

    1.模型原理 (一)原理 1.原理:引入信息熵(不确定程度)的概念,通过计算各属性下的信息增益程度(信息增益越大,则意味着使用该属性来进行划分所获得的"纯度提升"越大),增益程度最 ...

  8. 机器学习之分类决策树与回归决策树—基于python实现

    大家好,我是带我去滑雪! 本期为大家介绍决策树算法,它一种基学习器,广泛应用于集成学习,用于大幅度提高模型的预测准确率.决策树在分区域时,会考虑特征向量对响应变量的影响,且每次仅使用一个分裂变量,这使 ...

  9. 《统计学习方法》—— 5.决策树(Python实现)

    本文主要是在阅读过程中对本书的一些概念摘录,包括一些个人的理解,主要是思想理解不涉及到复杂的公式推导.若有不准确的地方,欢迎留言指正交流 本文完整代码见 github : https://github ...

  10. 决策树分类python代码_分类算法-决策树 Decision Tree

    决策树(Decision Tree)是一个非参数的监督式学习方法,决策树又称为判定树,是运用于分类的一种树结构,其中的每个内部节点代表对某一属性的一次测试,每条边代表一个测试结果,叶节点代表某个类或类 ...

最新文章

  1. 代码写的烂,经常被同事怼,教你一招!
  2. python代码怎么运行-Python程序执行原理,python程序怎么运行的?
  3. java jvm 参数 -Xms -Xmx -Xmn -Xss 调优总结
  4. 分区脚本(fdisk)
  5. Oracle(21)—— Linux环境部署Oracle11g数据库
  6. springboot 各种日志打印
  7. 编程挑战:字符串的完美度
  8. 惜缘-致家乡的一位女孩[原创]
  9. 获得磁盘的飞鸽传书描述信息
  10. Java Socket编程中使用ObjectOutputStream 和 ObjectInputStream 出现问题
  11. 《趣学算法 [陈小玉]》学习笔记01
  12. Linux内核 设备树操作常用API【转】
  13. 优雅的使用springboot集成任务调度
  14. C Coding Standard
  15. 浪潮之颠一_读书笔记
  16. 单片机C语言程序设计实训100例:基于AVR+proteus仿真pdf
  17. 基于Java的超市水果管理系统_技术分享 - 基于JAVA SWING结合链表的水果超市管理系统...
  18. 大气数据计算机仿真算法,自适应光学系统中大气湍流的模型分析与计算机仿真...
  19. matlab插值函数 外插,02-函数插值--Matlab插值函数
  20. 蓝桥杯赛后总结与反思

热门文章

  1. 利用数据库来填充UltraWebTree
  2. 一步步教你搭建SSM整合+前提配置超详细版(IDEA版本)
  3. springboot项目如何不依赖spring-boot-parent
  4. sw工程图导出bom_SolidWorks材料明细表自动调用钣金展开尺寸,轻松导出BOM表
  5. python io_Python 的 io.StringIO()
  6. 超详细动手搭建一个 VuePress 站点及开启 PWA 与自动部署
  7. Setting Up ODI's Schedule
  8. 登录与注册 艺术与业务 的结合
  9. mysql数据与Hadoop之间导入导出之Sqoop实例
  10. 《UNIX编程环境》——5.6 zap:使用名字终止进程