構造決策樹

2021-09-01 14:47:06 字數 4388 閱讀 5984

注:先提交**和各行**的解釋,後續完善。參照機器學習實戰教材

from math import log

import operator

defcreatedataset()

:#建立鑑定資料集

dataset =[[

1,1,

'yes'],

[1,1

,'yes'],

[1,0

,'no'],

[0,1

,'no'],

[0,1

,'no']]

labels =

['no su***cing'

,'flippers'

]return dataset, labels

defcalcshannonent

(dataset)

: numentries =

len(dataset)

#計算鑑定資料集長度

labelcounts =

#建立空字典

for featvec in dataset:

#計算每個結果發生的個數,為求每個分類的概率做準備

currentlabel = featvec[-1

]if currentlabel not

in labelcounts.keys():

labelcounts[currentlabel]

=0

labelcounts[currentlabel]+=1

#得到每個結果對應的個數

shannonent =

0.0for key in labelcounts:

#求資訊熵,資訊熵公式

prob =

float

(labelcounts[key]

)/numentries

shannonent -= prob * log(prob,2)

#log base 2

return shannonent #自定義函式返回資訊熵

defsplitdateset

(dataset,axis,value)

:#實現資料集劃分,引數:待劃分資料集、劃分資料集的特徵、特徵值的返回值

retdataset=

#空列表

for featvec in dataset:

#if featvec[axis]

==value:

#判斷特徵值等於特徵的返回值

reducedfeatvec=featvec[

:axis]

#截圖某特徵之前的特徵資料

reducedfeatvec.extend(featvec[axis+1:

])#拼接某特徵值之後的特徵資料,構成新資料

#資料集中滿足特徵值等於特徵的返回值的樣本

return retdataset #劃分某特徵在特定特徵值返回值時對應的資料集

defchoosebestfeaturetosplit

(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.0for value in uniquevals:

#依次遍歷某特徵的某個值

subdateset=splitdateset(dataset,i,value)

# 對當前特徵的每個特徵劃分一次資料集

prob=

len(subdateset)

/float

(len

(dataset)

)# 計算每種劃分的資訊熵公式

newentropy +=prob*calcshannonent(subdateset)

# 計算每種劃分的資訊熵公式

infogain=baseentropy-newentropy # 計算每種劃分方式的資訊增益

if(infogain>bestinfogain)

:#計算最好的資訊增益

bestinfogain=infogain

bestfeature=i

return bestfeature #返回最好特徵劃分的索引值

#test=choosebestfeaturetosplit(dataset)#求得資料集最好的特徵劃分的索引值

defmajoritycnt

(classlist)

:#該函式使用分類名稱的列表,然後建立鍵值為classlist中唯一值的資料字典,

#字典物件儲存了classlist中每個類表現出現的次數,並利用operator操作鍵值排序字典,並返回次數最多的分類名稱。

classcount=

for vote in classlist:

if vote not

in classcount.keys(

):classcount[vote]

=0

classcount[vote]

+=1

sortedclasscount=

sorted

(classcount.items(

),key=operator.itemgetter(1)

,reverse=

true

)return sortedclasscount[0]

[0]def

creattree

(dataset,labels)

:#建立決策樹,引數為資料集和標籤列表

classlist=

[example[-1

]for example in dataset]

# 獲取待分類資料集的所有分類結果

if classlist.count(classlist[0]

)==len(classlist)

:#資料集下的所有分類都具有相同的分類

return classlist[0]

#返回此分類

iflen

(dataset[0]

)==1:

#遍歷完所有劃分資料集的屬性,遍歷到最後乙個屬性的時候

return majoritycnt(classlist)

#返回次數最多的分類名稱,來替代劃分成僅包含唯一類別的分組

bestfeat=choosebestfeaturetosplit(dataset)

#選擇資料集最好的特徵劃分的索引值

bestfeatlabel=labels[bestfeat]

#選擇資料集最好的特徵劃分的特徵

mytree=

}#得到的返回值插入到字典變數mytree中

del(labels[bestfeat]

)#對屬性標籤依次刪除已經插入到字典的特徵

featvalues=

[example[bestfeat]

for example in dataset]

#得到當前用來劃分的特徵的所有屬性值

uniquevals=

set(featvalues)

#對當前特徵的所有屬性值去重,得到唯一值

for value in uniquevals:

#遍歷當前特徵的所有屬性的唯一值

sublabels=labels[:]

#複製了類標籤,並將其儲存在新列表變數中,確保不修改原始列表內容

mytree[bestfeatlabel]

[value]

=creattree(splitdateset(dataset,bestfeat,value)

,sublabels)

return mytree

dataset, labels=createdataset(

)#得到待劃分的資料集和特徵

test=creattree(dataset,labels)

#完成決策樹的巢狀字典

決策樹 構造註解樹

註解樹 將樹中的資訊新增到決策樹圖中。note 繪製圖形的x軸有效範圍是0.0到1.0,y軸有效範圍也是0.0到1.0。def getnumleafs mytree 獲取葉節點樹 numleafs 0 firststr mytree.keys 0 mytree的第乙個特徵值 python2寫法 fi...

決策樹和CART決策樹

首先簡單介紹下決策樹 說到決策樹肯定離不開資訊熵 什麼是資訊熵 不要被這名字唬住,其實很簡單 乙個不太可能的時間居然發生了,要比乙個非常可能的時間發生提供更多的資訊。訊息說 今天早上太陽公升起 資訊量是很少的,以至於沒有必要傳送。但另一條訊息說 今天早上日食 資訊量就很豐富。概率越大資訊量就越少,與...

決策樹(二)決策樹回歸

回歸 決策樹也可以用於執行回歸任務。我們首先用sk learn的decisiontreeregressor類構造一顆回歸決策樹,並在乙個帶雜訊的二次方資料集上進行訓練,指定max depth 2 import numpy as np quadratic training set noise np.r...