本篇决策树算法是依据ID3算法来的,所以在看之间建议先了解ID3算法:https://blog.csdn.net/qq_27396861/article/details/88226296

文章目录

  • 一、构建决策树
  • 二、plot构建树

案例,按照属性来分辨海洋生物:

图一:

图二:

一、构建决策树

实例:

# coding: utf-8from math import log
import operatordef createDataSet():dataSet = [[1,1,'yes'], [1,1,'yes'], [1,0,'no'], [0,1,'no'], [0,1,'no']]labels = ['no surfacing', 'flippers']return dataSet, labelsdef calcShannonEnt(dataSet):''' 计算给定总的数据集的香农熵 '''numEntries = len( dataSet ) # 集合里元素的数量labelCounts = {}# 为所有可能的分类创建次数字典for featVec in dataSet:currentLabel = featVec[-1] # 倒数第一个元素if currentLabel not in labelCounts.keys():labelCounts[currentLabel] = 0labelCounts[currentLabel] += 1shannonEnt = 0.0for key in labelCounts:# 将当前样本的数量除以总的样本数量prob = float(labelCounts[key]) / numEntries# 以2为底求对数,然后求和shannonEnt -= prob * log(prob, 2)return shannonEntdef splitDataSet(dataSet, axis, value):''' 按照给定特征划分数据集, 待划分的数据集 划分数据集的特征(dataSet里特征的下标) 特征的返回值 '''''' 如果axis下标是0,那么reduceFeatVec就是后两个,如果是1,那么就是第一个和第三个。也就是除了axisd的下标'''retDataSet = []for featVec in dataSet:if featVec[axis] == value:reduceFeatVec = featVec[:axis]reduceFeatVec.extend(featVec[axis+1:])retDataSet.append(reduceFeatVec)return retDataSetdef chooseBestFeatureToSplit(dataSet):''' 选择最好的数据集划分方式 '''numFeatures = len(dataSet[0]) - 1 # 每个元素的特征个数# 香农熵baseEntropy = calcShannonEnt(dataSet) # 求取数据集合的香农熵bestInfoGain = 0.0  # 最好的熵bestFeature = -1 # 最好的特征for i in range(numFeatures):featList = [example[i] for example in dataSet]uniqueVals = set(featList)newEntropy = 0.0 for value in uniqueVals:subDataSet = splitDataSet(dataSet, i, value)prob = len(subDataSet) / float(len(dataSet)) # 符合的数量 / 总的数量# 条件熵newEntropy += prob * calcShannonEnt(subDataSet) # 划分完之后的信息熵,相加#信息增益infoGain = baseEntropy - newEntropyif(infoGain > bestInfoGain):bestInfoGain = infoGainbestFeature = i# 返回0是不浮出水面也能生活,1是否有脚蹼return bestFeature def majorityCnt(classList):''' 找出数量最多的分类 '''# 分类字典classCount = {}for vote in classList:if vote not in classCount.keys():classCount[vote] = 0classCount[vote] += 1# 以第二列的数据排序sortedClassCount = sorted(classCount.iteritems(), \key = operator.itemgetter(1), reverse = True)return sortedClassCount[0][0]def createTree(dataSet, labels):''' 创建树的函数代码 '''classList = [example[-1] for example in dataSet] # 提取所有的类print "classList = ", classList# 数据集都是同一类的情况if classList.count(classList[0]) == len(classList):return classList[0]# 如果数据集只有一个特征的情况if len(dataSet[0]) == 1:return majorityCnt(classList) # 那就按大多数的分类bestFeat = chooseBestFeatureToSplit( dataSet ) # 最好的特征bestFeatLabel = labels[bestFeat] # 最好的分类myTree = {bestFeatLabel:{}}# 递归建树del( labels[bestFeat] )featValue = [example[bestFeat] for example in dataSet]uniqueVals = set(featValue) # 最好的特征集合for value in uniqueVals:subLabels = labels[:] # 去掉前面标签之后剩下的标签myTree[bestFeatLabel][value] = createTree(splitDataSet\(dataSet, bestFeat, value), subLabels)return myTreedef main():dataSet, labels = createDataSet()myTree = createTree(dataSet, labels)print myTreeif __name__=="__main__":main()

结果与上述图二一致:

{'no surfacing': {0: 'no', 1: {'flippers': {0: 'no', 1: 'yes'}}}}

二、plot构建树

由于代码的思想是将x轴和y轴平均分为几等分,且长度都是都是0到1,totalW记录叶子结点的个数,那么 1/totalW 正好是每个叶子结点的宽度。

以下代码是构建决策树视图的,难点在于两处地方:
(1)初始化x轴坐标的时候:
由于要使每次加1/totalW 正好是每个跟节点的增加的距离是在叶子节点之间,故要设置x初始位置要减去 0.5 / totalW,以至于后面每加一个1/totalW ,刚好都是在中间。

plotTree.xOff = -0.5 / plotTree.totalW

(2)计算跟节点x轴坐标的时候
这个需要分步理解:
X坐标=节点的x偏移量 + 叶节点数距离

所有该节点下子叶子节点的距离:numLeafs / plotTree.totalW
但是坐标在叶子节点的中心:numLeafs / 2 / plotTree.totalW
又因为xOff初始坐标点在原点的左边:numLeafs / 2 / plotTree.totalW + 0.5 / plotTree.totalW,这是偏移量
那么x = numLeafs / 2 / plotTree.totalW + 0.5 / plotTree.totalW + plotTree.xOff

plotTree.xOff + (1.0 + float(numLeafs) ) / 2.0 / plotTree.totalW

代码如下:

# coding: utf-8import matplotlib.pyplot as plt
import sys# 定义文本框和箭头格式
decisionNode = dict( boxstyle = "sawtooth", fc = "1.0" )
leafNode = dict( boxstyle = "round4", fc = "0.8" )
arrow_args = dict( arrowstyle = "<-" )# 绘制带箭头的注释
def plotNode( nodeTxt, centerPt, parentPt, nodeType ):createPlot.ax1.annotate( nodeTxt, xy = parentPt, xycoords = 'axes fraction',\xytext = centerPt, textcoords = 'axes fraction', va = 'center',\ha = 'center', bbox = nodeType, arrowprops = arrow_args )'''
def createPlot():fig = plt.figure( 1, facecolor = 'white' )fig.clf()createPlot.ax1 = plt.subplot( 111, frameon = False )plotNode( "decision node", (0.5, 0.1), (0.1, 0.5), decisionNode )plotNode( "leaf node", (0.8, 0.1), (0.3, 0.8), leafNode )plt.show()
'''def getNumLeafs( myTree ):''' 获取叶子节点数 '''numLeafs = 0firstStr = myTree.keys()[0] # 头结点secondDict = myTree[ firstStr ] # 取出头结点的的字典# 测试节点的数据类型是否为字典for key in secondDict.keys():if type( secondDict[key] ).__name__=='dict':numLeafs += getNumLeafs( secondDict[key] )else:numLeafs += 1return numLeafsdef getTreeDepth( myTree ):''' 求树的深度 '''maxDepth = 0firstStr = myTree.keys()[0] # 头结点secondDict = myTree[ firstStr ] for key in secondDict.keys():if type(secondDict[key]).__name__=='dict':thisDepth = 1 + getTreeDepth( secondDict[key] )else:thisDepth = 1if thisDepth > maxDepth:maxDepth = thisDepthreturn maxDepthdef retrieveTree(i):listOfTrees = [ {'no surfacing': {0: 'no', 1: {'flippers': {0: 'no', 1: 'yes'}}}},\{'no surfacing': {0: 'no', 1: {'flippers': {0: \{'head': {0: 'no', 1: 'yes'}}, 1: 'no'}}}}]return listOfTrees[i]def plotMidText( cntrPt, parentPt, txtString ):''' 在父子节点之间填充文本信息 '''xMid = ( parentPt[0] - cntrPt[0] ) / 2.0 + cntrPt[0]yMid = ( parentPt[1] - cntrPt[1] ) / 2.0 + cntrPt[1]createPlot.ax1.text( xMid, yMid, txtString )def plotTree( myTree, parentPt, nodeTxt ):''' parentPt 根节点坐标 '''numLeafs = getNumLeafs( myTree ) # 子节点数量depth = getTreeDepth( myTree )    # 深度firstStr = myTree.keys()[0] # 根节点的key'''X坐标=节点的x偏移量 + 叶节点数距离所有该节点下子叶子节点的距离:numLeafs / plotTree.totalW但是坐标在叶子节点的中心:numLeafs / 2 / plotTree.totalW又因为xOff初始坐标点在原点的左边:numLeafs / 2 / plotTree.totalW + 0.5 / plotTree.totalW ,这是偏移量那么x = numLeafs / 2 / plotTree.totalW + 0.5 / plotTree.totalW + plotTree.xOff '''# 根节点坐标# 叶子节点距离x = plotTree.xOff + (1.0 + float(numLeafs) ) / 2.0 / plotTree.totalW#x = plotTree.xOff + (float(numLeafs) ) / 2.0 / plotTree.totalWy = plotTree.yOffprint "x = %f, y = %f" % (x, y)cntrPt = ( x, y ) # 标记子节点属性值plotMidText( cntrPt, parentPt, nodeTxt )plotNode( firstStr, cntrPt, parentPt, decisionNode )secondDict = myTree[firstStr]plotTree.yOff = plotTree.yOff - 1.0 / plotTree.totalDfor key in secondDict.keys():if type(secondDict[key]).__name__=='dict':plotTree( secondDict[key], cntrPt, str(key) )else:plotTree.xOff = plotTree.xOff + 1.0 / plotTree.totalWplotNode( secondDict[key], (plotTree.xOff, plotTree.yOff), cntrPt, leafNode )plotMidText( (plotTree.xOff, plotTree.yOff), cntrPt, str(key) )plotTree.yOff = plotTree.yOff + 1.0 / plotTree.totalDdef createPlot( inTree ):fig = plt.figure( 1, facecolor='white' )fig.clf()axprops = dict( xticks = [], yticks = [] )createPlot.ax1 = plt.subplot( 111, frameon = False, **axprops )# 给plotTree函数建立属性plotTree.totalW = float( getNumLeafs( inTree ) ) # 宽度是叶子节点数plotTree.totalD = float( getTreeDepth( inTree ) ) # 高度是深度plotTree.xOff = -0.5 / plotTree.totalW # 方便后面加上 1.0 / plotTree.totalW 后位置刚好在中间plotTree.yOff = 1.0plotTree( inTree, (0.5, 1.0), '' )plt.show()def main():# createPlot()myTree = retrieveTree(1)createPlot( myTree )if __name__=="__main__":main()

结果如下:

机器学习实战-决策树算法相关推荐

  1. 机器学习实战--决策树算法

    决策树 决策树(decision tree)是一种基本的分类与回归方法.从判断模块引出的左右箭头称为分支,它可以达到另外一个判断模块或者终止模块.分类决策树模型是一种描述对实例进行分类的树形结构.决策 ...

  2. python决策树实例_Python机器学习之决策树算法实例详解

    本文实例讲述了Python机器学习之决策树算法.分享给大家供大家参考,具体如下: 决策树学习是应用最广泛的归纳推理算法之一,是一种逼近离散值目标函数的方法,在这种方法中学习到的函数被表示为一棵决策树. ...

  3. 机器学习:决策树算法(ID3算法)的理解与实现

    机器学习:决策树算法(ID3算法)的理解与实现 文章目录 机器学习:决策树算法(ID3算法)的理解与实现 1.对决策树算法的理解 1.概述 2.算法难点 选择最优划分属性 1.信息熵 2.信息增益 2 ...

  4. 【机器学习】决策树算法

    在前一期介绍搭建结合机器学习的CI/CD管道时,无意中提到了算法分类.在受监督学习的分类中,有一个既适用于回归又适用于分类的算法,即我们今天要介绍的决策树算法(CART, Classification ...

  5. 机器学习算法——决策树算法详细介绍,并使用sklearn实现案例预测,可视化决策树

    目录 一.决策树算法简介 二.决策树分类原理 1.熵 1.1 概念 1.2 案例 2.决策树的划分依据一:信息增益 2.1 概念 2.2 案例: 3.决策树的划分依据二:信息增益率 3.1 概念 3. ...

  6. 机器学习之决策树算法前期(创建、分类及展示)

    一.什么是决策树? 决策树算法是一种逼近离散函数值的方法.它是一种典型的分类方法,首先对数据进行处理,利用归纳算法生成可读的规则和决策树,然后使用决策对新数据进行分析.本质上决策树是通过一系列规则对数 ...

  7. 机器学习3决策树算法模型

    决策树算法模型 1.什么是决策树? 2.决策树的归纳 2.1 (选择分裂特征)特征的选择 2.2 决策树的生成 2.2.1 ID3 算法 2.2.2 C4.5 算法 2.2.3 Card算法 2.2 ...

  8. 机器学习基础 决策树算法

    文章目录 一.决策树算法简介 二.决策树分类原理 1. 熵 1.1 概念 1.2 案例 2. 决策树的划分依据一----信息增益 2.1 概念 2.2 案例 3. 决策树的划分依据二----信息增益率 ...

  9. 机器学习之决策树算法-概念和学习过程

    1.      概念 决策树是通过一系列规则对数据进行分类的过程,它提供一种在什么条件下会得到什么值的类似规则的方法.决策树分为分类树和回归树两种,分类树对离散变量做决策树,回归树对连续变量做决策树. ...

最新文章

  1. 2018年中国65家机器人产业园布局与规划汇总盘点
  2. 启用Apache Mod_rewrite模块
  3. Ubuntu伪分布式hadoop安装
  4. TCL with SNPS sizeof_collectionget_object_namefindget_libslist_attributes
  5. 云计算网络基础第八天
  6. s5-15 开放的最短路径优先_OSPF
  7. LINUX内核之内存屏障
  8. 这个结构体对齐输出有意思
  9. linux系统安全(二): 日志(转)
  10. jquery跨域访问解决方案
  11. 【转】putty基本操作--不错
  12. 你需要的三维激光LiDAR点云数据处理服务来了!
  13. Johnson 算法
  14. Unity的URP项目开启
  15. zabbix sender get trapper External check
  16. 红心大战c语言程序设计,Win 7系统安全优化、瘦身攻略(2)
  17. 游戏读取服务器配置文件失败,游戏服务器怎么配置文件
  18. matlab之isnumeric函数
  19. 2014年河北职称计算机考试,2014河北省职称计算机考试新增题
  20. 步进电机驱动选型的详细指南

热门文章

  1. 【教程】潘多拉Pandora-SS+多拨+去广告同时运行配置教(斐讯K1)
  2. 李国庆做客王峰十问:为何大佬们突然呼唤996?
  3. Linux Mint设置中文输入法
  4. 使用VMware搭建虚拟网络
  5. 20221229英语学习
  6. jquery实现点击小图片显示大图片
  7. 华为两年,苦乐参半!
  8. Couple number
  9. 高中计算机课代表竞选,初中数学课代表竞选稿(精选3篇)
  10. 【产品面试】产品面试总结出了这三类面试题