決策樹算法之ID3與C4.5的理解與實現


github:代碼實現
本文算法均使用python3實現


1. 決策樹

  決策樹(decision tree)是一種基本的分類與回歸方法(本文主要是描述分類方法),是基於樹結構進行決策的,可以將其認為是if-then規則的集合。一般的,一棵決策樹包含一個根節點若干內部節點若干葉節點。其中根節點包含所有樣本點,內部節點作為划分節點(屬性測試),葉節點對應於決策結果。

  用決策樹進行分類,是從根節點開始,對實例的某一特征進行測試,根據測試結果,將實例分配到其子節點,若該子節點仍為划分節點,則繼續進行判斷與分配,直至將實例分到葉節點的類中。

  若對以上描述不太明白,可以結合以下圖進行理解。

![](https://images2018.cnblogs.com/blog/1238724/201805/1238724-20180509193902265-534475075.jpg)
  根據以上決策樹,現在給你一個實例:{色澤:青綠,根蒂:稍蜷,敲聲:清脆,紋理:清晰,臍部:稍凹,觸感:光滑},來判斷該瓜是否是好瓜。其過程是:臍部(稍凹)-->根蒂(稍蜷)-->色澤(青綠)-->好瓜。
  以上是由決策樹來進行分類的過程。而決策樹的學習(構建)通常是一個 遞歸地選擇最優特征的過程。那么構建決策樹時如何**選擇特征作為划分點**(即選擇哪個特征作為根節點或者選擇哪個特征作為非葉子節點)?當訓練數據量大、特征數量較多時構建的**決策樹可能很龐大**,這樣的決策樹用來分類是否好?
  由這些問題我們可以知道,構建決策樹的三個要點:   (1)特征選擇   (2)決策樹的生成   (3)決策樹修剪

2. ID3算法

  基於ID3算法的決策樹構建,其選擇特征的准則是信息增益信息增益(information gain)表示得知特征 $ X $ 的信息而使得類 $ Y $ 的信息的不確定性減少的程度。也就是說,信息增益越大,通過特征 $ X $ ,就越能夠准確地將樣本進行分類;信息增益越小,越無法准確進行分類。

  在介紹信息增益之前,我們需要先對進行一下講解。

2.1 熵(Entropy)

  是度量樣本集合純度最常用的一種指標,它是信息的期望值。我們首先了解一下什么是信息。由《機器學習實戰》中定義:

如果待分類的事務可能划分在多個分類之中,則符號(特征) $ k $ 的信息定義為: $$ l(k)=-\log_2{p(k)} $$
其中 $ p(k) $ 為選擇該分類的概率。

  而計算的是所有類別所有可能值包含的信息期望值,其公式為:$$ Ent(D)=-\sum_{k=1}^N{p(k)\log_2{p(k)}} $$
  其中 $ N $ 為類別個數。

  現在我們使用例子,來理解熵的計算:

![](https://images2018.cnblogs.com/blog/1238724/201805/1238724-20180509193918471-82194729.jpg)
  (1)對於最終分類(是否為好瓜),計算其信息熵:     由上表可看出,一共有17個樣本,屬於好瓜的有8個樣本,壞瓜的有9個樣本,因此其熵為:$$ Ent(D) = -\sum_{k=1}^2{p_k\log_2{p_k}}= - ( \frac{8}{17}\log_2\frac{8}{17} + \frac{9}{17}\log_2\frac{9}{17})=0.998 $$   (2)對於特征“色澤”,計算其信息熵:     由於特征“色澤”取值有:{青綠,烏黑,淺白}。若使用該屬性對 $ D $ 進行划分,可得到3個子集,分別記為: $ D_1 $ (色澤=青綠), $ D_2 $ (色澤=烏黑), $ D_3 $ (色澤=淺白)。
    其中 $ D_1 $ 包含樣本 $ \{1,4,6,10,13,17\} $ ,其中類別為好瓜的比例為 $ p_1=\frac{3}{6} $ ,壞瓜的比例為 $ p_2=\frac{3}{6} $ ; $ D_2 $ 包含樣本 $ \{2,3,7,8,9,15\} $ ,其中類別為好瓜的比例 $ p_1=\frac{4}{6} $ ,壞瓜的比例為 $ p_2=\frac{2}{6} $ ; $ D_3 $ 包含樣本 $ \{5,11,12,14,16\} $ ,其中類別為好瓜的比例 $ p_1=\frac{1}{5} $ ,壞瓜的比例為 $ p_2=\frac{4}{5} $ ,因此其三個分支點的信息熵為:$$ Ent(D_1) = - ( \frac{3}{6}\log_2\frac{3}{6} + \frac{3}{6}\log_2\frac{3}{6})=1.000 $$ $$ Ent(D_2) = - ( \frac{4}{6}\log_2\frac{4}{6} + \frac{2}{6}\log_2\frac{2}{6})=0.918 $$ $$ Ent(D_3) = - ( \frac{1}{5}\log_2\frac{1}{5} + \frac{4}{5}\log_2\frac{4}{5})=0.722 $$ ### 2.2 信息增益(information gain)    信息增益,由《統計學習方法》中定義: > 特征 $ a $ 對訓練數據集 $ D $ 的信息增益 $ Gain(D,a) $ ,定義為集合 $ D $ 的經驗熵(即為熵)與特征 $ a $ 給定條件下的經驗條件熵 $ Ent(D|a) $ 之差,即: $$ Gain(D,a)=Ent(D)-Ent(D|a) $$ 其中特征 $ a $ 將數據集划分為: $ \{D_1,D_2,...,D_v \} $,而經驗條件熵為: $$ Ent(D|a) = \sum_{i=1}^v \frac{\left|D_i\right|}{\left|D\right|}Ent(D_i)$$

  我們根據例子對其進行理解:
  對於特征“色澤”,我們計算其信息增益,由2.1中,集合 $ D $ 的熵為: $ Ent(D)=0.998 $ ,對於特征“色澤”的三個分支點的熵為: $ Ent(D_1)=1.000,Ent(D_2)=0.918,Ent(D_3)=0.722 $,則“色澤”特征的信息增益為:

\[Gain(D,色澤)=Ent(D)-\sum_{i=1}^3 \frac{\left|D_i\right|}{\left|D\right|}Ent(D_i) = 0.998-(\frac{6}{17}\times1.000 + \frac{6}{17}\times0.918 + \frac{5}{17}\times0.722) = 0.109 \]

2.3 算法步驟

  ID3算法遞歸地構建決策樹,從根節點開始,對所有特征計算信息增益,選擇信息增益最大的特征作為節點的特征,由該特征的不同取值建立子節點;再對子節點遞歸地調用以上方法構建決策樹;知道所有特征的信息增益均很小或者沒有特征可以選擇為止。最后得到一個決策樹。

  在算法中(C4.5也是),有三種情形導致遞歸返回:

  (1)當前節點包含的樣本全屬於同一類別,無需划分。
  (2)當前屬性集為空,或是所有樣本在所有屬性上取值相同,無法划分。(此時將所含樣本最多的類別設置為該葉子節點類別)
  (3)當前節點包含的樣本集合為空,不能划分。(將其父節點中樣本最多的類別設置為該葉子節點的類別)


  輸入:訓練數據集 $ D $ ,特征集 $ A $ , 閾值 $ \epsilon $ ;
  過程:函數 $ TreeGenerate(D,A) $ .
  1:計算節點信息增益 $ Gain(D,a) $ :
  2:  節點a的熵: $ Ent(D,a) $
  3:  節點D的熵: $ Ent(D) $
  4:  節點信息增益: $ Gain(D,a)=Ent(D)-Ent(D,a) $
  5:生成節點node:
  6:if $ D $ 中樣本全屬於同一類別 $ C $ then
  7:  將node標記為 $ C $ 類葉節點;return
  8:end if
  9:if $ A = \emptyset $ OR $ D $ 中樣本在 $ A $ 上取值相同then
  10:  將node標記為葉節點,期類別標記為 $ D $ 中樣本數最多的類;return
  11:end if
  12:按照節點信息增益,從 $ A $ 中選擇最優划分屬性 $ a_* $
  13:for $ a_* $ 中的每一個值 $ a_* ^i $ do
  14:  為node生成一個分支;令 $ D_i $ 表示 $ D $ 中在 $ a_* $ 上取值為 $ a_* ^i $ 的樣本子集;
  15:  if $ D_i $ 為空,then
  16:    將分支節點標記為葉節點,其類別標記為 $ D $ 中樣本最多的類;return
  17:  else
  18:    以 $ TreeGenerate(D_i,A / { a_* }) $ 為分支節點
  19:  end if
  20:end for
  輸出:以node為根節點的一棵決策樹



3. C4.5算法

  實際上,信息增益准則對可取值書目較多的屬性有所偏好,例如如果將前面表格中的第一列ID也作為特征的話,它的信息增益將達到最大值,而這樣做顯然不對,會造成過擬合。為了減少這種偏好可能帶來的不利影響,C4.5算法中將采用信息增益比來進行特征的選擇。信息增益比准則對可取值數目較少的屬性有所偏好。接下來,我們首先對信息增益比進行介紹。

3.1 信息增益比(增益率)

  信息增益比的定義為: $$ Gain_ratio(D,a)=\frac{Gain(D,a)}{IV(a)} $$,
  其中:$$ IV(a)=-\sum_{i=1}^v \frac{\left|D_i\right|}{\left|D\right|} \log_2\frac{\left|D_i\right|}{\left|D\right|} $$
  我們根據例子對其進行理解:

  對於特征“色澤”,我們計算其信息增益比,由2.2計算得 $ Gain(D,色澤)= 0.109 $,而 $$ IV(色澤)= -(\frac{6}{17}\times\log_2\frac{6}{17} + \frac{6}{17}\times\log_2\frac{6}{17} + \frac{5}{17}\times\log_2\frac{5}{17})=1.580 $$
  則 $ Gain\_ratio(D,色澤)=\frac{0.109}{1.580}=0.069 $。

3.2 算法步驟

  C4.5算法同ID3算法過程相似,僅在選擇特征時,使用信息增益比作為特征選擇准則。


  輸入:訓練數據集 $ D $ ,特征集 $ A $ , 閾值 $ \epsilon $ ;
  過程:函數 $ TreeGenerate(D,A) $ .
  1:計算節點信息增益比 $ Gain_ratio(D,a) $ :
  2:  節點a的熵: $ Ent(D,a) $
  3:  節點D的熵: $ Ent(D) $
  4:  節點信息增益: $ Gain(D,a)=Ent(D)-Ent(D,a) $
  5:  節點固定值: $ IV(a) $
  6:  節點信息增益比: $ Gain _ ratio(D,a)= \frac{Gain(D,a)}{IV(a)} $
  7:生成節點node:
  8:if $ D $ 中樣本全屬於同一類別 $ C $ then
  9:  將node標記為 $ C $ 類葉節點;return
  10:end if
  11:if $ A = \emptyset $ OR $ D $ 中樣本在 $ A $ 上取值相同then
  12:  將node標記為葉節點,期類別標記為 $ D $ 中樣本數最多的類;return
  13:end if
  14:按照節點信息增益,從 $ A $ 中選擇最優划分屬性 $ a_* $
  15:for $ a_* $ 中的每一個值 $ a_* ^i $ do
  16:  為node生成一個分支;令 $ D_i $ 表示 $ D $ 中在 $ a_* $ 上取值為 $ a_* ^i $ 的樣本子集;
  17:  if $ D_i $ 為空,then
  18:    將分支節點標記為葉節點,其類別標記為 $ D $ 中樣本最多的類;return
  19:  else
  20:    以 $ TreeGenerate(D_i,A / {a_* }) $ 為分支節點
  21:  end if
  22:end for
  輸出:以node為根節點的一棵決策樹



4. 剪枝處理

  針對於在第1部分提到的最后一個問題:當訓練數據量大、特征數量較多時構建的決策樹可能很龐大,這樣的決策樹用來分類是否好?答案是否定的。決策樹是依據訓練集進行構建的,當決策樹過於龐大時,可能對訓練集依賴過多,也就是對訓練數據過度擬合。從訓練數據集上看,擬合效果很好,但對於測試數據集或者新的實例來說,並不一定能夠准確預測出其結果。因此,對於決策樹的構建還需要最后一步----即決策樹的修剪。
  決策樹的修剪,也就是剪枝操作,主要分為兩種:
  (1)預剪枝(Pre-Pruning)
  (2)后剪枝(Post-Pruning)
  接下來我們將詳細地介紹這兩種剪枝方法。

4.1 預剪枝(Pre-Pruning)

  預剪枝是指在決策樹生成過程中,對每個節點在划分前先進行估計,若當前節點的划分不能帶來決策樹泛化性能的提升,則停止划分並將當前節點標記為葉節點。
  我們使用例子進一步理解預剪枝的過程:
  將本文開始的西瓜數據集表划分成兩部分,一部分作為訓練集用來構建決策樹,一部分作為驗證集用來進行決策樹的剪枝。具體划分見下圖:

![](https://images2018.cnblogs.com/blog/1238724/201805/1238724-20180509193942068-1885211797.jpg)
  使用**ID3算法**進行決策樹的構建,即使用**信息增益**進行特征的選擇。首先選擇特征“臍部”作為決策樹根節點,如何判斷該節點是否需要剪枝,需要對剪枝前后驗證集精度進行比較。由“臍部”這個特征將產生三個分支“凹陷”、“稍凹”、“平坦”,並認定其分支結果(可采用多數表決法,當分類數量相當時,任選一類即可),如下圖:
![](https://images2018.cnblogs.com/blog/1238724/201805/1238724-20180509193949366-1452597590.jpg)
  查看**驗證集**,若將“臍部”看做節點,並將其標記為“好瓜”,那么划分前的精度為: $ \frac{3}{7} = 0.429 $。符合“臍部”=“凹陷”的樣本有: $ \{4,5,13\} $ ,其中正樣本(是好瓜)為 $ \{4,5\} $ ,**正樣本**個數為2,按照上圖預測正確數為2;同理“臍部”=“稍凹”的樣本中**正樣本**個數為1,預測正確數為1;“臍部”=“平坦”的樣本中**負樣本**個數為2,預測正確個數為2。因此使用“臍部”這個特征進行划分,划分后的精度為: $ \frac{5}{7} = 0.714 $。由於預測后精度大於預測前精度,因此不對“臍部”進行剪枝,即將其作為划分點進行划分。
![](https://images2018.cnblogs.com/blog/1238724/201805/1238724-20180509193958253-510855707.jpg)
  同理我們“色澤”以及“根蒂”特征進行划分前后精度的計算。對於“色澤”,划分后的精度為 $ 0.571 $ ,而划分前為 $ 0.714 $ ,划分使得結果變差,因此不以該特征進行划分,即將該節點記為葉子節點並標記為“好瓜”;同理“根蒂”特征划分前后的精度都為 $ 0.714 $ ,效果並未提升,因此也不將該特征進行划分,而是將其作為葉子節點並標記為“好瓜”。由此,決策樹構建完畢。此時的決策樹為只有一層的樹。
  **可有由圖中看出,該決策樹有點過於簡單,雖然降低的過擬合的風險,但是由於其基於“貪心”的本質禁止了其它分支的展開,給預剪枝決策樹帶來了欠擬合的風險。** ### 4.1 后剪枝(Post-Pruning)   **后剪枝**是指先從訓練集生成一棵完整的決策樹,然后自底向上地對非葉節點進行考察,若將該節點對應的子樹替換為葉節點能帶來決策能力的提升,則將該子樹替換成葉節點。   我們使用例子進一步理解后剪枝的過程:   同樣適用4.1中的划分數據集。針對已建立好的決策樹,我們首先對“紋理”特征節點進行處理,判斷其是否需要剪枝,見下圖。
![](https://images2018.cnblogs.com/blog/1238724/201805/1238724-20180509194005404-1984118890.jpg)
  首先,使用整個決策樹對驗證集進行預測,並將其預測結果與真實結果進行對比,可得到如下結果(預測結果與真實結果相同,標記為“正確”,否則標記為“不正確”):$$ \{(4,正確),(5,不正確),(8,不正確),(9,不正確),(11,正確),(12,正確),(13,不正確)\} $$   首先我們判斷是否需要對“紋理”進行剪枝:剪枝前精確度由上結果可以得到為 $ \frac{3}{7} = 0.429 $ ,剪枝后(即將該節點標記為“好瓜”),此時對於樣本 $ \{((8,正確))\} $ ,其它樣本結果不變,其精度提升到 $ \frac{4}{7} = 0.571 $ ,因此對該節點進行剪枝。對節點5“色澤”,剪枝前精確度為 $ 0.571 $ ,剪枝后仍舊為 $ 0.571 $ ,對此我們可以不進行剪枝(但在實際情況下仍舊會需要剪枝);同理對“根蒂”、節點2“色澤”進行計算,所得結果見上圖。由此得到后剪枝決策樹。
  **后剪枝決策樹通常比預剪枝決策樹保留了更多的分支,一般情況下,后剪枝決策樹欠擬合的風險很小,其泛化能力往往優於預剪枝預測數。但由於其是基於創建完決策樹之后,再對決策樹進行自底向上地剪枝判斷,因此訓練時間開銷會比預剪枝或者不剪枝決策樹要大。**

引用及參考:
[1]《機器學習》周志華著
[2]《統計學習方法》李航著
[3]《機器學習實戰》Peter Harrington著

寫在最后:本文參考以上資料進行整合與總結,屬於原創,文章中可能出現理解不當的地方,若有所見解或異議可在下方評論,謝謝!
若需轉載請注明http://www.cnblogs.com/lliuye/p/9008901.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM