精华内容
下载资源
问答
  • 决策树(二)在 python 中使用 Matplotlib 注解绘制树形图1. Matplotlib 注解1.1 使用文本注解绘制决策树2. 构造注解树2.1 获取叶节点的数目和树的层数2.2 plotTree函数 1. Matplotlib 注解 Matplotlib 提供了一个...

    转载请注明作者和出处:https://blog.csdn.net/weixin_45814668
    微信公众号:qiongjian0427
    知乎:https://www.zhihu.com/people/qiongjian0427
    Github代码获取:https://github.com/qiongjian/Machine-learning/
    Python版本: Python3.x

    1. Matplotlib 注解

    Matplotlib 提供了一个注解工具 annotations ,可以在数据图形上添加文本注释。注解通常用于解释数据的内容。

    1.1 使用文本注解绘制决策树

    import matplotlib.pyplot as plt
    
    decisionNode = dict(boxstyle="sawtooth", fc="0.8") # boxstyle为文本框的类型,sawtooth是锯齿形,fc是边框线粗细
    leafNode = dict(boxstyle="round4", fc="0.8") # round4表示圆形
    arrow_args = dict(arrowstyle="<-") # 箭头样式
    
    def plotNode(nodeTxt, centerPt, parentPt, nodeType):
        # nodeTxt:节点文本, centerPt:子节点, parentPt:父节点, nodeType:节点样式
        createPlot.axl.annotate(nodeTxt, xy=parentPt,xycoords='axes fraction',\
                                xytext=centerPt, textcoords='axes fraction',\
                                va="center", ha="center", bbox=nodeType, arrowprops=arrow_args)
    

    这是第一个版本的 createPlot()函数。

    def createPlot():
        fig = plt.figure(1, facecolor='white')
        fig.clf()
        createPlot.axl = plt.subplot(111, frameon=False)
        plotNode('JCJD', (0.5, 0.1), (0.1, 0.5), decisionNode)
        plotNode('YJD', (0.8, 0.1), (0.3, 0.8), leafNode) 
        plt.show()
    

    createPlot 函数是这段代码的核心。
    createPlot 函数首先创建了一个新图形并清空绘图区,然后再绘图区上绘制了两个代表不同类型的树节点,后面我们将用这两个节点绘制树图形。

    代码运行结果:
    在这里插入图片描述

    2. 构造注解树

    2.1 获取叶节点的数目和树的层数

    定义 getNumLeafs 函数,获取叶节点的数目,getTreeDepth 函数,获取树的层数。

    获取叶节点的数目

    def getNumLeafs(myTree):
        numLeafs = 0
        firstStr = myTree.keys()[0]
        secondDict = myTree[firstStr]
        for key in secondDict.keys():
            if type(secondDict[key]).__name__ == 'dict':
                numLeafs += getNumLeafs(secondDict[key])
            else:
                numLeafs += 1
        return numLeafs
    

    获取树的层数

    def getTreeDepth(myTree):
        maxDepth = 0
        firstStr = myTree.keys()[0] 
        secondDict = myTree[firstStr]
        for key in secondDict.keys():
            if type(secondDict[key]).__name__ == 'dict':
                thisDepth = 1 +getTreeDepth(secondDict[key])
            else:
                thisDepth = 1
            if thisDepth > maxDepth : maxDepth = thisDepth
        return maxDepth
    

    为了节省时间,函数 retrieveTree 输出预先存储的树信息,避免每次测试都要创建树的麻烦。

    def 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]
    

    运行代码结果:
    在这里插入图片描述运行下面的代码时有错误:
    在这里插入图片描述 这是因为python3 中 dict.keys 返回的是 dict_keys 对象,不支持 indexable,所以将第3行修改代码为:

    firstStr = list(myTree.keys())[0]
    

    运行结果为:
    在这里插入图片描述

    2.2 plotTree函数

    使用plotMidText函数,计算父节点和子节点的中间位置,并在此处添加简单的文本标签信息。

    decisionNode = dict(boxstyle="sawtooth", fc="0.8") # boxstyle为文本框的类型,sawtooth是锯齿形,fc是边框线粗细
    leafNode = dict(boxstyle="round4", fc="0.8") # round4表示圆形
    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 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, va="center", ha="center", rotation=30)
    

    计算宽与高。

    def plotTree(myTree, parentPt, nodeTxt):
        
        numLeafs = getNumLeafs(myTree)
        depth = getTreeDepth(myTree)
        firstStr = list(myTree.keys())[0]                                                      # 找到第一个元素,根节点
        cntrPt = (plotTree.xOff + (1.0 + float(numLeafs))/2.0/plotTree.totalW, plotTree.yOff)  # 节点位置
        
        plotMidText(cntrPt, parentPt, nodeTxt)                         #标记子节点属性值
        plotNode(firstStr, cntrPt, parentPt, decisionNode)
        secondDict = myTree[firstStr]                                      # 获取节点下的内容
        plotTree.yOff = plotTree.yOff - 1.0/plotTree.totalD                  # 减少 y 偏移,树是自顶向下画的
        for key in secondDict.keys():                                           # 键值:0、1
            if type(secondDict[key]).__name__ == 'dict':                           # 判断是 dict 还是 value
                plotTree(secondDict[key], cntrPt, str(key))                          # 递归调用
            else:
                plotTree.xOff = plotTree.xOff + 1.0/plotTree.totalW                      # 更新 x 值
                plotNode(secondDict[key], (plotTree.xOff, plotTree.yOff), cntrPt, leafNode)
                plotMidText((plotTree.xOff, plotTree.yOff), cntrPt, str(key))
        plotTree.yOff = plotTree.yOff + 1.0/plotTree.totalD
    

    更新 createPlot()函数。

    def createPlot(inTree):
        fig = plt.figure(1, facecolor='white')
        fig.clf()
        axprps = dict(xticks=[], yticks=[])
        createPlot.ax1 = plt.subplot(111, frameon=False, **axprps)   # 定义绘图区
        plotTree.totalW = float(getNumLeafs(inTree))                  # 存储树的宽度
        plotTree.totalD = float(getTreeDepth(inTree))                 #存储树的深度
    
        # 使用了这两个全局变量追踪已经绘制的节点位置,以及放置下一个节点的恰当位置
        plotTree.xOff = -0.5/plotTree.totalW;plotTree.yOff = 1.0;
        plotTree(inTree, (0.5,1.0), ' ')
        plt.show()
    

    绘制图形的 x 轴有效范围是 0.0 到 1.0,y 轴有效范围也是 0.0 到 1.0。

    按照图形比例绘制树形图的最大好处是无需关心实际输出图形的大小,一旦图形大小发生了变化,函数会自动按照图形大小重新绘制。

    运行结果:

    在这里插入图片描述

    变更字典,重新绘制。

    myTree['no surfacing'][3]='maybe'
    

    运行结果:
    在这里插入图片描述

    END

    展开全文
  • 本节我们将学习如何编写代码绘制3-3所示的决策。 1.Matplotlib 注解 Matplotlib提供了一个注解工具annotations,非常有用,它可以在数据图形上添加文本注释。注解通常用于解释数据的内容。由于数据上面...
    本节我们将学习如何编写代码绘制如图 3-3 所示的决策树。

    1.Matplotlib 注解

            Matplotlib提供了一个注解工具annotations,非常有用,它可以在数据图形上添加文本注释。注解通常用于解释数据的内容。由于数据上面直接存在文本描述非常丑陋,因此工具内嵌支持带箭头的划线工具,使得我们可以在其他恰当的地方指向数据位置,并在此处添加描述信息,解释数据内容。如图3-4所示,在坐标(0.2, 0.1)的位置有一个点,我们将对该点的描述信息放在(0.35,0.3)的位置,并用箭头指向数据点(0.2, 0.1)。

     

     使用文本注解绘制树节点

    import matplotlib.pyplot as plt
    
    decisionNode = dict(boxstyle="sawtooth", fc="0.8") # 决策节点的属性。boxstyle为文本框的类型,sawtooth是锯齿形,fc是边框线粗细
    # 可以写为decisionNode={boxstyle:'sawtooth',fc:'0.8'}
    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)
        # nodeTxt为要显示的文本,centerPt为文本的中心点,parentPt为箭头指向文本的点,xy是箭头尖的坐标,xytest设置注释内容显示的中心位置
        # xycoords和textcoords是坐标xy与xytext的说明(按轴坐标),若textcoords=None,则默认textcoords与xycoords相同,若都未设置,默认为data
        # va/ha设置节点框中文字的位置,va为纵向取值为(u'top', u'bottom', u'center', u'baseline'),ha为横向取值为(u'center', u'right', u'left')
    
    def createPlot():
        fig = plt.figure(1,facecolor = 'white') #创建一个画布,背景为白色
        fig.clf() #画布清空
        # ax1是函数createPlot的一个属性,这个可以在函数里面定义也可以在函数定义后加入也可以
        createPlot.ax1 = plt.subplot(111,frameon = True) # frameon表示是否绘制坐标轴矩形
        plotNode(U'决策节点',(0.5,0.1),(0.1,0.5),decisionNode)
        plotNode(U'叶节点',(0.8,0.1),(0.3,0.8),leafNode)
        plt.show()
    
    createPlot()

     注意:直接执行出来中文不会显示,原因是没有中文字体,例如:

     解决方案,添加中文字体文件并引用

    下载压缩包:

    链接:https://pan.baidu.com/s/1nZI1g7-JDX-6RzSPUyoT_Q 
    提取码:3glh

     然后运行以下代码查看自己字体所在文件夹

    import matplotlib
    print(matplotlib.matplotlib_fname())

     

    进入文件夹D:\Anaconda3\Lib\site-packages\matplotlib\mpl-data\fonts\ttf

    将解压后的ttf文件复制进去,然后执行以下代码

    from matplotlib.font_manager import _rebuild
    _rebuild()

     之后回到原先文件中,添加这样一行代码

    plt.rcParams['font.sans-serif']=['SimHei']

     再次执行文件

    >>> import importlib
    >>> importlib.reload(treePlotter)

    这样就解决了问题

     

     

    展开全文
  • Matplotlib绘制树形图

    千次阅读 2017-05-04 16:33:32
    机器学习实战之Matplotlib绘制树形图树信息存储为”字典“对象,例如{‘no surfacing’: {0: ‘no’, 1: {‘flippers’: {0: ‘no’, 1: ‘yes’}}}} 绘制图形为: #绘制树形图 import matplotlib.pyplot as ...

    Matplotlib绘制树形图

    树信息存储为”字典“对象,

    例如{‘no surfacing’: {0: ‘no’, 1: {‘flippers’: {0: ‘no’, 1: ‘yes’}}}}
    绘制图形为:
    这里写图片描述

    #绘制树形图
    import matplotlib.pyplot as plt
    
    decision_node = dict(boxstyle="sawtooth",fc="0.8")
    leaf_node = dict(boxstyle="round4",fc="0.8")
    arrow_args = dict(arrowstyle="<-")
    #获取树的叶子结点个数(确定图的宽度)
    def get_leaf_num(tree):
        leaf_num = 0
        first_key = list(tree.keys())[0]
        next_dict = tree[first_key]
        for key in next_dict.keys():
            if type(next_dict[key]).__name__=="dict":
                leaf_num +=get_leaf_num(next_dict[key])
            else:
                leaf_num +=1
        return leaf_num
    #获取数的深度(确定图的高度)
    def get_tree_depth(tree):
        depth = 0
        first_key = list(tree.keys())[0]
        next_dict = tree[first_key]
        for key in next_dict.keys():
            if type(next_dict[key]).__name__ == "dict":
                thisdepth = 1+ get_tree_depth(next_dict[key])
            else:
                thisdepth = 1
            if thisdepth>depth: depth = thisdepth
        return depth
    
    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 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, va="center", ha="center", rotation=30)
    
    def plotTree(myTree, parentPt, nodeTxt):
        numLeafs = get_leaf_num(myTree)
        depth = get_tree_depth(myTree)
        firstStr = list(myTree.keys())[0]
        cntrPt = (plotTree.xOff + (1.0 + float(numLeafs)) / 2.0 / plotTree.totalW, plotTree.yOff)
        plotMidText(cntrPt, parentPt, nodeTxt)
        plotNode(firstStr, cntrPt, parentPt, decision_node)
        secondDict = myTree[firstStr]
        plotTree.yOff = plotTree.yOff - 1.0 / plotTree.totalD
        for key in secondDict.keys():
            if type(secondDict[
                        key]).__name__ == 'dict':
                plotTree(secondDict[key], cntrPt, str(key))
            else:
                plotTree.xOff = plotTree.xOff + 1.0 / plotTree.totalW
                plotNode(secondDict[key], (plotTree.xOff, plotTree.yOff), cntrPt, leaf_node)
                plotMidText((plotTree.xOff, plotTree.yOff), cntrPt, str(key))
        plotTree.yOff = plotTree.yOff + 1.0 / plotTree.totalD
    
    
    
    def createPlot(inTree):
        fig = plt.figure(1, facecolor='white')
        fig.clf()
        axprops = dict(xticks=[], yticks=[])
        createPlot.ax1 = plt.subplot(111, frameon=False, **axprops)
        plotTree.totalW = float(get_leaf_num(inTree))
        plotTree.totalD = float(get_tree_depth(inTree))
        plotTree.xOff = -0.5 / plotTree.totalW
        plotTree.yOff = 1.0
        plotTree(inTree, (0.5, 1.0), '')
        plt.show()
    展开全文
  • matplotlib提供了一个注解工具...1.使用文本注解绘制树节点 import matplotlib.pyplot as plt decisionNode = dict(boxstyle="sawtooth", fc="0.8") leafNode = dict(boxstyle="round4", fc="0.8") ...

    matplotlib提供了一个注解工具annotations,可以在数据图形上添加文本注释。

    1.使用文本注解绘制树节点

    import matplotlib.pyplot as plt
    
    decisionNode = dict(boxstyle="sawtooth", fc="0.8")
    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) #ticks for demo puropses 
        plotNode('a decision node', (0.5, 0.1), (0.1, 0.5), decisionNode)
        plotNode('a leaf node', (0.8, 0.1), (0.3, 0.8), leafNode)
        plt.show()
    使用文本注解
    • dict

    详解:http://www.cnblogs.com/yangyongzhi/archive/2012/09/17/2688326.html

    字典初始化:

    >>> d=dict(name='vi',age=20)
    >>> d
    {'name': 'vi', 'age': 20}

    访问字典:

    dict = {'Name': 'Zara', 'Age': 7, 'Class': 'First'};
    >>> print("dict[name]",dict['Name'])
    dict[name] Zara

    通过annotate()函数画一个标注的箭头;其中的两个位置是箭头和箭尾的坐标,后面是颜色等信息。

     

    2. 构造注解树

    先获取叶节点的数目和树的层数:

    def getNumLeafs(myTree):
        numLeafs = 0
        firstStr = list(myTree.keys())[0]
        secondDict = myTree[firstStr]
        for key in secondDict.keys():
            if type(secondDict[key]).__name__=='dict':#test to see if the nodes are dictonaires, if not they are leaf nodes
                numLeafs += getNumLeafs(secondDict[key])
            else:   numLeafs +=1
        return numLeafs
    
    def getTreeDepth(myTree):
        maxDepth = 0
    #    firstStr = myTree.keys()[0]
        firstStr = list(myTree.keys())[0]
        secondDict = myTree[firstStr]
        for key in secondDict.keys():
            if type(secondDict[key]).__name__=='dict':#test to see if the nodes are dictonaires, if not they are leaf nodes
                thisDepth = 1 + getTreeDepth(secondDict[key])
            else:   thisDepth = 1
            if thisDepth > maxDepth: maxDepth = thisDepth
        return maxDepth
    叶子节点数目和树的层数

    遍历节点,判断是否为字典类型,是字典类型,则是叶子节点

    然后绘制树的结构

    def createPlot(inTree):
        fig = plt.figure(1, facecolor='white')
        fig.clf()
        axprops = dict(xticks=[], yticks=[])
        createPlot.ax1 = plt.subplot(111, frameon=False, **axprops)    #no ticks
        #createPlot.ax1 = plt.subplot(111, frameon=False) #ticks for demo puropses 
        plotTree.totalW = float(getNumLeafs(inTree))
        plotTree.totalD = float(getTreeDepth(inTree))
        plotTree.xOff = -0.5/plotTree.totalW; plotTree.yOff = 1.0;
        plotTree(inTree, (0.5,1.0), '')
        plt.show()
        
    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, va="center", ha="center", rotation=30)
    
    def plotTree(myTree, parentPt, nodeTxt):#if the first key tells you what feat was split on
        numLeafs = getNumLeafs(myTree)  #this determines the x width of this tree
        depth = getTreeDepth(myTree)
        firstStr = list(myTree.keys())[0]     #the text label for this node should be this
        cntrPt = (plotTree.xOff + (1.0 + float(numLeafs))/2.0/plotTree.totalW, plotTree.yOff)
        plotMidText(cntrPt, parentPt, nodeTxt)
        plotNode(firstStr, cntrPt, parentPt, decisionNode)
        secondDict = myTree[firstStr]
        plotTree.yOff = plotTree.yOff - 1.0/plotTree.totalD
        for key in secondDict.keys():
            if type(secondDict[key]).__name__=='dict':#test to see if the nodes are dictonaires, if not they are leaf nodes   
                plotTree(secondDict[key],cntrPt,str(key))        #recursion
            else:   #it's a leaf node print the leaf node
                plotTree.xOff = plotTree.xOff + 1.0/plotTree.totalW
                plotNode(secondDict[key], (plotTree.xOff, plotTree.yOff), cntrPt, leafNode)
                plotMidText((plotTree.xOff, plotTree.yOff), cntrPt, str(key))
        plotTree.yOff = plotTree.yOff + 1.0/plotTree.totalD
    #if you do get a dictonary you know it's a tree, and the first element will be another dict
    绘制树

    最后得到的图形为:

    转载于:https://www.cnblogs.com/mzhourr/p/8849804.html

    展开全文
  • 《机器学习实战》第三章 3.2 在Python中使用Matplotlib注解绘制树形图 自己按照树上的代码敲了一遍(Spyder),调试之后可以使用,向大家分享一下,另外,有好多的注解,希望对大家有帮助。 代码 源代码 # -*- ...
  • #使用文本注解绘制树形图 import matplotlib.pyplot as plt decisionNode = dict(boxstyle="sawtooth", fc="0.8") leafNode = dict(boxstyle="round4", fc="0.8") arrow_args = dict(arrowstyle=") #上面三行代码...
  • 基于python树形决策构建基于python树形决策构建
  • 最简单粗暴的决策,并用画图包画出了决策树型
  • 本文实例为大家分享了Python生成树形图案的具体代码,供大家参考,具体内容如下先看一下效果,见下。上面这颗大树是使用Python + Tkinter绘制的,主要原理为使用分形画树干、树枝,最终叶节点上画上绿色圆圈代表...
  • 本文实例为大家分享了Python生成树形图案的具体代码,供大家参考,具体内容如下 先看一下效果,见下。 上面这颗大树是使用Python + Tkinter绘制的,主要原理为使用分形画树干、树枝,最终叶节点上画上绿色圆圈...
  • 使用文本注解绘制树节点 #coding:utf-8 import matplotlib.pyplot as plt # 定义决策树决策结果的属性,用字典来定义 # 下面的字典定义也可写作 decisionNode={boxstyle:'sawtooth',fc:'0.8'} # ...
  • 利用Matplotlib注解绘制树形图 Matplotlib注解工具—annotations 此模块运用了一个非常重要的技术 将一些对象和变量作为函数的属性在函数的外部进行初始化 由于其全局的特性,使得在整个递归过程中,任意过程对这些...
  • 使用Python生成树形图案

    千次阅读 2009-10-10 17:00:00
     上面这颗大树是使用Python + Tkinter绘制的,主要原理为使用分形画树干、树枝,最终叶节点上画上绿色圆圈代表树叶。当然,为了看起来更真实,绘制过程中也加入了一些随机变化,比如树枝会稍微有些扭曲而不是一条...
  • 机器学习-决策树(绘制树形图

    千次阅读 2019-07-16 17:34:37
    具体绘制树的代码大体懂个意思,书上没讲视频没说,比较难理解。 from math import log import operator import matplotlib.pyplot as plt from matplotlib.font_manager import FontProperties """求树的叶子...
  • I have implemented an algorithm to solve the problem of clustering in a ... I used the python library "python-graph" to represent the graph. Now, at each step of my computation (the algorithm is it...
  • 在决策树02——决策树的构建中,我们将已经进行分类的数据存储在字典中,然而字典的表示... 以下将使用Matplotlib的注解功能绘制树形图,它可以对文字着色,并提供多种形状以供选择,而且我们还可以反转箭头,将它指
  • 本文旨在描述如何使用Python实现基本的树形图。要实现这样的树形图,首先需要有一个数值矩阵。每一行代表一个实体(这里是一辆汽车)。每列都是描述汽车的变量。目标是将实体聚类以了解谁与谁有共同点。python下通过...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 3,754
精华内容 1,501
关键字:

python绘制树形图

python 订阅