一、什麼是熵
假設符號xi的資訊定義為:
則熵定義為資訊的期望值,為了計算熵,我們需要計算所有類別所有可能值包含的資訊期望值,計算方式如下:
熵愈大,不穩定性愈高,即在決策樹中乙個樣本可選擇的分支會愈多。從公式來理解是:假如每個p(xi)愈少,則i值愈大,即資訊量愈大,就是有可以有很多中分類。同時,h是關於p(xi)的減函式,
熵表示資料的混亂程度,假如每個p(xi)愈少,資料愈分散,則最後求出的嫡愈大,熵的本質是乙個系統「內在的混亂程度」。所以,熵、不確定性、資訊量,這三者是同乙個數值。
二、構建樹的理解
首先我認為要先理解怎樣用一堆資料集訓練出來一棵樹。資料集中的資料報括特徵值和類標籤值。注意了這裡的特徵值是只有值,這些值要根據專案的背景歸納出來特徵。這些特徵就是訓練決策樹時要輸入的標籤。
然後,我個人理解建立決策樹的過程就是判斷哪個特徵(就是上面所說的要輸入的標籤)是父節點,哪些特徵是子節點,哪些特徵是葉子節點。構建決策樹的目的是把資料集合中的不同型別的資料劃分得清清楚楚,即不同型別的資料必須分開。也就是說,只有決策樹的分支愈多,把不同型別的資料分開的概率才能愈大。所以在建立樹的過程中,會優先選擇一些特徵作為上層節點。這些特徵的特點是:在根據這個特徵劃分資料集之後,資料子集的熵是最大的(熵愈大,不穩定性愈高,則在後續的節點中可以分出更多的類別)。
以下是計算熵和劃分資料集的**
#計算熵值
defcalcshannonent
(dataset):
numentries = len(dataset)
labelcounts={}
for featvect in dataset:
currentlabel = featvect[-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
shannonent -= prob*log(prob,2)
return shannonent
#分割資料子集合,返回篩選出某一特徵之後的資料子集
defsplitdataset
(dataset,axis,value):
retdataset=
for featvec in dataset:
if featvec[axis]==value:
reducefeatvec=featvec[:axis]
#這裡獲取的是取出了該特徵之後的資料子集
reducefeatvec.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)
#print uniquevals
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
至此,把資料集劃分完畢,接下來是進行構建樹。工作原理是:對原始的資料集基於最好的特徵(即根據該特徵劃分之後子集熵最大)進行劃分資料集。在一次劃分之後,資料將會被傳到下乙個節點,在這個節點上可以再次劃分資料。每次遞迴都會在資料子集上選擇乙個最好的特徵進行資料的分割,遞迴結束的條件是,所有程式遍歷完所有的特徵,或者是每個分支下所有的例項都具有相同的分類。
以下是建立樹的**:
#假如已經遍歷了所有的特徵,但是最終的分類標籤仍然不是唯一的,則採用少數服從多數的原則決定這個標籤
defmajoritycnt
(classlist):
classcount={}
for vote in classlist:
if vote not
in classcount.keys():
classcount[vote]=0
#zhege if yuju xiangdangyu yige chushihua tiaojian
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]
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
測試分類器的**如下:
#test
#featlabels就是上面所說的要輸入的標籤,而testvec就是屬性值
defclassify
(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=classify(seconddict[key],featlabels,testvec)
else:classlabel=seconddict[key]
return classlabel
總結:一步乙個腳印! 機器學習十大演算法之決策樹(詳細)
什麼是決策樹?如何構建決策樹?id3c4.5 cart 決策樹的優缺點及改進 什麼是決策樹?決策樹是運用於分類的一種樹結構,其本質是一顆由多個判斷節點組成的樹,其中的每個內部節點代表對某一屬性的一次測試,每條邊代表乙個測試結果,而葉節點代表某個類或類的分布。屬於有監督學習 核心思想 分類決策樹的核心...
資料探勘十大演算法(一) 決策樹分類C4 5演算法
如下圖所示,為乙個待訓練的資料集 訓練集,表示乙個人具備年齡 收入 是否學生 信譽這4個屬性,待訓練的目標是這個人是否購買計算機。其中年齡 收入 是否學生 信譽被稱作描述屬性,是否購買計算機稱作類別屬性,即分為什麼類別。為了理解什麼叫決策樹,我們直接跳到結果 利用上述資料集,得到的決策樹 決策樹如下...
決策樹演算法
決策樹是一種樹型結構,其中每個內部結點表示在乙個屬性上的測試,每個分支代表乙個測試輸出,每個葉結點代表一種類別。決策樹學習是以例項為基礎的歸納學習,採用的是自頂向下的遞迴方法,其基本思想是以資訊熵為度量構造一棵熵值下降最快的樹,到葉子結點處的熵值為零,此時每個葉節點中的例項都屬於同一類。決策樹學習演...