機器學習實戰之決策樹

2021-07-30 05:41:25 字數 4591 閱讀 6485

1 演算法概述

1.1 結構分析

決策樹是一種依託決策而建立起來的樹,其中,每乙個內部節點表示乙個屬性上的測試,每乙個分支代表乙個測試的結果輸出,每乙個葉子代表一種類別。

如上圖所示就是乙個決策樹,首先分析所給資料集是否為同一類別,如果是,那就不用劃分了,如果不是,就尋找劃分資料集最好的特徵進行劃分(也就是影響資料集劃分因素最明顯的特徵劃分,這個後面會專門介紹最大資訊增益法劃分,知道怎麼用就中),比如上圖一開始就是選擇的是:傳送郵件網域名稱位址為某某莫,每個內部節點(資料子集)代表乙個二分類問題,每個葉子節點是分類的結果,遇到內部節點就一直劃分,直到劃分的資料子集都屬於同一型別的資料時,就停止劃分,此時,也就意味著你的決策樹已經建好。

1.2 演算法思想

這是一種尋找資料集內部之間規律的演算法,以資訊熵為度量,構造一顆熵值下降最快的數,到葉子節點處的熵值為零。此時,每乙個葉子代表乙個類別。

在決策樹的每乙個非葉子結點劃分之前,先計算每乙個屬性所帶來的資訊增益,選擇最大資訊增益的屬性來劃分,因為資訊增益越大,區分樣本的能力就越強,越具有代表性,很顯然這是一種自頂向下的貪心策略。以上就是id3演算法的核心思想

1.3 演算法實現步驟

①計算每種特徵劃分方式的資訊熵,選取資訊熵最大的一種劃分方式

②遞迴的構建決策樹

2 實現

(1)創造資料集

(2)計算資料集資訊熵

def

calcshannonent

(dataset):

numentries = len(dataset) #len()是計算變數長度的函式 ,numentries=5

labelcounts = {} #為所有可能分類創造字典

#遍歷每條資料集樣本,如果字典裡沒有資料集中的類別,將此類別存入字典中,如果有,將此類別數目加1

#以下for迴圈裡計算結果為labelcounts=['yes':2,'no':3]

#其實,以下for迴圈可以用一句話概括:

#labelcounts[currentlabel]=labelcounts.get(currentlabel,0)+1

for featvec in dataset: #the the number of unique elements and their occurance

currentlabel = featvec[-1]

if currentlabel not

in labelcounts.keys():

labelcounts[currentlabel] = 0

labelcounts[currentlabel] += 1

#計算熵值

shannonent = 0.0

for key in labelcounts: #遍歷上面生成的字典中的每乙個特徵類別,計算其中每個類別的熵值

prob = float(labelcounts[key])/numentries #numentries=5

shannonent -= prob * log(prob,2) #log base 2

return shannonent

(3)根據上面計算的資訊熵,劃分資料集

(4)選擇最好的劃分結果

def

choosebestfeaturetosplit

(dataset):

numfeatures = len(dataset[0]) - 1

#特徵數,-1是因為dataset最後一列是標籤類別

baseentropy = calcshannonent(dataset) #計算總資料集的資訊熵

bestinfogain = 0.0; bestfeature = -1

for i in range(numfeatures): #遍歷每乙個特徵

featlist = [example[i] for example in dataset]#遍歷每個特徵的資料集

uniquevals = set(featlist) #第i個特徵取值集合,如果i=1,則uniquevals=[1,1,1,0,0]

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 #calculate the info gain; ie reduction in entropy

if (infogain > bestinfogain): #選擇最大資訊熵的劃分結果

bestinfogain = infogain #if better than current best, set to best

bestfeature = i

return bestfeature #returns an integer

(5)遞迴構造決策樹

多數表決的方法決定葉子節點的分類 –該葉子屬於哪一類的樣本最多,我們就說該葉子屬於哪類

def

createtree

(dataset,labels):

classlist = [example[-1] for example in dataset] #資料集所有標籤列表

#終止條件1;類別完全相同,表示就只有乙個類別,則停止繼續劃分 返回標籤-葉子節點

if classlist.count(classlist[0]) == len(classlist):

return classlist[0]#stop splitting when all of the classes are equal

#終止條件2:無法將資料集劃分成唯一類別時,採用多數表決法決定葉子的分類

if len(dataset[0]) == 1: #stop splitting when there are no more features in dataset

return majoritycnt(classlist) #遍歷完所有的特徵時返回出現次數最多的

#開始建立樹

bestfeat = choosebestfeaturetosplit(dataset) #選擇最好的方式進行劃分資料集,得到最好劃分資料集特徵

bestfeatlabel = labels[bestfeat]

mytree = } #用上面得到的最好劃分資料集特徵建立乙個空樹(空字典)

del(labels[bestfeat]) #刪除labels[bestfeat]

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

uniquevals = set(featvalues)

for value in uniquevals: #遍歷當前選擇的特徵包含的所有屬性

sublabels = labels[:] #copy all of labels, so trees don't mess up existing labels

#遞迴呼叫構建樹的過程,直到遍歷完所有劃分資料集屬性,所有相同類別的資料均被分到同乙個資料子集中

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

return mytree

(6)用決策樹進行**標籤

def

classify

(inputtree,featlabels,testvec):

firststr = inputtree.keys()[0] #第乙個特徵屬性:firststr='no su***cing'

#除去第乙個特徵屬性的字典:seconddict=}}

seconddict = inputtree[firststr]

featindex = featlabels.index(firststr) #尋找第乙個特徵屬性在特徵屬性列表中的位置:featindex=0

for key in seconddict.keys(): #遍歷整棵樹,比較待測特徵與樹節點的值,直到找到特徵值完全匹配的葉子節點

if testvec[featindex] == key:

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

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

else: classlabel = seconddict[key]

return classlabel

機器學習實戰之決策樹

1.熵 entropy h s 用來測量乙個資料集s的不確定程度。h s x x p x log2 p x s 待計算熵的資料集,在id3演算法的每次迭代中會改變 x s中類別的集合 p x 屬於類別x的元素站集合s中總元素的比例 h s 0 集合s 被完全分到乙個類中。在id3中,對每乙個屬性熵,...

機器學習實戰之決策樹

在 機器學習實戰 決策樹這一章的時候,有些地方的 有點看不太懂,看了幾篇部落格,還是未解。最後仔細看書,發現自己不懂資料集的組織方式。希望大家看的時候也注意一下。在決策樹函式呼叫的資料要滿足如下要求 1 資料必須是由列表元素組成的列表,所有的列表元素都要具有相同的資料長度 2 資料 也就是資料集中的...

機器學習實戰 決策樹

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