決策樹是既可以作為分類算法,又可以作為回歸算法,而且在經常被用作為集成算法中的基學習器。決策樹是一種很古老的算法,也是很好理解的一種算法,構建決策樹的過程本質上是一個遞歸的過程,采用if-then的規則進行遞歸(可以理解為嵌套的 if - else 的條件判斷過程),關於遞歸的終止條件有三種情形:
1)當前節點包含的樣本屬於同一類,則無需划分,該節點作為葉子節點,該節點輸出的類別為樣本的類別
2)該節點包含的樣本集合為空,不能划分
3)當前屬性集為空,則無法划分,該節點作為葉子節點,該節點的輸出類別為樣本中數量多數的類別
事實上,我們在遞歸的過程中不會等達到上面的條件才終止遞歸,往往會提前終止來減小過擬合(提前終止也是一種較好的減小過擬合的方式,不只是在決策樹算法中,在很多場景下都有應用)。
決策樹主要的有點是模型具有很好的可讀性,模型可以可視化,分類速度快(log(n) 的時間復雜度),本文介紹三種最常見的決策樹算法 — ID3,C4.5,CART,並介紹三種算法的優缺點。
1、信息論基礎
首先我們需要熟悉信息論中熵的概念,熵度量了事物的不確定性,熵越大,表示事物的不確定性越高,混亂程度越高。則隨機變量X的熵定義為:
![]()
條件熵H(Y|X)表示在已經知道隨機變量X的條件下隨機變量Y的不確定性,隨機變量X給定的條件下隨機變量Y的條件熵H(Y|X),定義為X給定條件下Y的條件概率分布的熵對X的數學期望:
![]()
2、ID3算法
前面說過決策樹本質上是 if-else 的嵌套,然而如何決定每一層的if 條件呢?在ID3算法中用的是信息增益作為選擇特征的指標,信息增益的定義是在特征A給定的條件下,集合D的信息熵H(D) 和在 特征A條件下的條件熵H(D|A) 的差值,描述了選取特征A對數據集進行划分對信息熵的減小程度,信息增益的表達式:
![]()
具體的信息增益計算過程如下:
1)計算數據集D的信息熵H(D):
![]()
2)計算特征A對數據集D的條件熵H(D|A):

3)計算信息增益g(D, A)
![]()
因此ID3算法的流程就很簡單了,每次都采用信息增益來選取最優划分特征來划分數據集,直到遇到了遞歸終止條件,具體算法流程如下:
定義輸入值:訓練數據集D,特征集A(可以從訓練集中提取出來),閥值ε(用來實現提前終止);
1)若當前節點中所有實例屬於同一類Ck,則該結點作為葉子節點,並將類別Ck作為該結點的輸出類;
2)若A為空,則將當前結點作為葉子節點,並將數據集中數量最多的類作為該結點輸出類;
3)否則,計算所有特征的信息增益,若此時最大的信息增益小於閥值ε,則將當前結點作為葉子節點,並將數據集中數量最多的類作為該結點輸出類;
4)若當前的最大信息增益大於閥值ε,則將最大信息增益對應的特征A作為最優划分特征對數據集進行划分,根據特征A的取值將數據集划分為若干個子集;
5)對第i個結點,以Di為訓練集,以Ai為特征集(將之前用過的特征從特征集中去除),遞歸的調用前面的1- 4 步。
ID3算法簡單,但是其缺點也不少:
1)ID3算法采用信息增益來選擇最優划分特征,然而人們發現,信息增益傾向與取值較多的特征,對於這種具有明顯傾向性的屬性,往往容易導致結果誤差;
2)ID3算法沒有考慮連續值,對與連續值的特征無法進行划分;
3)ID3算法無法處理有缺失值的數據;
4)ID3算法沒有考慮過擬合的問題,而在決策樹中,過擬合是很容易發生的;
5)ID3算法采用貪心算法,每次划分都是考慮局部最優化,而局部最優化並不是全局最優化,當然這一缺點也是決策樹的缺點,獲得最優決策樹本身就是一個NP難題,所以只能采用局部最優;
3、C4.5算法
C4.5算法的提出旨在解決ID3算法的缺點 ,因此講解C4.5算法我們從ID3算法的缺點出發:
1)采用信息增益比來替代信息增益作為尋找最優划分特征,信息增益比的定義是信息增益和特征熵的比值,對於特征熵,特征的取值越多,特征熵就傾向於越大;
信息增益比的表達式如下:

其中
,n是特征A取值的個數。
2)對於連續值的問題,將連續值離散化,在這里只作二類划分,即將連續值划分到兩個區間,划分點取兩個臨近值的均值,因此對於m個連續值總共有m-1各划分點,對於每個划分點,依次算它們的信息增益,選取信息增益最大的點作為離散划分點;
3)對於缺失值的問題,我們需要解決兩個問題,第一是在有缺失值的情況下如何選擇划分的屬性,也就是如何得到一個合適的信息增益比;第二是選定了划分屬性,對於在該屬性的缺失特征的樣本該如何處理。
對於第一個問題,對於某一個有缺失特征值的特征A。C4.5的思路是將數據分成兩部分,對每個樣本設置一個權重(初始可以都為1),然后划分數據,一部分是有特征值A的數據D1,另一部分是沒有特征A的數據D2. 然后對於沒有缺失特征A的數據集D1來和對應的A特征的各個特征值一起計算加權重后的信息增益比,最后乘上一個系數,這個系數是無特征A缺失的樣本加權后所占加權總樣本的比例。
對於第二個子問題,可以將缺失特征的樣本同時划分入所有的子節點,不過將該樣本的權重按各個子節點樣本的數量比例來分配。比如缺失特征A的樣本a之前權重為1,特征A有3個特征值A1,A2,A3。 3個特征值對應的無缺失A特征的樣本個數為2,3,4。則a同時划分入A1,A2,A3。對應權重調節為2/9,3/9,4/9;
4)對於過擬合的問題,采用了后剪枝算法和交叉驗證對決策樹進行剪枝處理,這個在CART算法中一起介紹。
雖說C4.5解決了ID3算法中的幾個缺點,但其仍有很多不足之處:
1)C4.5的剪枝算法不夠優秀;
2)C4.5和ID3一樣,都是生成的多叉樹,然而在計算機中二叉樹模型會比多叉樹的運算效率高,采用二叉樹也許效果會更好;
3)在計算信息熵時會涉及到大量的對數運算,如果是連續值還需要進行排序,尋找最優離散划分點,這些都會增大模型的運算;
4)C4.5算法只能處理分類問題,不能處理回歸問題,限制了其應用范圍。
4、CART算法
CART樹是在C4.5算法的基礎上對其缺點進行改進的算法,采用二叉樹作為樹模型的基礎結構,采用基尼指數(分類問題)和和方差(回歸問題)屬性來選取最優划分特征。CART算法由以下兩部組成:
1)決策樹生成:基於訓練集極大可能的生成決策樹(事實上,在生成樹的過程中可以加入一些閥值,對決策樹做一些預剪枝處理,配合之后的后剪枝效果會更好);
2)決策樹剪枝:用驗證數據集對已生成的樹進行剪枝並選擇最優子樹,這時用損失函數最小作為剪枝的標准(尋找全局最優子樹);
CART分類樹
先引入基尼指數,基尼指數也可以表述數據集D的不確定性,基尼指數越大,樣本集合的不確定性就越大,對於給定的樣本集,假設有k個類別,第k個類別的概率為Pk,則基尼指數的表達式為:

對於給定的樣本集合D,其基尼指數可以表述為:

在給定特征A的情況下,若集合被特征A的取值給分成D1和D2 ,則在特征A的條件下的基尼指數可以表述為:

因此在進行最優划分特征選擇時,我們選擇在該特征下基尼指數最小的特征,而且在二分類的問題中基尼指數和熵的差異不大,基尼指數和熵之半的曲線如下

引入基尼指數解決了計算熵時大量的對數運算的問題,然而CART樹是二叉樹,那么我們在選取了特征之后,又該如何划分數據集呢?
1)對於連續值
在C4.5中我們對於連續值的處理就是將其划分為兩類,那么在CART中更是如此,划分方式和C4.5算法一模一樣,唯一的區別是度量方式不同,在CART中采用基尼指數作為度量屬性,選擇使得在該特征下基尼指數最小的划分點來將連續值划分為兩類;
2)對於離散值
對與離散值的處理和ID3或者C4.5都有很大的不同,對於某個特征A,其取值可能不只兩個,對於取值大於2的,我們需要隨意組合將其分為兩類,選擇基尼指數最小的那一類作為當前的划分(因為對與特征A,並沒有將其按照取值完全分開,因此此時特征A不會從特征集中去除,會留到之后可能再被選擇,這也是和ID3、C4.5不同的地方)。
對於CART分類樹的算法流程和C4.5差不多,只要注意每次都是進行二類划分,即使該特征的取值有多個。
CART回歸樹
CART回歸樹是CART算法中新引進的用來處理回歸問題,其算法流程和CART分類樹差不多,但在細節上有寫不同,主要是以下兩個方面:
1)對連續值的處理方式不一樣,采用的特征選擇屬性不一樣,在這里采用的是常用的和方差來進行特征選擇,其表達式如下:

對於任意特征A,對應的任意划分點將數據集划分成D1和D2兩個部分,尋找到使得D1和D2各自集合的均方誤差最小,並且D1和D2的均方誤差之和也最小的划分點,該划分點就是該特征最佳的划分點,因此利用和方差選取最優特征時,就是選取使得和方差最小的特征和划分點。
2)決策樹的預測方式不一樣,在分類算法中都是采用葉子結點中數量最多的類別作為輸出值,而對於回歸問題,一般采用葉子結點中的樣本集的均值或者中位數作為輸出值,有的還會基於葉子結點中的集合建立線性回歸模型來作為輸出值。
CART算法雖然在C4.5算法的基礎上進行了很大的改進,但是仍然存在一些缺點:
1)每次用最優特征進行划分,這種貪心算法很容易陷入局部最優,事實上分類決策不應該由某一特征決定,而是一組特征決定的,比如多變量決策樹(事實上我覺得還不如用集成算法);
2)樣本敏感性,樣本的一點改動足以影響整個樹的結構,也可以通過集成算法解決;
感覺單獨的決策樹算法用的不多,決策樹大多是作為集成算法的基學習器來用的。
5、CART算法的剪枝
無論是對於分類樹還是回歸樹,都可以用同樣的方式進行剪枝,決策樹是非常容易過擬合的,因此對決策樹進行剪枝是很有必要的(剪枝說白了就是減小模型的復雜度),具體的剪枝算法如下:
首先我們看看剪枝的損失函數度量,在剪枝的過程中,對於任意的一刻子樹T,其損失函數為:
![]()
其中,α為正則化參數,這和線性回歸的正則化一樣。C(T)為訓練數據的預測誤差,分類樹是用基尼系數度量,回歸樹是均方差度量。|T|是子樹T的葉子節點的數量。當α=0時,即沒有正則化,原始的生成的CART樹即為最優子樹。當α= ∞ 時,即正則化強度達到最大,此時由原始的生成的CART樹的根節點組成的單節點樹為最優子樹。當然,這是兩種極端情況。一般來說,α越大,則剪枝剪的越厲害,生成的最優子樹相比原生決策樹就越偏小。對於固定的α,一定存在使損失函數Cα(T)最小的唯一子樹。
具體的從整體樹開始剪枝,對與任意內部結點,以t為單結點數的損失函數是:
![]()
以t為根節點的子樹Tt的損失函數是:
![]()
當α=0或者α很小時,Cα(Tt) < Cα(T) ;
當α增大到一定的程度時 Cα(Tt) = Cα(T);
當α繼續增大時不等式反向,也就是說,如果滿足:α=(C(T) − C(Tt)) / (|Tt| − 1),Tt和T有相同的損失函數,但是T節點更少,因此可以對子樹Tt進行剪枝,也就是將它的子節點全部剪掉,變為一個葉子節點T。
最后我們看看CART樹的交叉驗證策略。上面我們講到,可以計算出每個子樹是否剪枝的閾值α,如果我們把所有的節點是否剪枝的值α都計算出來,然后分別針對不同的α所對應的剪枝后的最優子樹做交叉驗證。這樣就可以選擇一個最好的α,有了這個α,我們就可以用對應的最優子樹作為最終結果。
現在我們現在來看看CART樹的剪枝算法:
輸入是CART樹建立算法得到的原始決策樹T;
輸出是最優決策子樹Tα;
具體算法過程如下:
1)初始化αmin = ∞, 最優子樹集合ω = {T};
2)從葉子節點開始自下而上計算各內部節點t的訓練誤差損失函數Cα(Tt)(回歸樹為均方差,分類樹為基尼系數), 葉子節點數|Tt|,以及正則化閾值α=min{(C(T) − C(Tt)) / (|Tt| − 1), αmin}, 更新αmin = α;
3) 得到所有節點的α值的集合M;
4)從M中選擇最大的值αk,自上而下的訪問子樹t的內部節點,如果(C(T) − C(Tt)) / (|Tt| − 1) ≤ αk時,進行剪枝。並決定葉節點t的值。如果是分類樹,則是概率最高的類別,如果是回歸樹,則是所有樣本輸出的均值。這樣得到αk對應的最優子樹Tk
5)最優子樹集合ω = ω ∪ Tk, M = M − {αk};
6) 如果M不為空,則回到步驟4。否則就已經得到了所有的可選最優子樹集合ω;
7) 采用交叉驗證在ω選擇最優子樹Tα
6、決策樹的優缺點
決策樹的優點:
1)決策樹簡單直觀,相比於如神經網絡之類的黑盒模型,決策樹容易理解,還可以進行可視化;
2)基本上不需要做預處理,不需要做歸一化,不需要處理缺失值;
3)使用決策樹進行預測的時間復雜度只有O(log2m),m為樣本數;
4)即可以處理離散值,也可以處理連續值,無論數對於分類問題還是回歸問題;
5)可以很容易的處理多分類的問題;
6)可以用交叉驗證來對決策數進行剪枝,避免過擬合(對於很復雜的決策樹,最好配合預剪枝一起處理);
7)對於異常點的容錯性好,健壯性高;
決策樹的缺點:
1)決策樹很容易過擬合,很多時候即使進行后剪枝也無法避免過擬合的問題,因此可以通過設置樹深或者葉節點中的樣本個數來進行預剪枝控制;
2)決策樹屬於樣本敏感型,即使樣本發生一點點改動,也會導致整個樹結構的變化,可以通過集成算法來解決;
3)尋找最優決策樹是各NP難題,一般是通過啟發式方法,這樣容易陷入局部最優,可以通過集成算法來解決;
4)決策樹無法表達如異或這類的復雜問題;
