github:代碼實現
本文算法均使用python3實現
1. 決策樹
決策樹(decision tree)是一種基本的分類與回歸方法(本文主要是描述分類方法),是基於樹結構進行決策的,可以將其認為是if-then規則的集合。一般的,一棵決策樹包含一個根節點、若干內部節點和若干葉節點。其中根節點包含所有樣本點,內部節點作為划分節點(屬性測試),葉節點對應於決策結果。
用決策樹進行分類,是從根節點開始,對實例的某一特征進行測試,根據測試結果,將實例分配到其子節點,若該子節點仍為划分節點,則繼續進行判斷與分配,直至將實例分到葉節點的類中。
若對以上描述不太明白,可以結合以下圖進行理解。
以上是由決策樹來進行分類的過程。而決策樹的學習(構建)通常是一個 遞歸地選擇最優特征的過程。那么構建決策樹時如何**選擇特征作為划分點**(即選擇哪個特征作為根節點或者選擇哪個特征作為非葉子節點)?當訓練數據量大、特征數量較多時構建的**決策樹可能很龐大**,這樣的決策樹用來分類是否好?
由這些問題我們可以知道,構建決策樹的三個要點: (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 $ 為類別個數。
現在我們使用例子,來理解熵的計算:
其中 $ 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 $,則“色澤”特征的信息增益為:
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)
預剪枝是指在決策樹生成過程中,對每個節點在划分前先進行估計,若當前節點的划分不能帶來決策樹泛化性能的提升,則停止划分並將當前節點標記為葉節點。
我們使用例子進一步理解預剪枝的過程:
將本文開始的西瓜數據集表划分成兩部分,一部分作為訓練集用來構建決策樹,一部分作為驗證集用來進行決策樹的剪枝。具體划分見下圖:
**可有由圖中看出,該決策樹有點過於簡單,雖然降低的過擬合的風險,但是由於其基於“貪心”的本質禁止了其它分支的展開,給預剪枝決策樹帶來了欠擬合的風險。** ### 4.1 后剪枝(Post-Pruning) **后剪枝**是指先從訓練集生成一棵完整的決策樹,然后自底向上地對非葉節點進行考察,若將該節點對應的子樹替換為葉節點能帶來決策能力的提升,則將該子樹替換成葉節點。 我們使用例子進一步理解后剪枝的過程: 同樣適用4.1中的划分數據集。針對已建立好的決策樹,我們首先對“紋理”特征節點進行處理,判斷其是否需要剪枝,見下圖。
**后剪枝決策樹通常比預剪枝決策樹保留了更多的分支,一般情況下,后剪枝決策樹欠擬合的風險很小,其泛化能力往往優於預剪枝預測數。但由於其是基於創建完決策樹之后,再對決策樹進行自底向上地剪枝判斷,因此訓練時間開銷會比預剪枝或者不剪枝決策樹要大。**
引用及參考:
[1]《機器學習》周志華著
[2]《統計學習方法》李航著
[3]《機器學習實戰》Peter Harrington著
寫在最后:本文參考以上資料進行整合與總結,屬於原創,文章中可能出現理解不當的地方,若有所見解或異議可在下方評論,謝謝!
若需轉載請注明:http://www.cnblogs.com/lliuye/p/9008901.html