機器學習實戰讀書筆記 決策樹

2021-08-06 06:08:38 字數 4024 閱讀 3122

以下是需要的一些子函式

# 計算給定資料集的夏農熵

defcalcshannonent

(dataset):

numentries = len(dataset) #得到行數

labexcounts = {}

for featvec in dataset:

currentlabel = featvec[-1] #獲取每行最後一列的值

#根據最後一列的值進行分類,並計算每一類的個數

if currentlabel not

in labexcounts.keys():

labexcounts[currentlabel] = 0

labexcounts[currentlabel] += 1

shannonent = 0.0

#計算夏農熵

for key in labexcounts:

prob = float (labexcounts [key] )/numentries

shannonent -= prob * log(prob,2)

return shannonent

# 選擇最好的資料集劃分方式

defchoosebestfeaturetosplit

(dataset):

numfeatures = len(dataset[0]) - 1

baseentropy = calcshannonent(dataset) #獲取資料集的夏農熵

bestinfogain = 0

bestfeature = -1

#從1 - (len-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 - newentropy

if (infogain > bestinfogain):

bestinfogain = infogain

bestfeature = i

return bestfeature

# 按照給定特徵劃分資料集

defsplitdataset

(dataset, axis, value):

# axis 表示第幾列,value表示特徵值。eg:axis =3 ,value = "kk" 表示,第三列中值為"kk"的,把這些行取出來(去掉第3列)

retdataset =

for featvec in dataset:

if featvec[axis] == value:

reducedfeatvec = featvec[:axis]

reducedfeatvec.extend(featvec[axis + 1:])

return retdataset

# 獲取給定第單列集中最多的分類

defmajoritycnt

(classlist):

classcount = {}

for vote in classlist:

if vote not

in classcount.keys(): classcount[vote] = 0

classcount[vote] += 1

sortedclasscount = sorted(classcount.iteritems(), key=operator.itemgetter(1), reverse=true)

return sortedclasscount[0][0]

#建立樹的函式**

defcreatetree

(dataset,labels):

classlist = [example[-1] for example in dataset] #獲取最後一列,結果特徵

if classlist.count(classlist[0]) == len(classlist): #如果這一列的特徵都一樣,則直接返回該特徵值

return classlist[0]

if len(dataset[0]) == 1: #如果遞迴到只剩下一列,還沒分出類別,那麼取剩下類別中最多的返回

return majoritycnt(classlist)

bestfeat = choosebestfeaturetosplit(dataset) #選擇最好的特徵列

bestfeatlabel = labels[bestfeat] #最後的特徵列對應的標籤(注意,這個不是結果值,而是每一列的標籤,含義,不包含在dataset中,比dataset少一列,因為結果那一列不需要定義標籤)

mytree = }

del(labels[bestfeat])

featvalues = [example[bestfeat] for example in dataset]

uniquevals = set(featvalues)

for value in uniquevals:

sublabels = labels[:]

mytree[bestfeatlabel][value] = createtree(splitdataset(dataset, bestfeat, value),sublabels)

return mytree

以下為最終演算法**,同樣的。也是遞迴(樹相關經常會使用遞迴)

# 使用決策樹的分類函式

deftreeclassify

(inputtree,featlabels,testvec):

firststr = inputtree.keys()[0]

seconddict = inputtree[firststr]

featindex = featlabels.index(firststr)

for key in seconddict.keys():

if testvec[featindex] == key:

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

classlabel = treeclassify(seconddict[key], featlabels, testvec)

else: classlabel = seconddict[key]

return classlabel

構造決策樹是很耗時的任務,即使處理很小的資料集。如果資料集很大,將會耗費很多計算時間。然而用建立好的決策樹解決分類問題,則何以 很快完成。因此,為了節省計算時間,最好能夠在每次執行分類時呼叫巳經構造好的決策樹。為 了解決這個問題,需要使用python模組pickle序列化物件。序列化物件可以在磁 盤上儲存物件,並在需要的時候讀取出來。任何物件都可以執行序列化操作,字典物件也不例外。

#儲存決策樹

defstoretree

(inputtree,filename):

import pickle

fw = open(filename,'w')

pickle.dump(inputtree,fw)

fw.close()

defgrabtree

(filename):

import pickle

fr = open(filename)

return pickle.load(fr)

機器學習讀書筆記 決策樹

決策樹是一類常見的機器學習方法。舉個簡單的例子,我們分辨乙個藝術品是否具有藝術價值,可以從色彩,線條兩方面去評價 不會美術,只是打個比方 例如下面這幅畫,我們可以先判斷色彩不鮮豔,再判斷線條不美觀,從而得出這沒有藝術價值。這判斷的過程就是一棵決策樹。如圖 這是決策樹學習基本演算法 可以看出,關鍵在第...

機器學習實戰 決策樹

決策樹 2 python語言在函式中傳遞的是列表的引用,在函式內部對列表物件的修改,將會影響該列表物件的整個生存週期。為了消除這個不良影響,我們需要在函式的開始宣告乙個新列表物件。在本節中,指的是在劃分資料集函式中,傳遞的引數dataset列表的引用,為了不影響dataset我們重新宣告了乙個ret...

機器學習實戰決策樹

這幾天一直在學習機器學習實戰python 實現,在程式清單的3 6 獲取及誒單數程式,書上的程式是這樣的 def getnumleafs mytree numleafs 0.0 firststr list dict.keys mytree 0 seconddict mytree firststr p...