決策樹的剪枝
決策樹為什么要剪枝?原因就是避免決策樹“過擬合”樣本。前面的算法生成的決策樹非常的詳細而龐大,每個屬性都被詳細地加以考慮,決策樹的樹葉節點所覆蓋的訓練樣本都是“純”的。因此用這個決策樹來對訓練樣本進行分類的話,你會發現對於訓練樣本而言,這個樹表現堪稱完美,它可以100%完美正確得對訓練樣本集中的樣本進行分類(因為決策樹本身就是100%完美擬合訓練樣本的產物)。
但是,這會帶來一個問題,如果訓練樣本中包含了一些錯誤,按照前面的算法,這些錯誤也會100%一點不留得被決策樹學習了,這就是“過擬合”。C4.5的締造者昆蘭教授很早就發現了這個問題,他作過一個試驗,在某一個數據集中,過擬合的決策樹的錯誤率比一個經過簡化了的決策樹的錯誤率要高。那么現在的問題就來了,如何在原生的過擬合決策樹的基礎上,通過剪枝生成一個簡化了的決策樹?
第一種方法,也是最簡單的方法,稱之為基於誤判的剪枝。這個思路很直接,完全的決策樹不是過度擬合么,我再用一個測試數據集來糾正它。對於完全決策樹中的每一個非葉子節點的子樹,我們嘗試着把它替換成一個葉子節點,該葉子節點的類別我們用子樹所覆蓋訓練樣本中存在最多的那個類來代替,這樣就產生了一個簡化決策樹,然后比較這兩個決策樹在測試數據集中的表現,如果簡化決策樹在測試數據集中的錯誤比較少,並且該子樹里面沒有包含另外一個具有類似特性的子樹(所謂類似的特性,指的就是把子樹替換成葉子節點后,其測試數據集誤判率降低的特性),那么該子樹就可以替換成葉子節點。該算法以bottom-up的方式遍歷所有的子樹,直至沒有任何子樹可以替換使得測試數據集的表現得以改進時,算法就可以終止。
第一種方法很直接,但是需要一個額外的測試數據集,能不能不要這個額外的數據集呢?
為了解決這個問題,於是就提出了悲觀剪枝。該方法剪枝的依據是訓練樣本集中的樣本誤判率。我們知道一顆分類樹的每個節點都覆蓋了一個樣本集,根據算法這些被覆蓋的樣本集往往都有一定的誤判率,因為如果節點覆蓋的樣本集的個數小於一定的閾值,那么這個節點就會變成葉子節點,所以葉子節點會有一定的誤判率。而每個節點都會包含至少一個的葉子節點,所以每個節點也都會有一定的誤判率。悲觀剪枝就是遞歸得估算每個內部節點所覆蓋樣本節點的誤判率。剪枝后該內部節點會變成一個葉子節點,該葉子節點的類別為原內部節點的最優葉子節點所決定。然后比較剪枝前后該節點的錯誤率來決定是否進行剪枝。該方法和前面提到的第一種方法思路是一致的,不同之處在於如何估計剪枝前分類樹內部節點的錯誤率。
悲觀剪枝的思路非常巧妙。把一顆子樹(具有多個葉子節點)的分類用一個葉子節點來替代的話,誤判率肯定是上升的(這是很顯然的,同樣的樣本子集,如果用子樹分類可以分成多個類,而用單顆葉子節點來分的話只能分成一個類,多個類肯定要准確一些)。於是我們需要把子樹的誤判計算加上一個經驗性的懲罰因子。對於一顆葉子節點,它覆蓋了N個樣本,其中有E個錯誤,那么該葉子節點的錯誤率為(E+0.5)/N。這個0.5就是懲罰因子,那么一顆子樹,它有L個葉子節點,那么該子樹的誤判率估計為。這樣的話,我們可以看到一顆子樹雖然具有多個子節點,但由於加上了懲罰因子,所以子樹的誤判率計算未必占到便宜。剪枝后內部節點變成了葉子節點,其誤判個數J也需要加上一個懲罰因子,變成J+0.5。那么子樹是否可以被剪枝就取決於剪枝后的錯誤J+0.5在
的標准誤差內。
對於樣本的誤差率e,我們可以根據經驗把它估計成各種各樣的分布模型,比如是二項式分布,比如是正態分布。我們以二項式分布為例,啰嗦幾句來分析一下。什么是二項分布,在n次獨立重復試驗中,設事件A發生的次數為X,如果每次試驗中中事件A發生的概率是p,那么在n次獨立重復試驗中,事件A恰好發生k次的概率是
其概率期望值為np,方差為np(1-p)。比如投骰子就是典型的二項分布,投骰子10次,擲得4點的次數就服從n=10,p=1/6的二項分布。
如果二項分布中n=1時,也就是只統計一次,事件A只可能有兩種取值1或0,那么事件A的值所代表的分布就是伯努利分布。B(1,p)~f(1;1,p)就是伯努利分布,伯努利分布式是二項分布的一種特殊形式。比如投硬幣,正面值為1,負面值為0,那么硬幣為正面的概率為p=0.5,該硬幣值就服從概率為0.5的伯努利分布。
當n趨於無限大時,二項式分布就正態分布,如下圖。
那么一棵樹錯誤分類一個樣本值為1,正確分類一個樣本值為0,該樹錯誤分類的概率(誤判率)為e(e為分布的固有屬性,可以通過統計出來),那么樹的誤判次數就是伯努利分布,我們可以估計出該樹的誤判次數均值和方差:
把子樹替換成葉子節點后,該葉子的誤判次數也是一個伯努利分布,其概率誤判率e為(E+0.5)/N,因此葉子節點的誤判次數均值為
那么,如果子樹可以被葉子節點替代,它必須滿足下面的條件:
這個條件就是剪枝的標准。根據置信區間,我們設定一定的顯著性因子,我們可以估算出誤判次數的上下界。
誤判次數也可以被估計成一個正態分布,有興趣大家可以推導一下。
連續值屬性的改進
相對於那些離散值屬性,分類樹算法傾向於選擇那些連續值屬性,因為連續值屬性會有更多的分支,熵增益也最大。算法需要克服這種傾向。還記得前面講得如何克服分類樹算法傾向於離散值較多的離散屬性么?對了,我們利用增益率來克服這種傾向。增益率也可以用來克服連續值屬性傾向。增益率作為選擇屬性的依據克服連續值屬性傾向,這是沒有問題的。但是如果利用增益率來選擇連續值屬性的分界點,會導致一些副作用。分界點將樣本分成兩個部分,這兩個部分的樣本個數之比也會影響增益率。根據增益率公式,我們可以發現,當分界點能夠把樣本分成數量相等的兩個子集時(我們稱此時的分界點為等分分界點),增益率的抑制會被最大化,因此等分分界點被過分抑制了。子集樣本個數能夠影響分界點,顯然不合理。因此在決定分界點是還是采用增益這個指標,而選擇屬性的時候才使用增益率這個指標。這個改進能夠很好得抑制連續值屬性的傾向。當然還有其它方法也可以抑制這種傾向,比如MDL,有興趣的讀者可以自己閱讀相關文章。
處理缺失屬性
如果有些訓練樣本或者待分類樣本缺失了一些屬性值,那么該如何處理?要解決這個問題,需要考慮3個問題:
i)當開始決定選擇哪個屬性用來進行分支時,如果有些訓練樣本缺失了某些屬性值時該怎么辦?
ii)一個屬性已被選擇,那么在決定分支的時候如果有些樣本缺失了該屬性該如何處理?
iii)當決策樹已經生成,但待分類的樣本缺失了某些屬性,這些屬性該如何處理?
針對這三個問題,昆蘭提出了一系列解決的思路和方法。
對於問題i),計算屬性a的增益或者增益率時,如果有些樣本沒有屬性a,那么可以有這么幾種處理方式:
(1)忽略這些缺失屬性a的樣本。
(2)給缺失屬性a的樣本賦予屬性a一個均值或者最常用的的值。
(3)計算增益或者增益率時根據缺失屬性樣本個數所占的比率對增益/增益率進行相應的“打折”。
(4)根據其他未知的屬性想辦法把這些樣本缺失的屬性補全。
對於問題ii),當屬性a已經被選擇,該對樣本進行分支的時候,如果有些樣本缺失了屬性a,那么:
(1)忽略這些樣本。
(2)把這些樣本的屬性a賦予一個均值或者最常出現的值,然后再對他們進行處理。
(3)把這些屬性缺失樣本,按照具有屬性a的樣本被划分成的子集樣本個數的相對比率,分配到各個子集中去。至於哪些缺失的樣本被划分到子集1,哪些被划分到子集2,這個沒有一定的准則,可以隨機而動。
(4)把屬性缺失樣本分配給所有的子集,也就是說每個子集都有這些屬性缺失樣本。
(5)單獨為屬性缺失的樣本划分一個分支子集。
(6)對於缺失屬性a的樣本,嘗試着根據其他屬性給他分配一個屬性a的值,然后繼續處理將其划分到相應的子集。
對於問題iii),對於一個缺失屬性a的待分類樣本,有這么幾種選擇:
(1)如果有單獨的確實分支,依據此分支。
(2)把待分類的樣本的屬性a值分配一個最常出現的a的屬性值,然后進行分支預測。
(3)根據其他屬性為該待分類樣本填充一個屬性a值,然后進行分支處理。(F)在決策樹中屬性a節點的分支上,遍歷屬性a節點的所有分支,探索可能所有的分類結果,然后把這些分類結果結合起來一起考慮,按照概率決定一個分類。
(4)待分類樣本在到達屬性a節點時就終止分類,然后根據此時a節點所覆蓋的葉子節點類別狀況為其分配一個發生概率最高的類。
推理規則
C4.5決策樹能夠根據決策樹生成一系列規則集,我們可以把一顆決策樹看成一系列規則的組合。一個規則對應着從根節點到葉子節點的路徑,該規則的條件是路徑上的條件,結果是葉子節點的類別。C4.5首先根據決策樹的每個葉子節點生成一個規則集,對於規則集中的每條規則,算法利用“爬山”搜索來嘗試是否有條件可以移除,由於移除一個條件和剪枝一個內部節點本質上是一樣的,因此前面提到的悲觀剪枝算法也被用在這里進行規則簡化。MDL准則在這里也可以用來衡量對規則進行編碼的信息量和對潛在的規則進行排序。簡化后的規則數目要遠遠小於決策樹的葉子節點數。根據簡化后的規則集是無法重構原來的決策樹的。規則集相比決策樹而言更具有可操作性,因此在很多情況下我們需要從決策樹中推理出規則集。C4.5有個缺點就是如果數據集增大了一點,那么學習時間會有一個迅速地增長。
分類回歸樹CART
分類回歸樹(CART,Classification And Regression Tree)也屬於一種決策樹,上回文我們介紹了基於ID3算法的決策樹和C4.5的決策樹。這里只介紹CART是怎樣用於分類的。
分類回歸樹是一棵二叉樹,且每個非葉子節點都有兩個孩子,所以對於第一棵子樹其葉子節點數比非葉子節點數多1。
表1
名稱 | 體溫 | 表面覆蓋 | 胎生 | 產蛋 | 能飛 | 水生 | 有腿 | 冬眠 | 類標記 |
人 | 恆溫 | 毛發 | 是 | 否 | 否 | 否 | 是 | 否 | 哺乳類 |
巨蟒 | 冷血 | 鱗片 | 否 | 是 | 否 | 否 | 否 | 是 | 爬行類 |
鮭魚 | 冷血 | 鱗片 | 否 | 是 | 否 | 是 | 否 | 否 | 魚類 |
鯨 | 恆溫 | 毛發 | 是 | 否 | 否 | 是 | 否 | 否 | 哺乳類 |
蛙 | 冷血 | 無 | 否 | 是 | 否 | 有時 | 是 | 是 | 兩棲類 |
巨蜥 | 冷血 | 鱗片 | 否 | 是 | 否 | 否 | 是 | 否 | 爬行類 |
蝙蝠 | 恆溫 | 毛發 | 是 | 否 | 是 | 否 | 是 | 否 | 哺乳類 |
貓 | 恆溫 | 皮 | 是 | 否 | 否 | 否 | 是 | 否 | 哺乳類 |
豹紋鯊 | 冷血 | 鱗片 | 是 | 否 | 否 | 是 | 否 | 否 | 魚類 |
海龜 | 冷血 | 鱗片 | 否 | 是 | 否 | 有時 | 是 | 否 | 爬行類 |
豪豬 | 恆溫 | 剛毛 | 是 | 否 | 否 | 否 | 是 | 是 | 哺乳類 |
鰻 | 冷血 | 鱗片 | 否 | 是 | 否 | 是 | 否 | 否 | 魚類 |
蠑螈 | 冷血 | 無 | 否 | 是 | 否 | 有時 | 是 | 是 | 兩棲類 |
上例是屬性有8個,每個屬性又有多少離散的值可取。在決策樹的每一個節點上我們可以按任一個屬性的任一個值進行划分。比如最開始我們按:
1)表面覆蓋為毛發和非毛發
2)表面覆蓋為鱗片和非鱗片
3)體溫為恆溫和非恆溫
等等產生當前節點的左右兩個孩子。按哪種划分最好呢?有3個標准可以用來衡量划分的好壞:GINI指數、雙化指數、有序雙化指數。下面我們只講GINI指數。
GINI指數
總體內包含的類別越雜亂,GINI指數就越大(跟熵的概念很相似)。比如體溫為恆溫時包含哺乳類5個、鳥類2個,則:
體溫為非恆溫時包含爬行類3個、魚類3個、兩棲類2個,則
所以如果按照“體溫為恆溫和非恆溫”進行划分的話,我們得到GINI的增益(類比信息增益):
最好的划分就是使得GINI_Gain最小的划分。
終止條件
一個節點產生左右孩子后,遞歸地對左右孩子進行划分即可產生分類回歸樹。這里的終止條件是什么?什么時候節點就可以停止分裂了?直觀的情況,當節點包含的數據記錄都屬於同一個類別時就可以終止分裂了。這只是一個特例,更一般的情況我們計算χ2值來判斷分類條件和類別的相關程度,當χ2很小時說明分類條件和類別是獨立的,即按照該分類條件進行分類是沒有道理的,此時節點停止分裂。注意這里的“分類條件”是指按照GINI_Gain最小原則得到的“分類條件”。
假如在構造分類回歸樹的第一步我們得到的“分類條件”是:體溫為恆溫和非恆溫。此時:
哺乳類 | 爬行類 | 魚類 | 鳥類 | 兩棲類 | |
恆溫 | 5 | 0 | 0 | 2 | 0 |
非恆溫 | 0 | 3 | 3 | 0 | 2 |
這里χ2的計算方法就不說了。當選定置信水平后查表可得“體溫”與動物類別是否相互獨立。
還有一種方式就是,如果某一分支覆蓋的樣本的個數如果小於一個閾值,那么也可產生葉子節點,從而終止Tree-Growth。
剪枝
當分類回歸樹划分得太細時,會對噪聲數據產生過擬合作用。因此我們要通過剪枝來解決。剪枝又分為前剪枝和后剪枝:前剪枝是指在構造樹的過程中就知道哪些節點可以剪掉,於是干脆不對這些節點進行分裂,在N皇后問題和背包問題中用的都是前剪枝,上面的χ2方法也可以認為是一種前剪枝;后剪枝是指構造出完整的決策樹之后再來考查哪些子樹可以剪掉。
在分類回歸樹中可以使用的后剪枝方法有多種,比如:代價復雜性剪枝、最小誤差剪枝、悲觀誤差剪枝等等。這里我們只介紹代價復雜性剪枝法。
對於分類回歸樹中的每一個非葉子節點計算它的表面誤差率增益值α。
是子樹中包含的葉子節點個數;
是節點t的誤差代價,如果該節點被剪枝;
r(t)是節點t的誤差率;
p(t)是節點t上的數據占所有數據的比例。
是子樹Tt的誤差代價,如果該節點不被剪枝。它等於子樹Tt上所有葉子節點的誤差代價之和。
比如有個非葉子節點t4如圖所示:
已知所有的數據總共有60條,則節點t4的節點誤差代價為:
子樹誤差代價為:
以t4為根節點的子樹上葉子節點有3個,最終:
找到α值最小的非葉子節點,令其左右孩子為NULL。當多個非葉子節點的α值同時達到最小時,取最大的進行剪枝。
參考http://www.cnblogs.com/zhangchaoyang/articles/2709922.html
http://blog.sina.com.cn/s/blog_68ffc7a40100urn3.html