python中如何画出决策树_使用Python绘制决策树
決策樹(shù)為字典格式,示例如下:
{'tearRate': {'reduced': 'no lenses', 'normal': {' astigmatic': {'yes': {' prescript': {'hyper': {'age': {'pre': 'no lenses', 'presbyopic': 'no lenses', 'young': 'hard'}}, 'myope': 'hard'}}, 'no': {'age': {'pre': 'soft', 'presbyopic': {' prescript': {'hyper': 'soft', 'myope': 'no lenses'}}, 'young': 'soft'}}}}}}
繪制決策樹(shù)代碼
import matplotlib.pyplot as plt
def getNumLeafs(myTree):
# 初始化樹(shù)的葉子節(jié)點(diǎn)個(gè)數(shù)
numLeafs = 0
# myTree.keys()獲取樹(shù)的非葉子節(jié)點(diǎn)'no surfacing'和'flippers'
# list(myTree.keys())[0]獲取第一個(gè)鍵名'no surfacing'
firstStr = list(myTree.keys())[0]
# 通過(guò)鍵名獲取與之對(duì)應(yīng)的值,即{0: 'no', 1: {'flippers': {0: 'no', 1: 'yes'}}}
secondDict = myTree[firstStr]
# 遍歷樹(shù),secondDict.keys()獲取所有的鍵
for key in secondDict.keys():
# 判斷鍵是否為字典,鍵名1和其值就組成了一個(gè)字典,如果是字典則通過(guò)遞歸繼續(xù)遍歷,尋找葉子節(jié)點(diǎn)
if type(secondDict[key]).__name__ == 'dict':
numLeafs += getNumLeafs(secondDict[key])
# 如果不是字典,則葉子結(jié)點(diǎn)的數(shù)目就加1
else:
numLeafs += 1
# 返回葉子節(jié)點(diǎn)的數(shù)目
return numLeafs
def getTreeDepth(myTree):
# 初始化樹(shù)的深度
maxDepth = 0
# 獲取樹(shù)的第一個(gè)鍵名
firstStr = list(myTree.keys())[0]
# 獲取鍵名所對(duì)應(yīng)的值
secondDict = myTree[firstStr]
# 遍歷樹(shù)
for key in secondDict.keys():
# 如果獲取的鍵是字典,樹(shù)的深度加1
if type(secondDict[key]).__name__ == 'dict':
thisDepth = 1 + getTreeDepth(secondDict[key])
else:
thisDepth = 1
# 去深度的最大值
if thisDepth > maxDepth: maxDepth = thisDepth
# 返回樹(shù)的深度
return maxDepth
# 繪圖相關(guān)參數(shù)的設(shè)置
def plotNode(nodeTxt, centerPt, parentPt, nodeType):
# annotate函數(shù)是為繪制圖上指定的數(shù)據(jù)點(diǎn)xy添加一個(gè)nodeTxt注釋
# nodeTxt是給數(shù)據(jù)點(diǎn)xy添加一個(gè)注釋,xy為數(shù)據(jù)點(diǎn)的開(kāi)始繪制的坐標(biāo),位于節(jié)點(diǎn)的中間位置
# xycoords設(shè)置指定點(diǎn)xy的坐標(biāo)類(lèi)型,xytext為注釋的中間點(diǎn)坐標(biāo),textcoords設(shè)置注釋點(diǎn)坐標(biāo)樣式
# bbox設(shè)置裝注釋盒子的樣式,arrowprops設(shè)置箭頭的樣式
'''
figure points:表示坐標(biāo)原點(diǎn)在圖的左下角的數(shù)據(jù)點(diǎn)
figure pixels:表示坐標(biāo)原點(diǎn)在圖的左下角的像素點(diǎn)
figure fraction:此時(shí)取值是小數(shù),范圍是([0,1],[0,1]),在圖的左下角時(shí)xy是(0,0),最右上角是(1,1)
其他位置是按相對(duì)圖的寬高的比例取最小值
axes points : 表示坐標(biāo)原點(diǎn)在圖中坐標(biāo)的左下角的數(shù)據(jù)點(diǎn)
axes pixels : 表示坐標(biāo)原點(diǎn)在圖中坐標(biāo)的左下角的像素點(diǎn)
axes fraction : 與figure fraction類(lèi)似,只不過(guò)相對(duì)于圖的位置改成是相對(duì)于坐標(biāo)軸的位置
'''
createPlot.ax1.annotate(nodeTxt, xy=parentPt, \
xycoords='axes fraction', xytext=centerPt, textcoords='axes fraction', \
va="center", ha="center", bbox=nodeType, arrowprops=arrow_args)
# 繪制線(xiàn)中間的文字(0和1)的繪制
def plotMidText(cntrPt, parentPt, txtString):
xMid = (parentPt[0] - cntrPt[0]) / 2.0 + cntrPt[0] # 計(jì)算文字的x坐標(biāo)
yMid = (parentPt[1] - cntrPt[1]) / 2.0 + cntrPt[1] # 計(jì)算文字的y坐標(biāo)
createPlot.ax1.text(xMid, yMid, txtString)
# 繪制樹(shù)
def plotTree(myTree, parentPt, nodeTxt):
# 獲取樹(shù)的葉子節(jié)點(diǎn)
numLeafs = getNumLeafs(myTree)
# 獲取樹(shù)的深度
depth = getTreeDepth(myTree)
# firstStr = myTree.keys()[0]
# 獲取第一個(gè)鍵名
firstStr = list(myTree.keys())[0]
# 計(jì)算子節(jié)點(diǎn)的坐標(biāo)
cntrPt = (plotTree.xoff + (1.0 + float(numLeafs)) / 2.0 / plotTree.totalW, plotTree.yoff)
# 繪制線(xiàn)上的文字
plotMidText(cntrPt, parentPt, nodeTxt)
# 繪制節(jié)點(diǎn)
plotNode(firstStr, cntrPt, parentPt, decisionNode)
# 獲取第一個(gè)鍵值
secondDict = myTree[firstStr]
# 計(jì)算節(jié)點(diǎn)y方向上的偏移量,根據(jù)樹(shù)的深度
plotTree.yoff = plotTree.yoff - 1.0 / plotTree.totalD
for key in secondDict.keys():
if type(secondDict[key]).__name__ == 'dict':
# 遞歸繪制樹(shù)
plotTree(secondDict[key], cntrPt, str(key))
else:
# 更新x的偏移量,每個(gè)葉子結(jié)點(diǎn)x軸方向上的距離為 1/plotTree.totalW
plotTree.xoff = plotTree.xoff + 1.0 / plotTree.totalW
# 繪制非葉子節(jié)點(diǎn)
plotNode(secondDict[key], (plotTree.xoff, plotTree.yoff), cntrPt, leafNode)
# 繪制箭頭上的標(biāo)志
plotMidText((plotTree.xoff, plotTree.yoff), cntrPt, str(key))
plotTree.yoff = plotTree.yoff + 1.0 / plotTree.totalD
# 繪制決策樹(shù),inTree的格式為{'no surfacing': {0: 'no', 1: {'flippers': {0: 'no', 1: 'yes'}}}}
def createPlot(inTree):
# 新建一個(gè)figure設(shè)置背景顏色為白色
fig = plt.figure(1, facecolor='white')
# 清除figure
fig.clf()
axprops = dict(xticks=[], yticks=[])
# 創(chuàng)建一個(gè)1行1列1個(gè)figure,并把網(wǎng)格里面的第一個(gè)figure的Axes實(shí)例返回給ax1作為函數(shù)createPlot()
# 的屬性,這個(gè)屬性ax1相當(dāng)于一個(gè)全局變量,可以給plotNode函數(shù)使用
createPlot.ax1 = plt.subplot(111, frameon=False, **axprops)
# 獲取樹(shù)的葉子節(jié)點(diǎn)
plotTree.totalW = float(getNumLeafs(inTree))
# 獲取樹(shù)的深度
plotTree.totalD = float(getTreeDepth(inTree))
# 節(jié)點(diǎn)的x軸的偏移量為-1/plotTree.totlaW/2,1為x軸的長(zhǎng)度,除以2保證每一個(gè)節(jié)點(diǎn)的x軸之間的距離為1/plotTree.totlaW*2
plotTree.xoff = -0.5 / plotTree.totalW
plotTree.yoff = 1.0
plotTree(inTree, (0.5, 1.0), '')
plt.show()
運(yùn)行代碼
# 設(shè)置畫(huà)節(jié)點(diǎn)用的盒子的樣式
decisionNode = dict(boxstyle="sawtooth", fc="0.8")
leafNode = dict(boxstyle="round4", fc="0.8")
# 設(shè)置畫(huà)箭頭的樣式
arrow_args = dict(arrowstyle="
tree_dict = {'tearRate': {'reduced': 'no lenses', 'normal': {' astigmatic': {'yes': {' prescript': {'hyper': {'age': {'pre': 'no lenses', 'presbyopic': 'no lenses', 'young': 'hard'}}, 'myope': 'hard'}}, 'no': {'age': {'pre': 'soft', 'presbyopic': {' prescript': {'hyper': 'soft', 'myope': 'no lenses'}}, 'young': 'soft'}}}}}}
createPlot(tree_dict)
效果圖
決策樹(shù)構(gòu)建示例
決策樹(shù)實(shí)戰(zhàn)——預(yù)測(cè)隱形眼睛類(lèi)型
總結(jié)
以上是生活随笔為你收集整理的python中如何画出决策树_使用Python绘制决策树的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 自考计算机网络应用,自考计算机网络原理总
- 下一篇: python决策树 多分类_Python