機器學習 決策樹

1. 決策樹

決策樹是一種分類算法,它像是一個倒着的樹,遵循if—then原則來對樣本進行分類,如下圖:

在這裏插入圖片描述

這是一個簡單的決策樹模型,它通過樣本數據的特徵來一點一點判斷,最終將樣本歸到正確的分類中。最上面的"擁有房產"這個節點稱爲根節點,中間諸如"已婚"、"年收入"等節點稱爲內部節點,內部節點就是表示一個特徵或屬性的取值。“可以償還”、"無法償還"等節點稱爲葉節點,葉節點對應着類別。

2. 信息熵

有些地方把信息熵叫做信息量,其實也能大致這樣理解。信息量就是你知道一件事以後能得到的信息的多少,說白了是一種度量單位,然而得到信息的多少跟事件發生的概率有關係。最常舉的例子,若有人告訴你,“太陽從東方升起從西方落下”,那你得到的信息量就爲0,因爲這件事發生的概率爲1,就是一定會發生,所以在別人告訴你的那一刻,你就沒有獲得信息量。若別人告訴你,世界盃國足出線了,那麼你獲得的信息量就是巨大的,因爲這件事發生的概率太低了(皮一下很開心)。從這裏我們就得到了一條重要的性質或者可以叫信息熵的一條必要條件:信息熵隨着事件發生的概率的增大而減小。

若別人告訴你國足出線了,這件事的概率記做P(x),信息熵爲X。同時又告訴你,今天上課點名了,這件事的概率記做P(y),信息熵爲Y。你知道了兩件事,你所得到的信息量一定是X+Y,然而這兩件事情是獨立的(不要說老師知道你看球故意點名),他們同時發生的概率P(x,y)=P(x)P(y)。這便得到了信息熵的第三個性質:兩件獨立的事情發生時,概率是乘積,信息熵是累加。

如果要用一個公式來表示信息熵,從第三條性質我們很容易想到它一定與log有關係,然而log是個遞增函數,我們需要個遞減的,那麼log前面一定需要加一個負號。還要不爲負數,那麼一定是概率作爲log的自變量,因爲概率最大爲1。綜上所述,信息熵的公式就浮出水面了。

從隨機變量角度來看,隨機變量X的可能取值有x1,x2,...,xKx_1,x_2,...,x_K,對於每個可能的取值,其概率p(xk)p(x_k),因此隨機變量X的熵爲:
H(X)=k=1Kp(xk)log2p(xk)H(X)=-\sum\limits_{k=1}^Kp(x_k)log_2p(x_k)

爲什麼用2作爲底數?其實這裏用e作爲底數也行,這裏的log只是爲了實現第一條性質和第三條性質,它的底數是沒關係的,所以根據傳統取2。

從離散樣本空間角度來看,對於樣本集合D來說,假設樣本有K個類別,Dk|D_k|表示類別k的樣本個數,D|D|表示樣本總數,則對於樣本集合D來說熵爲:
H(D)=k=1KDkDlog2DkDH(D)=-\sum\limits_{k=1}^K\cfrac{|D_k|}{|D|}log_2\cfrac{|D_k|}{|D|}

信息熵計算代碼實現:

from math import log
def getShannonEnt(dataSet):
    dataNum=len(dataSet)
    labelCounts={}
    for data in dataSet:
        label=data[-1] #獲取標籤
        if label not in labelCounts.keys():
            labelCounts[label]=0
        labelCounts[label]+=1
    ShannonEnt=0.0
    for key in labelCounts:
        #計算概率=頻數/總數
        pro=float(labelCounts[key])/dataNum
        # print(f'pro[{key}]={pro}')
        #累加香農熵
        ShannonEnt -=pro*log(pro,2)
    return ShannonEnt

dataSet=[[1,1],[2,1],[3,0],[4,1],[5,0]]
print(f'ShannonEnt={getShannonEnt(dataSet)}')

dataSet=[[1,1],[2,1],[3,0],[4,1],[5,0],[6,1],[7,1],[8,0],[9,1],[10,2]]
print(f'ShannonEnt={getShannonEnt(dataSet)}')

ShannonEnt=0.9709505944546686
ShannonEnt=1.295461844238322

以weka中的天氣數據爲例(weather.norminal.arff),數據集如下圖所示:

在這裏插入圖片描述

令D爲天氣數據集,共14個樣本,每個樣本有5個屬性。類別標籤屬性play有兩個值C1=yes,C2=no{C1=yes,C2=no}C1=yes在D中出現的概率爲914\frac{9}{14},C2=no出現的概率爲514\frac{5}{14}。因此D的熵爲:
H(D)=H(914,514)=914log2914514log2514=0.94H(D)=H(\cfrac{9}{14},\cfrac{5}{14})=-\cfrac{9}{14}log_2\cfrac{9}{14}-\cfrac{5}{14}log_2\cfrac{5}{14}=0.94

dataSet=[[1,0],[2,0],[3,1],[4,1],[5,1],[6,0],[7,1],[8,0],[9,1],[10,1],[11,1],[12,1],[13,1],[14,0]]
print(f'ShannonEnt={getShannonEnt(dataSet)}')
ShannonEnt=0.9402859586706309

3. 特徵選擇

特徵選擇指選擇有較強分類能力的特徵。**而分類能力通過信息增益或者信息增益比來刻畫。**選擇特徵的標準是找出局部最優的特徵作爲判斷進行切分,取決於切分後節點數據集合中類別的有序程度(純度),劃分後的分區數據越純,切分規則越合適。衡量節點數據集合的純度有:熵、基尼係數和方差。熵和基尼係數是針對分類的,方差是針對迴歸的。

4. 信息增益(ID3算法)

ID3名字中的ID是Iterative Dichotomiser(迭代二分器)的簡稱。

信息增益(gain)是熵與條件熵的差。前面是訓練集D的熵,表示訓練機D的不確定程度。後面是訓練集D在特徵A給定的情況下不確定程度。那麼二者的差值就可以理解爲由於給定了特徵A,訓練集D的不確定性降低了多少。顯然,這個值越大說明這個特徵對提純的貢獻越多。

Gain(D,A)=H(D)H(DA)=H(D)k=1KDkDH(Dk)Gain(D,A)=H(D)-H(D|A)=H(D)-\sum_{k=1}^{K}\frac{|D_k|}{|D|}H(D_k)

根據信息增益的特徵選擇方法爲:對數據集D的每個特徵計算其信息增益,然後排序,選擇最大的最爲最先劃分的特徵。根據此特徵劃分之後可以形成幾波子集(取決於此特徵的取值多少),然後在這些子集上再分別計算信息增益並選擇最大的進行劃分,這樣不斷循環下去,直到所有特徵都被劃分完。

計算每個屬性劃分數據集D所得的信息增益:

以上面天氣數據中的屬性windy爲例,取值爲{FASLE,TRUE},將D劃分爲2個子集{D1D_1(8個),D2D_2(6個)}。

對於D1D_1,play=yes 有6個樣本,play=no 有2個樣本,則:
H(D1)=68log26828log228=0.811H(D_1)=-\cfrac{6}{8}log_2\cfrac{6}{8}-\cfrac{2}{8}log_2\cfrac{2}{8}=0.811
對於D2D_2,play=yes 有3個樣本,play=no 有3個樣本,則:
H(D2)=36log23636log236=1H(D_2)=-\cfrac{3}{6}log_2\cfrac{3}{6}-\cfrac{3}{6}log_2\cfrac{3}{6}=1

D1=[[1,0],[2,1],[3,1],[4,1],[5,0],[6,1],[7,1],[8,1]]
print(f'H(D1)={getShannonEnt(D1)}')

D2=[[1,0],[2,0],[3,1],[4,1],[5,1],[6,0]]
print(f'H(D2)={getShannonEnt(D2)}')
H(D1)=0.8112781244591328
H(D2)=1.0

利用屬性windy劃分D後的條件熵爲:

H(Dwindy)=k=1KDkDH(Dk)=D1DH(D1)+D2DH(D2)=814H(D1)+614H(D2)=0.5710.811+0.4281=0.891\begin{aligned} H(D|windy)&=\sum\limits_{k=1}^K\frac{|D_k|}{|D|}H(D_k)=\frac{|D_1|}{|D|}H(D_1)+\frac{|D_2|}{|D|}H(D_2)\\ &=\frac{8}{14}H(D_1)+\frac{6}{14}H(D_2)=0.571*0.811+0.428*1\\ &= 0.891 \end{aligned}

則按屬性windy劃分數據集D所得的信息增益值爲:

Gain(D,windy)=H(D)H(Dwindy)=0.940.891=0.049Gain(D,windy)=H(D)-H(D|windy)=0.94-0.891=0.049

同理,得到S對其他所有屬性的信息增益,如下所示:
Gain(D,outlook)=0.246Gain(D,outlook)=0.246,
Gain(D,temperature)=0.029Gain(D,temperature)=0.029,
Gain(D,humidity)=0.152Gain(D,humidity)=0.152

如果只用ID3算法,則將信息增益取值最大的那個屬性作爲分裂節點,因此以outlook屬性作爲決策樹的根節點。接下來根決策節點的三個不同取值的分支,遞歸計算信息增益,求子樹,最後得到的決策樹。

ID3算法的缺點:

1、無法處理連續值特徵,比如來一個西瓜的密度作爲特徵,密度的數值是連續的,它就無法處理。
2、對取值較多的特徵有偏向。若數據集中最左側的編號No.也作爲一個特徵的話,那麼他被首先選上是必然的,因爲總共14條數據它就有14個取值,意思是用它來劃分將會產生14個分支,這14個分支每個分支僅僅包含一個樣本,純度自然非常非常高。當然這是一個比較極端的例子,但也反映了ID3算法對取值較多的特徵有偏向。
3、沒有考慮缺失值的處理。
4、沒有考慮過擬合。

5. 信息增益比(C4.5算法)

信息增益準則對可取值數目較多的屬性有所偏好,爲減少這種偏好可能帶來的不利影響,著名的 C4.5 決策樹算法(Quinlan 1993)不直接使用信息增益,而是使用"增益率" (gain ratio) 來選擇最優劃分屬性。信息增益比定義爲:
Gain_ratio(D,A)=Gain(D,A)HA(D)HA(D)=i=1nNiNlog2NiNGain\_ratio(D,A)=\cfrac{Gain(D,A)}{H_A(D)}\\ H_A(D)=-\sum\limits_{i=1}^n\cfrac{N_i}{N}log_2\cfrac{N_i}{N}

其中HA(D)H_A(D),表示將當前特徵A作爲隨機變量(取值爲特徵A的各個特徵值)求得的經驗熵。

outlook屬性爲例,取值爲overcast的樣本有4條,取值爲rain的樣本有5條,取值爲sunny的樣本有5條:

Houtlook(D)=414log2414514log2514514log2514=1.576H_{outlook}(D)=-\cfrac{4}{14}log_2\cfrac{4}{14}-\cfrac{5}{14}log_2\cfrac{5}{14}-\cfrac{5}{14}log_2\cfrac{5}{14}=1.576

那麼,Gain_ratio(D,outlook)=Gain(D,outlook)Houtlook(D)=0.2461.576=0.156Gain\_ratio(D,outlook)=\cfrac{Gain(D,outlook)}{H_{outlook}(D)}=\cfrac{0.246}{1.576}=0.156

同理,計算其他屬性的信息增益比:
Gain_ratio(D,temperature)=Gain(D,temperature)Htemperature(D)=0.0291.556=0.019Gain\_ratio(D,temperature)=\cfrac{Gain(D,temperature)}{H_{temperature}(D)}=\cfrac{0.029}{1.556}=0.019
Gain_ratio(D,humidity)=Gain(D,humidity)Hhumidity(D)=0.1521=0.152Gain\_ratio(D,humidity)=\cfrac{Gain(D,humidity)}{H_{humidity}(D)}=\cfrac{0.152}{1}=0.152
Gain_ratio(D,windy)=Gain(D,windy)Hwindy(D)=0.0490.985=0.0497Gain\_ratio(D,windy)=\cfrac{Gain(D,windy)}{H_{windy}(D)}=\cfrac{0.049}{0.985}=0.0497

使用C4.5算法則將信息增益率取值最大的那個屬性作爲分裂節點,因此以outlook屬性作爲決策樹的根節點。接下來根決策節點的三個不同取值的分支,遞歸計算信息增益比,求子樹。最後得到的決策樹如下圖:

在這裏插入圖片描述

基本的決策樹的生成算法中,典型的有ID3生成算法和C4.5生成算法,它們生成樹的過程大致相似,ID3是採用的信息增益作爲特徵選擇的度量,而C4.5則採用信息增益比。

雖然C4.5算法改進了ID3算法的一些缺點,但其自身仍有缺點:
1、容易過擬合。(決策樹過擬合的解決方法一般是剪枝)
2、C4.5生成的是多叉樹結構,運行效率較低。(二叉樹效率高)
3、C4.5中的大量的對數計算影響效率。
4、C4.5算法只能處理分類問題。

6. CART 決策樹

CART全稱爲Classification and Regression Tree(分類與迴歸樹),這是一種著名的決策樹學習算法,分類和迴歸任務都可用。基本原理還是與之前的兩個算法相同,不同的仍然是選擇特徵的依據。
CART決策樹[Breiman et al., 1984] 使用"基尼指數" (Gini index) 來選擇劃分屬性。數據集的純度可用基尼值來度量:

Gini(D)=k=1ykkpkpk=1k=1ypk2Gini(D)=\sum_{k=1}^{|y|}\sum_{k'\neq k}p_{k}p_{k'}=1-\sum_{k=1}^{|y|}p_k^2

基尼指數反映了從數據集D中隨機抽取兩個樣本,其類別標記不一致的概率,基尼指數越小,數據集的純度越高。
那麼特徵A的基尼指數定義爲:
Gini_index(D,A)=k=1KDkDGini(Dk)Gini\_index(D,A)=\sum_{k=1}^K\cfrac{|D_k|}{|D|}Gini(D_k)

7. 決策樹停止生成條件

決策樹不會無限制的生長,總會有停止分裂的時候,最極端情況爲節點分裂到只剩一個數據點時自動停止分裂。爲降低決策樹的複雜度和提高預測精度,會適當提前終止節點的分裂(先剪枝)。決策樹停止分裂的一般性條件爲:

  1. 最小節點數
    當節點數小於一個指定數時,不再繼續分裂。因爲數據量較少時,再做分裂容易強化噪聲數據的作用。其次,降低樹生長的複雜性,提前結束分裂一定程度上有利於降低過擬合的影響。
  2. 熵或基尼指數小於閥值
    熵和基尼指數的大小表示數據的複雜程度,當熵或者基尼值過小時,表示數據的純度比較大,如果熵或者基尼值小於一定程度數,節點停止分裂。
  3. 決策樹的深度達到指定上限。
  4. 所有特徵已經使用完畢。

8. 總結

三個決策樹算法總結對比:
在這裏插入圖片描述

參考資料:
《決策樹》
《機器學習筆記 16_決策樹》
《機器學習-周志華》
《機器學習實戰-李銳》
本文主要參考前兩篇文章,摘選片段根據自己的理解進行重新排版整合,並對公式符號進行統一描述。

發佈了156 篇原創文章 · 獲贊 353 · 訪問量 72萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章