在決策樹算法原理(上)這篇裏,咱們講到了決策樹裏ID3算法,和ID3算法的改進版C4.5算法。對於C4.5算法,咱們也提到了它的不足,好比模型是用較爲複雜的熵來度量,使用了相對較爲複雜的多叉樹,只能處理分類不能處理迴歸等。對於這些問題, CART算法大部分作了改進。CART算法也就是咱們下面的重點了。因爲CART算法能夠作迴歸,也能夠作分類,咱們分別加以介紹,先從CART分類樹算法開始,重點比較和C4.5算法的不一樣點。接着介紹CART迴歸樹算法,重點介紹和CART分類樹的不一樣點。而後咱們討論CART樹的建樹算法和剪枝算法,最後總結決策樹算法的優缺點。javascript
咱們知道,在ID3算法中咱們使用了信息增益來選擇特徵,信息增益大的優先選擇。在C4.5算法中,採用了信息增益比來選擇特徵,以減小信息增益容易選擇特徵值多的特徵的問題。可是不管是ID3仍是C4.5,都是基於信息論的熵模型的,這裏面會涉及大量的對數運算。能不能簡化模型同時也不至於徹底丟失熵模型的優勢呢?有!CART分類樹算法使用基尼係數來代替信息增益比,基尼係數表明了模型的不純度,基尼係數越小,則不純度越低,特徵越好。這和信息增益(比)是相反的。css
具體的,在分類問題中,假設有K個類別,第k個類別的機率爲\(p_k\), 則基尼係數的表達式爲:html
\[ Gini(p) = \sum\limits_{k=1}^{K}p_k(1-p_k) = 1- \sum\limits_{k=1}^{K}p_k^2 \]java
若是是二類分類問題,計算就更加簡單了,若是屬於第一個樣本輸出的機率是p,則基尼係數的表達式爲:python
\[ Gini(p) = 2p(1-p) \]算法
對於個給定的樣本D,假設有K個類別, 第k個類別的數量爲\(C_k\),則樣本D的基尼係數表達式爲:瀏覽器
\[ Gini(D) = 1-\sum\limits_{k=1}^{K}(\frac{|C_k|}{|D|})^2 \]
微信
特別的,對於樣本D,若是根據特徵A的某個值a,把D分紅D1和D2兩部分,則在特徵A的條件下,D的基尼係數表達式爲:markdown
\[ Gini(D,A) = \frac{|D_1|}{|D|}Gini(D_1) + \frac{|D_2|}{|D|}Gini(D_2) \]網絡
你們能夠比較下基尼係數表達式和熵模型的表達式,二次運算是否是比對數簡單不少?尤爲是二類分類的計算,更加簡單。可是簡單歸簡單,和熵模型的度量方式比,基尼係數對應的偏差有多大呢?對於二類分類,基尼係數和熵之半的曲線以下:
從上圖能夠看出,基尼係數和熵之半的曲線很是接近,僅僅在45度角附近偏差稍大。所以,基尼係數能夠作爲熵模型的一個近似替代。而CART分類樹算法就是使用的基尼係數來選擇決策樹的特徵。同時,爲了進一步簡化,CART分類樹算法每次僅僅對某個特徵的值進行二分,而不是多分,這樣CART分類樹算法創建起來的是二叉樹,而不是多叉樹。這樣一能夠進一步簡化基尼係數的計算,二能夠創建一個更加優雅的二叉樹模型。
對於CART分類樹連續值的處理問題,其思想和C4.5是相同的,都是將連續的特徵離散化。惟一的區別在於在選擇劃分點時的度量方式不一樣,C4.5使用的是信息增益比,則CART分類樹使用的是基尼係數。
具體的思路以下,好比m個樣本的連續特徵A有m個,從小到大排列爲\({a_1,a_2,...,a_m}\),則CART算法取相鄰兩樣本值的平均數,一共取得m-1個劃分點,其中第i個劃分點\(T_i表示\)爲:\(T_i = \frac{a_i+a_{i+1}}{2}\)。對於這m-1個點,分別計算以該點做爲二元分類點時的基尼係數。選擇基尼係數最小的點做爲該連續特徵的二元離散分類點。好比取到的基尼係數最小的點爲\(a_t\),則小於\(a_t\)的值爲類別1,大於\(a_t\)的值爲類別2,這樣咱們就作到了連續特徵的離散化。要注意的是,與ID3或者C4.5處理離散屬性不一樣的是,若是當前節點爲連續屬性,則該屬性後面還能夠參與子節點的產生選擇過程。
對於CART分類樹離散值的處理問題,採用的思路是不停的二分離散特徵。
回憶下ID3或者C4.5,若是某個特徵A被選取創建決策樹節點,若是它有A1,A2,A3三種類別,咱們會在決策樹上一下創建一個三叉的節點。這樣致使決策樹是多叉樹。可是CART分類樹使用的方法不一樣,他採用的是不停的二分,仍是這個例子,CART分類樹會考慮把A分紅\(\{A1\}和\{A2,A3\}\), \(\{A2\}和\{A1,A3\}\), \(\{A3\}和\{A1,A2\}\)三種狀況,找到基尼係數最小的組合,好比\(\{A2\}和\{A1,A3\}\),而後創建二叉樹節點,一個節點是A2對應的樣本,另外一個節點是{A1,A3}對應的節點。同時,因爲此次沒有把特徵A的取值徹底分開,後面咱們還有機會在子節點繼續選擇到特徵A來劃分A1和A3。這和ID3或者C4.5不一樣,在ID3或者C4.5的一棵子樹中,離散特徵只會參與一次節點的創建。
上面介紹了CART算法的一些和C4.5不一樣之處,下面咱們看看CART分類樹創建算法的具體流程,之因此加上了創建,是由於CART樹算法還有獨立的剪枝算法這一塊,這塊咱們在第5節講。
算法輸入是訓練集D,基尼係數的閾值,樣本個數閾值。
輸出是決策樹T。
咱們的算法從根節點開始,用訓練集遞歸的創建CART樹。
1) 對於當前節點的數據集爲D,若是樣本個數小於閾值或者沒有特徵,則返回決策子樹,當前節點中止遞歸。
2) 計算樣本集D的基尼係數,若是基尼係數小於閾值,則返回決策樹子樹,當前節點中止遞歸。
3) 計算當前節點現有的各個特徵的各個特徵值對數據集D的基尼係數,對於離散值和連續值的處理方法和基尼係數的計算見第二節。缺失值的處理方法和上篇的C4.5算法裏描述的相同。
4) 在計算出來的各個特徵的各個特徵值對數據集D的基尼係數中,選擇基尼係數最小的特徵A和對應的特徵值a。根據這個最優特徵和最優特徵值,把數據集劃分紅兩部分D1和D2,同時創建當前節點的左右節點,作節點的數據集D爲D1,右節點的數據集D爲D2.
5) 對左右的子節點遞歸的調用1-4步,生成決策樹。
對於生成的決策樹作預測的時候,假如測試集裏的樣本A落到了某個葉子節點,而節點裏有多個訓練樣本。則對於A的類別預測採用的是這個葉子節點裏機率最大的類別。
CART迴歸樹和CART分類樹的創建算法大部分是相似的,因此這裏咱們只討論CART迴歸樹和CART分類樹的創建算法不一樣的地方。
首先,咱們要明白,什麼是迴歸樹,什麼是分類樹。二者的區別在於樣本輸出,若是樣本輸出是離散值,那麼這是一顆分類樹。若是果樣本輸出是連續值,那麼那麼這是一顆迴歸樹。
除了概念的不一樣,CART迴歸樹和CART分類樹的創建和預測的區別主要有下面兩點:
1)連續值的處理方法不一樣
2)決策樹創建後作預測的方式不一樣。
對於連續值的處理,咱們知道CART分類樹採用的是用基尼係數的大小來度量特徵的各個劃分點的優劣狀況。這比較適合分類模型,可是對於迴歸模型,咱們使用了常見的和方差的度量方式,CART迴歸樹的度量目標是,對於任意劃分特徵A,對應的任意劃分點s兩邊劃分紅的數據集D1和D2,求出使D1和D2各自集合的均方差最小,同時D1和D2的均方差之和最小所對應的特徵和特徵值劃分點。表達式爲:
\[ \underbrace{min}_{A,s}\Bigg[\underbrace{min}_{c_1}\sum\limits_{x_i \in D_1(A,s)}(y_i - c_1)^2 + \underbrace{min}_{c_2}\sum\limits_{x_i \in D_2(A,s)}(y_i - c_2)^2\Bigg] \]
其中,\(c_1\)爲D1數據集的樣本輸出均值,\(c_2\)爲D2數據集的樣本輸出均值。
對於決策樹創建後作預測的方式,上面講到了CART分類樹採用葉子節點裏機率最大的類別做爲當前節點的預測類別。而回歸樹輸出不是類別,它採用的是用最終葉子的均值或者中位數來預測輸出結果。
除了上面提到了之外,CART迴歸樹和CART分類樹的創建算法和預測沒有什麼區別。
CART迴歸樹和CART分類樹的剪枝策略除了在度量損失的時候一個使用均方差,一個使用基尼係數,算法基本徹底同樣,這裏咱們一塊兒來說。
因爲決策時算法很容易對訓練集過擬合,而致使泛化能力差,爲了解決這個問題,咱們須要對CART樹進行剪枝,即相似於線性迴歸的正則化,來增長決策樹的泛化能力。可是,有不少的剪枝方法,咱們應該這麼選擇呢?CART採用的辦法是後剪枝法,即先生成決策樹,而後產生全部可能的剪枝後的CART樹,而後使用交叉驗證來檢驗各類剪枝的效果,選擇泛化能力最好的剪枝策略。
也就是說,CART樹的剪枝算法能夠歸納爲兩步,第一步是從原始決策樹生成各類剪枝效果的決策樹,第二部是用交叉驗證來檢驗剪枝後的預測能力,選擇泛化預測能力最好的剪枝後的數做爲最終的CART樹。
首先咱們看看剪枝的損失函數度量,在剪枝的過程當中,對於任意的一刻子樹T,其損失函數爲:
\[ C_{\alpha}(T_t) = C(T_t) + \alpha |T_t| \]
其中,\(\alpha\)爲正則化參數,這和線性迴歸的正則化同樣。\(C(T_t)\)爲訓練數據的預測偏差,分類樹是用基尼係數度量,迴歸樹是均方差度量。\(|T_t|\)是子樹T的葉子節點的數量。
當\(\alpha = 0\)時,即沒有正則化,原始的生成的CART樹即爲最優子樹。當\(\alpha = \infty\)時,即正則化強度達到最大,此時由原始的生成的CART樹的根節點組成的單節點樹爲最優子樹。固然,這是兩種極端狀況。通常來講,\(\alpha\)越大,則剪枝剪的越厲害,生成的最優子樹相比原生決策樹就越偏小。對於固定的\(\alpha\),必定存在使損失函數\(C_{\alpha}(T)\)最小的惟一子樹。
看過剪枝的損失函數度量後,咱們再來看看剪枝的思路,對於位於節點t的任意一顆子樹\(T_t\),若是沒有剪枝,它的損失是
\[ C_{\alpha}(T_t) = C(T_t) + \alpha |T_t| \]
若是將其剪掉,僅僅保留根節點,則損失是
\[ C_{\alpha}(T) = C(T) + \alpha \]
當\(\alpha = 0\)或者$\alpha \(很小時,\)C_{\alpha}(T_t) <; C_{\alpha}(T)$ , 當\(\alpha\)增大到必定的程度時
\[ C_{\alpha}(T_t) = C_{\alpha}(T) \]
。當\(\alpha\)繼續增大時不等式反向,也就是說,若是知足下式:
\[ \alpha = \frac{C(T)-C(T_t)}{|T_t|-1} \]
\(T_t\)和\(T\)有相同的損失函數,可是\(T\)節點更少,所以能夠對子樹\(T_t\)進行剪枝,也就是將它的子節點所有剪掉,變爲一個葉子節點\(T\)。
最後咱們看看CART樹的交叉驗證策略。上面咱們講到,能夠計算出每一個子樹是否剪枝的閾值\(\alpha\),若是咱們把全部的節點是否剪枝的值\(\alpha\)都計算出來,而後分別針對不一樣的\(\alpha\)所對應的剪枝後的最優子樹作交叉驗證。這樣就能夠選擇一個最好的\(\alpha\),有了這個\(\alpha\),咱們就能夠用對應的最優子樹做爲最終結果。
好了,有了上面的思路,咱們如今來看看CART樹的剪枝算法。
輸入是CART樹創建算法獲得的原始決策樹\(T\)。
輸出是最優決策子樹\(T_\alpha\)。
算法過程以下:
1)初始化\(\alpha_{min}= \infty\), 最優子樹集合\(\omega=\{T\}\)。
2)從葉子節點開始自下而上計算各內部節點t的訓練偏差損失函數\(C_{\alpha}(T_t)\)(迴歸樹爲均方差,分類樹爲基尼係數), 葉子節點數\(|T_t|\),以及正則化閾值\(\alpha= min\{\frac{C(T)-C(T_t)}{|T_t|-1}, \alpha_{min}\}\), 更新\(\alpha_{min}= \alpha\)
3) 獲得全部節點的\(\alpha\)值的集合M。
4)從M中選擇最大的值\(\alpha_k\),自上而下的訪問子樹t的內部節點,若是\(\frac{C(T)-C(T_t)}{|T_t|-1} \leq \alpha_k\)時,進行剪枝。並決定葉節點t的值。若是是分類樹,則是機率最高的類別,若是是迴歸樹,則是全部樣本輸出的均值。這樣獲得\(\alpha_k\)對應的最優子樹\(T_k\)
5)最優子樹集合\(\omega=\omega \cup T_k\), \(M= M -\{\alpha_k\}\)。
6) 若是M不爲空,則回到步驟4。不然就已經獲得了全部的可選最優子樹集合\(\omega\).
7) 採用交叉驗證在\(\omega\)選擇最優子樹\(T_\alpha\)
上面咱們對CART算法作了一個詳細的介紹,CART算法相比C4.5算法的分類方法,採用了簡化的二叉樹模型,同時特徵選擇採用了近似的基尼係數來簡化計算。固然CART樹最大的好處是還能夠作迴歸模型,這個C4.5沒有。下表給出了ID3,C4.5和CART的一個比較總結。但願能夠幫助你們理解。