日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

python决策树可视化_「决策树」| Part3—Python实现之可视化

發布時間:2024/9/19 python 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python决策树可视化_「决策树」| Part3—Python实现之可视化 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章首發于微信公眾號:AlgorithmDeveloper,專注機器學習與Python,編程與算法,還有生活。

1.前言

「決策樹」| Part2—Python實現之構建決策樹中我們已經可以基于給定數據集訓練出決策樹模型,只不過是以字典方式表示決策樹,決策樹直觀、易于理解的優點完全體現不出來。因此,這篇文章的目的就是將訓練出的決策樹模型以樹狀圖形表示。

給定數據集:

字典形式決策樹模型:

{'人品': {'好': '見 ', '差': {'富有': {'沒錢': '不見', '有錢': {'外貌': {'漂亮': '見 ', '丑': '不見'}}}}}}

2.獲取決策樹的葉節點數及深度

為了使繪制出的決策樹圖形不因樹的節點、深度的增減而變得畸形,因此利用決策樹的葉子節點個數以及樹的深度將x軸、y軸平均切分,從而使樹狀圖平均分布在畫布上。

#獲取決策樹葉節點個數

def getNumLeafs(tree):

numLeafs = 0

#獲取第一個節點的分類特征

firstFeat = list(tree.keys())[0]

#得到firstFeat特征下的決策樹(以字典方式表示)

secondDict = tree[firstFeat]

#遍歷firstFeat下的每個節點

for key in secondDict.keys():

#如果節點類型為字典,說明該節點下仍然是一棵樹,此時遞歸調用getNumLeafs

if type(secondDict[key]).__name__== 'dict':

numLeafs += getNumLeafs(secondDict[key])

#否則該節點為葉節點

else:

numLeafs += 1

return numLeafs

#獲取決策樹深度

def getTreeDepth(tree):

maxDepth = 0

#獲取第一個節點分類特征

firstFeat = list(tree.keys())[0]

#得到firstFeat特征下的決策樹(以字典方式表示)

secondDict = tree[firstFeat]

#遍歷firstFeat下的每個節點,返回子樹中的最大深度

for key in secondDict.keys():

#如果節點類型為字典,說明該節點下仍然是一棵樹,此時遞歸調用getTreeDepth,獲取該子樹深度

if type(secondDict[key]).__name__ == 'dict':

thisDepth = 1 + getTreeDepth(secondDict[key])

else:

thisDepth = 1

if thisDepth > maxDepth:

maxDepth = thisDepth

return maxDepth

3.繪制決策樹

3.1繪制節點

#繪制決策樹

import matplotlib.pyplot as plt

def createPlot(tree):

#定義一塊畫布,背景為白色

fig = plt.figure(1, facecolor='white')

#清空畫布

fig.clf()

#不顯示x、y軸刻度

xyticks = dict(xticks=[],yticks=[])

#frameon:是否繪制坐標軸矩形

createPlot.pTree = plt.subplot(111, frameon=False, **xyticks)

#計算決策樹葉子節點個數

plotTree.totalW = float(getNumLeafs(tree))

#計算決策樹深度

plotTree.totalD = float(getTreeDepth(tree))

#最近繪制的葉子節點的x坐標

plotTree.xOff = -0.5/plotTree.totalW

#當前繪制的深度:y坐標

plotTree.yOff = 1.0

#(0.5,1.0)為根節點坐標

plotTree(tree,(0.5,1.0),'')

plt.show()

#定義決策節點以及葉子節點屬性:boxstyle表示文本框類型,sawtooth:鋸齒形;fc表示邊框線粗細

decisionNode = dict(boxstyle="sawtooth", fc="0.5")

leafNode = dict(boxstyle="round4", fc="0.5")

#定義箭頭屬性

arrow_args = dict(arrowstyle="

#nodeText:要顯示的文本;centerPt:文本中心點,即箭頭所在的點;parentPt:指向文本的點;nodeType:節點屬性

#ha='center',va='center':水平、垂直方向中心對齊;bbox:方框屬性

#arrowprops:箭頭屬性

#xycoords,textcoords選擇坐標系;axes fraction-->0,0是軸域左下角,1,1是右上角

def plotNode(nodeText, centerPt, parentPt, nodeType):

createPlot.pTree.annotate(nodeText, xy=parentPt, xycoords="axes fraction",

xytext=centerPt, textcoords='axes fraction',

va='center',ha='center',bbox=nodeType, arrowprops=arrow_args)

def plotMidText(centerPt,parentPt,midText):

xMid = (parentPt[0] - centerPt[0])/2.0 + centerPt[0]

yMid = (parentPt[1] - centerPt[1])/2.0 + centerPt[1]

createPlot.pTree.text(xMid, yMid, midtext)

plotNode函數一次繪制的是一個箭頭與一個節點,plotMidText函數繪制的是直線中點上的文本。

3.2遞歸繪制決策樹

遞歸繪制決策樹的整體思路如下:

(1)繪制當前節點;

(2)如果當前節點的子節點不是葉子節點,則遞歸;

(3)如果當前節點的子節點是葉子節點,則繪制。

def plotTree(tree, parentPt, nodeTxt):

#計算葉子節點個數

numLeafs = getNumLeafs(tree)

#獲取第一個節點特征

firstFeat = list(tree.keys())[0]

#計算當前節點的x坐標

centerPt = (plotTree.xOff + (1.0 + float(numLeafs))/2.0/plotTree.totalW, plotTree.yOff)

#繪制當前節點

plotMidText(centerPt,parentPt,nodeTxt)

plotNode(firstFeat,centerPt,parentPt,decisionNode)

secondDict = tree[firstFeat]

#計算繪制深度

plotTree.yOff -= 1.0/plotTree.totalD

for key in secondDict.keys():

#如果當前節點的子節點不是葉子節點,則遞歸

if type(secondDict[key]).__name__ == 'dict':

plotTree(secondDict[key],centerPt,str(key))

#如果當前節點的子節點是葉子節點,則繪制該葉節點

else:

#plotTree.xOff在繪制葉節點坐標的時候才會發生改變

plotTree.xOff += 1.0/plotTree.totalW

plotNode(secondDict[key], (plotTree.xOff,plotTree.yOff),centerPt,leafNode)

plotMidText((plotTree.xOff,plotTree.yOff),centerPt,str(key))

plotTree.yOff += 1.0/plotTree.totalD

根據決策樹的葉子節點數和深度來平均切分畫布,并且x、y軸的總長度為1,如下圖所示:

原諒我的畫圖水平

3.2.1在createPlot函數中:

plotTree.totalW :表示葉子節點個數,因此上圖中每兩個葉子節點之間的距離為:1/plotTree.totalW;

plotTree.totalD :表示決策樹深度;

plotTree.xOff:表示最近繪制的葉子節點x坐標,在繪制葉節點時其值才會更新;其初始值為圖中虛線圓圈位置,這樣在以后確定葉子節點位置時可以直接加整數倍的1/plotTree.totalW;

plotTree.yOff = 1.0 :表示當前繪制的深度,其值初始化為根節點y坐標。

3.2.2在plotTree函數中:

#計算當前節點的x坐標

centerPt = (plotTree.xOff + (1.0 + float(numLeafs))/2.0/plotTree.totalW, plotTree.yOff)

在確定當前節點x坐標時,只需確定當前節點下的葉節點個數,其x坐標即為葉節點所占距離的一半:float(numLeafs)/2.0/plotTree.totalW;

由于plotTree.xOff初始值為-0.5/plotTree.totalW,因此當前節點x坐標還需加上0.5/plotTree.totalW。

4.決策樹可視化

#決策樹節點文本可以以中文顯示

import matplotlib as mpl

mpl.rcParams["font.sans-serif"] = ["Microsoft YaHei"]

mpl.rcParams['axes.unicode_minus'] = False

#創建數據集

def createDataSet():

dataSet = [['有錢','好','漂亮','見 '],

['有錢','差','漂亮','見 '],

['有錢','差','丑','不見'],

['沒錢','好','丑','見 '],

['沒錢','差','漂亮','不見'],

['沒錢','好','漂亮','見 ']]

labels = ['富有','人品','外貌']

return dataSet, labels

dataSet, dataLabels = createDataSet()

#創建決策樹

myTree = createDecideTree(dataSet,dataLabels)

print(myTree)

#繪制決策樹

createPlot(myTree)

字典形式表示決策樹:

{'人品': {'好': '見 ', '差': {'富有': {'沒錢': '不見', '有錢': {'外貌': {'漂亮': '見 ', '丑': '不見'}}}}}}

樹狀圖形決策樹:

5.使用決策樹算法

在已知對方有錢,人品差,長得漂亮后,利用前面訓練的決策樹做出決策,見或不見?!

#使用決策樹進行分類

def classify(tree,feat,featValue):

firstFeat = list(tree.keys())[0]

secondDict = tree[firstFeat]

featIndex = feat.index(firstFeat)

for key in secondDict.keys():

if featValue[featIndex] == key:

if type(secondDict[key]).__name__ == 'dict':

classLabel = classify(secondDict[key],feat,featValue)

else:

classLabel = secondDict[key]

return classLabel

feat = ['富有','人品','外貌']

featValue = ['有錢','差','漂亮']

print(classify(myTree,feat,featValue))

決策結果:

6.存儲決策樹模型

構建決策樹消耗的時間還是很可觀的,尤其在數據量大的時候,因此,當訓練完決策樹模型后有必要將其保存下來,以便后續使用。使用Python模塊的pickle序列化對象可以解決這個問題,序列化對象可以在磁盤上保存對象,在需要時將其讀取出來。

#保存決策樹模型

import pickle

def saveTree(tree, fileName):

fw = open(fileName,'wb')

pickle.dump(tree, fw)

fw.close()

#加載決策樹模型

def loadTree(fileName):

fr = open(fileName,'rb')

return pickle.load(fr)

saveTree((myTree),'myTree.txt')

print(loadTree('myTree.txt'))

{'人品': {'差': {'富有': {'有錢': {'外貌': {'丑': '不見', '漂亮': '見 '}}, '沒錢': '不見'}}, '好': '見 '}}

Coding Your Ambition!

總結

以上是生活随笔為你收集整理的python决策树可视化_「决策树」| Part3—Python实现之可视化的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。