前面介紹了決策樹的相關原理和實現,其實集成學習並非是由決策樹演變而來,之所以從決策樹引申至集成學習是因為常見的一些集成學習算法與決策樹有關比如隨機森林、GBDT以及GBDT的升華版Xgboost都是以決策樹為基礎的集成學習方法,故將二者放在一起進行討論。本節主要介紹關於集成學習的基本原理,后面會介紹一些典型的集成學習算法及應用。
集成學習從字面上就是集成很多分類器進行學習的過程,通過將一系列弱分類器的模型做一些簡單的線性組合,最終形成了一個較強的分類器。因此集成學習的一般思路有以下三種:
-
- 通過組合不同類型的分類器進行提升的方法
- 將相同類型不同參數的弱分類器進行組合
- 將相同類型但不同訓練集的弱分類器進行組合提升
一般第一種不是很常見,第二種和第三種較為常見,二者的主要區別是生成弱分類器的方式不同,第二種是期望生成的相互獨立的分類器,分類器之間相互依賴性不強,相當於並行生成的方法,比較有代表性的Bagging算法就屬於這一類,而Bagging中比較有名的是RF隨機森林算法;第三種是一種順序生成的模型,其在原來弱分類器的基礎上,不斷調整樣本,從而得到提升,分類器之間具有較強的依賴性,相當於串行的方法,其著名的代表為Boosting,而Boosting中最具有代表性的為AdaBoost。下面分別對這兩類進行介紹。
Bagging和隨機森林
Bagging的全稱為Bootstrap aggregating,其思想就是源於Bootstrap,Bootstrap主要用於發現樣本的概率分布,通過“自舉”的方法,不斷自采樣模擬隨機變量真實分布生成樣本集,其主要做法為:
-
- 從樣本集X中隨機抽取一個樣本,然后將樣本放回;
- 重復抽取N次,生成一個樣本數為N的樣本集;
- 重復上述步驟,完成M次,生成M個樣本大小為N個樣本集。
因此參考Bootstrap的方法,Bagging的做法就是不斷抽取數據集,並用抽取的數據集訓練弱分類器的過程,具體來說:
-
- 利用Bootstrap的方法抽取M個樣本大小為N的數據集;
- 通過抽取的數據集訓練M個弱分類器;
- 將M個弱分類器進行集成,一般為為簡單的線性組合。
所謂的簡單線性組合通常做法是:
-
- 對弱分類器的分類結果進行簡單投票
- 對於回歸則是簡單的線性加權
為什么利用集成學習能夠將弱分類器組合一起就能成為一個較強的分類器呢?
我們假設有M個弱分類器G1、G2、...、GM,所計算得到的映射結果分別為g1、g2、...、gM,則這些分類器通過線性組合得到的結果為:
假設弱分類器的錯誤率為ε,則有:
根據霍夫丁不等式https://www.cnblogs.com/nolonely/p/6155145.html:
從此式中可以看出錯誤率隨着M的增大呈指數減小,理論上M→∞,ε→0。
因此多個弱分類器組合在一起,就成為了一個強分類器。然而,在Bagging中我們前面提到,每個弱分類器的錯誤率是相互獨立的,但顯然這並不現實,因為數據來源於同一個數據集生成,存在一定的相關性,因此,Bagging比較適用於“不穩定”的分類器,即對數據比較敏感的分類器,若訓練樣本稍微改變,所得的結果就會有較大的變化,效果就越好,Bagging能夠顯著提升。
隨機森林
Bagging中有一個著名的算法為隨機森林(RF,Random Forest),隨機森林就是利用Bagging的思想,利用決策樹模型,生成很多個決策樹的弱分類器,不同於普通的Bagging算法,隨機森林在建模過程中,不但隨機抽取M個樣本量為N的樣本集,在每個弱分類器即決策樹建立的過程中,在生成節點時還從可選的特征中隨機挑選出一部分特征進行節點的分裂。那么總結下來隨機森林的生成流程如下:
-
- 如果訓練集大小為N,對於每棵樹而言,隨機且有放回地從訓練集中的抽取N個訓練樣本(這種采樣方式稱為bootstrap sample方法),作為該樹的訓練集;
- 如果每個樣本的特征維度為M,指定一個常數m<<M,隨機地從M個特征中選取m個特征子集,每次樹進行分裂時,從這m個特征中選擇最優的,通常情況下特征的選取數量為m=log2d;
- 每棵樹都盡最大程度的生長,並且沒有剪枝過程。
隨機森林的分類效果與下面因素有關:
-
- 前面有提到每個分類器要盡可能地獨立,因此森林中任意兩棵樹的相關性越大,錯誤率就越大;
- 另一個就是隨機森林中每棵樹的分類能力,每棵樹的分類能力越強,則最終的分類錯誤率就越低。
- 同時,隨機森林中樹的數量也是影響其性能和效率的參數,當樹的數量較少時,隨機森林分類的誤差較大,性能差,但當數量大到一定規模時,樹的復雜度將大大提升。
上面提到通常特征的選擇數量為m=log2d,當減小選擇特征數量m時,樹的相關性和分類能力都會同時降低,增大m時,樹的相關性和分類能力也會提升,因此需要平衡二者選取合適的m。
那么為什么要選擇分類器能力強作為基分類器呢?從隨機森林的期望和方差來看:
樣本的權重並沒有改變,因此整體的期望與基分類器相同,當選弱分類器作為基分類器時,則模型可能具有較大的偏差,則導致整體的偏差較大,因此必須選取較強的分類器作為基分類器。同時從方差公式來看,整體模型的方差小於等於基模型的方差,隨着模型數量m的增多,整體方差也在逐漸減小,從而防止過擬合的能力變強,但是,當模型數量達到一定數量時,方差第二項對於方差的改變作用很小,因此防止過擬合能力達到極致,這也解釋了為什么樹的數量為什么不能無限大。
那么,如何來衡量隨機森林的好壞呢?通常采用精度估計的方法來評價模型的好壞,而其中袋外(OOB,Out of Bag)精度評估方法可以在不加入測試樣本的情況下評估隨機森林分類器的好壞。隨機森林在構建過程中,每棵樹都有約1/3的樣本集((1-1/m)^m,當→∞時約等於37%≈1/3)沒有參與訓練,這部分數據稱之為OOB數據。分別對每個袋外數據利用隨機森林對這部分樣本進行分類,將誤分類的占總樣本的比率作為袋外錯誤率,實質上相當於進行了k折交叉實驗。
下面舉一個簡單的隨機森林的例子,還是用前面決策樹中氣球的例子來說明,由於顏色對於結果不起作用,故先刪去該特征,在構建隨機森林時,每次選取1個特征,即m=1,那么構建三棵樹如下:
那么給定一個樣本:小孩、用腳踩、小氣球是否會發生爆炸,那么根據上面建立的森林,進行投票表決(上圖中紅線路徑),爆炸票數1,不爆炸票數2,因此最終結果為不爆炸(也可以用概率的線性加權,最終結果也是不爆炸)。
這里就不說隨進森林的建立實現了,后續會利用數據集和python帶的sklearn包對隨進森林進行實現。
Boosting與AdaBoost
集成學習的另一種思想方法就是Boosting的方法,Boosting是基於概率近似正確(PAC)理論中的可學習性而來,所謂PAC的可學習性是指算法能夠在合理的時間內,以足夠大的概率輸出錯誤率較小的模型,分為“強可學習性”和“弱可學習性”。
-
- 強學習性是指存在一個多項式算法可以學習出准確率很高的模型;
- 弱學習性是指存在一個多項式可學習但僅可學習到准確率略高於隨機猜測的模型;
- 這兩者在PAC的學習框架下是等價的,這也就意味着只要找到了弱學習模型就可以把其變為強學習模型(這一部分涉及到PAC相關理論,有興趣后續再進一步學習)。
Boosting算法就是利用了這種思想,將弱學習算法提升為強學習算法,其具體做法是:
- 根據當前訓練數據訓練出一個弱模型;
- 根據弱模型的表現在下一輪訓練中改變樣本的權重,具體而言就是:讓弱模型在做錯的樣本中在后續學習中受到更多的關注,同時讓弱模型表現好的樣本在后續訓練中獲得更少的關注;
- 最后根據弱模型的表現決定弱模型的話語權,即投票表決時的可信度。
那么上述過程就產生了兩個問題:
- 在每一輪訓練中如何改變樣本的權重;
- 如何將弱分類器組合成為一個強分類器。
AdaBoost針對第一個問題提高錯誤分類樣本的權重降低正確樣本權重的做法,對於第二個問題AdaBoost采用加權多數表決的方式,具體來說就是加大誤差率小的弱分類器的權值,在表決中起到更大的作用,同時減小誤差率大的分類器的權重,使其話語權變小。具體算法過程為:
“”“”
輸入:樣本數量N的數據集、弱分類器算法、迭代次數M
輸出:強分類器G
- 初始化數據集的樣本權重W0=(w01,w02,...,w0N);
- 對於迭代次數1~M:
- 根據弱分類器算法和權重訓練出一個弱分類器gk,並計算加權錯誤率ek:
-
- 根據加權錯誤率,計算權重的更新的大小為:
-
- 根據權重更新的大小對樣本進行權重進行更新:
- 對弱分類器進行加權集成,形成強分類器:
“”“”
在用Boosting進行提升學習過程中,不宜選擇學習能力較強的模型,這樣可能會導致提升沒有意義或者不兼容,因為Boosting是讓弱模型專注某一個方面,最后再進行集中表決,若使用較強的模型的模型,可能包含了多個方面,最后表決出現模棱兩可的情況導致Boosting失去作用,可能模型在第一次產生模型就已經達到了最優,使得模型沒有提升空間。
具體解釋如下:Boosting的期望、方差可用下式表示:
可以發現,當選取強模型時,其具有較大的方差δ,從而導致整體的方差變大,防止過擬合的能力變差,因此必須選擇弱模型作為基分類器。從期望公式來看,隨着基分類器的增多,整體期望也就越接近真實值,整體模型准確度提高。但准確率並不會無限逼近1,正因為隨着訓練的進行,整體的方差變大,防止過擬合能力變差,導致准確度下降。
所謂的比較弱的弱模型比如說是限制層數的決策樹,最極端的情況下就是只有1個決策樹樁的決策時(這一點有待商榷,在《Python機器學習實戰》這本書中提到,使用決策樹樁進行提升,就成為了提升樹,但在其他資料中貌似沒有看到生成提升樹時需要特別注意樹的深度的),選用該弱分類器就成為了提升樹(Boosting Tree),提升樹既可以用於分類也可用於回歸。
新增:AdaBoost的推導過程
在這里補充上有關AdaBoost算法原理過程推導,以便於理解上述AdaBoost的迭代步驟。
首先,假設第m輪學習到的強學習器為fm(x),所學習到的弱分類器為Gm(x),那么由於模型是線性相加的,那么有:
在m輪中的損失函數為L,由於AdaBoost使用的是指數損失函數,那么L可以表示為:
那么進一步,將fm(x)帶入到損失函數中,開始對上式進行整理:
Gm(x)是弱分類器,那么其能夠將樣本分為-1和+1兩類(假設為二分類的情況),則有:
那么損失函數L可以改寫為:
上面主要用到了全集和子集的關系變換。
然后求L對α的偏導數:
令其等於0,解得α:
其中:
再由:
至此權重更新完畢,進入下一輪迭代,這里即為AdaBoost的推導過程。
提升樹
提升樹是Boosting的弱分類器采用決策樹的一種算法,這里主要說明回歸樹,為后面GBDT做一個鋪墊,提升樹是通過擬合上一顆樹的殘差,生成一顆新的樹,因此每次都僅有一個樹樁。下面是提升樹的生成原理。
假設上一輪所學習到最終的強分類器為fm-1(x)(疊加之后的),那么此時的損失函數為:
假設在本輪迭代中學習到的弱分類器hm(x),那么損失函數可以表示為(采用平方損失函數),通過最小化損失函數求hm(x):
這里的y-fm-1(x)=r即為殘差,這就表明每一次進行回歸樹生成時采用的訓練數據都是上次預測結果與訓練數據值之間的殘差。這個殘差會逐漸的減小。也就是說,讓上式損失函數最小,只需遍歷輸出結果為殘差的數據集可能產生的回歸樹樁,選出一顆使得和方差最小的樹樁即可。
其具體算法如下:
- 初始化決策函數f0(x)=0;
- 對於迭代次數1~M:
- 計算殘差:
-
- 擬合殘差rmi,選擇平方損失函數最小的切分點學習到一顆回歸樹,得到hm(x)
- 更新fm(x)=fm-1+hm(x)
- 最終得到提升樹模型:
這里添加一個提升樹建立過程的例子,例子來源於李航老師《統計學習方法》中, 有下面一組數據:
x | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
y | 5.56 | 5.70 | 5.91 | 6.40 | 6.80 | 7.05 | 8.90 | 8.70 | 9.0 | 9.05 |
現根據這組數據,構建一個提升樹模型,首先,根據回歸樹的建立過程,划分x的值有1.5、2.5、3.5、4.5、5.5、6.5、7.5、8.5、9.5,那么每一個取值都能將數據分為兩部分,那么取哪個數據呢?對於每個數據:
當x=1.5時:
將數據分為兩部分{1}、{2,3,4,5,6,7,8,9,10},此時兩個分支輸出c1=5.56,c2=(5.7+5.91+6.4+6.8+7.05+8.9+8.7+9.0+9.05)/9=7.5;
當x=2.5時:
將數據分為{1,2}、{3,4,5,6,7,8,9,10},此時c1=(5.56+5.7)/2=5.63,c2=(5.91+6.4+6.8+7.05+8.9+8.7+9.0+9.05)/8=7.726;
依次類推,得到如下這張表:
x' | 1.5 | 2.5 | 3.5 | 4.5 | 5.5 | 6.5 | 7.5 | 8.5 | 9.5 |
c1 | 5.56 | 5.63 | ... | ... | ... | ... | ... | ... | ... |
c2 | 7.5 | 7.726 | ... | ... | ... | ... | ... | ... | ... |
然后根據每個划分情況,計算每個節點划分后的殘差的總和,即:
那么有ms(1.5)=(5.56-5.56)2+[(5.7-7.5)2+(5.91-7.5)2+(6.4-7.5)2+(6.8-7.5)2+(7.05-7.5)2+(8.90-7.5)2+(8.7-7.5)2+(9.0-7.5)2+(9.05-7.5)2]=15.72;依次類推求得如下一張表:
x' | 1.5 | 2.5 | 3.5 | 4.5 | 5.5 | 6.5 | 7.5 | 8.5 | 9.5 |
ms | 15.72 | 12.08 | 8.36 | 5.78 | 3.91 | 1.93 | 8.01 | 11.73 |
15.74 |
然后發現當取值為6.5時ms最小,因此就以6.5作為划分值,將數據划分為兩部分{1,2,3,4,5,6}、{7,8,9,10},並根據x=6.5時的輸出值c1和c2,計算每個樣本的殘差,如表所示:
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
-0.68 | -0.54 | -0.33 | 0.16 | 0.56 | 0.81 | -0.01 | -0.21 | 0.09 | 0.14 |
同時,這樣就建立好了一棵樹:
然后將上邊的殘差表那個數據作為新的訓練數據,以此數據再建立一棵樹,建立過程與上述完全一致,得到第二棵樹:
那么將f1(x)與T2相加,得到第二輪訓練的強分類器:
按照上述步驟再進行多輪訓練,即可得到最終的強分類器f6 (x):
從上面過程可以看出,下一次訓練是基於上一次訓練的殘差數據進行的。
暫時就先到這里吧,決策樹和集成學習放在一起內容有點多,后邊還有比較重要的GBDT和XGBoost,還有很多地方理解不是很透徹,繼續學習。前一部分大概內容就是這樣,不是很全面,后續會對這一塊內容加深理解,會回頭進行內容上的補充,也盡可能添加一些示例。