集成学习-Boosting集成学习算法GBDT
?
GBDT算法的核心為:先構造一個(決策)樹,然后不斷在已有模型和實際樣本輸出的殘差上再構造一顆樹,依次迭代。
目錄
Decistion Tree(決策樹)
Gradient Boosting(梯度提升)
Shrinkage(漸變)
GBDT算法流程
回歸算法
二分類算法
多分類算法
GBDT損失函數
GBDT正則化
GBDT的兩個不同版本
sklearn參數
GBDT算法優缺點
GBDT的優點
GBDT的缺點
GBDT也是集成學習Boosting家族的成員,但是卻和傳統的Adaboost有很大的不同。
回顧下AdaBoost(集成學習-Boosting集成學習算法AdaBoost),我們是利用前一輪迭代弱學習器的誤差率來更新訓練集樣本的權重,這樣一輪輪的迭代下去。
GBDT也是迭代,但是是基于迭代累加的決策樹算法,它通過構造一組弱的學習器(樹),并把多顆決策樹的結果累加起來作為最終的預測輸出,弱學習器限定了只能使用CART回歸樹模型。GBDT這個算法有很多名字,但都是同一個算法:
GBRT (Gradient Boost Regression Tree) 漸進梯度回歸樹
GBDT (Gradient Boost Decision Tree) 漸進梯度決策樹
MART (MultipleAdditive Regression Tree) 多決策回歸樹
GBDT算法主要由三個部分組成:?
Decistion Tree(即DT?回歸樹)
Gradient Boosting(即GB?梯度提升)
Shrinkag(漸變)
Decistion Tree(決策樹)
提起決策樹(DT,Decision Tree) 絕大部分人首先想到的就是C4.5分類決策樹。但如果一開始就把GBDT中的樹想成分類樹,那就是錯誤的認識,所以說千萬不要以為GBDT是很多棵分類樹。
決策樹分為兩大類,回歸樹和分類樹。前者用于預測實數值,如明天的溫度、用戶的年齡、網頁的相關程度;后者用于分類標簽值,如晴天/陰天/霧/雨、用戶性別、網頁是否是垃圾頁面。這里要強調的是,前者的結果加減是有意義的,如10歲+5歲-3歲=12歲,后者則無意義,如男+男+女=到底是男是女? GBDT的核心在于累加所有樹的結果作為最終結果,就像前面對年齡的累加(-3是加負3),而分類樹的結果顯然是沒辦法累加的,所以GBDT中的樹都是回歸樹,不是分類樹,這點對理解GBDT相當重要(盡管GBDT調整后也可用于分類但不代表GBDT的樹是分類樹)。
分類樹
分類樹在每次分枝時,是窮舉每一個特征的每一個特征值,找到使得熵最大的特征分裂方式,按照該標準分枝得到兩個新節點,用同樣方法繼續分枝直到所有人都被分入性別唯一的葉子節點,或達到預設的終止條件,若最終葉子節點中的類別不唯一,則以多數人的類別作為該葉子節點的類別。
回歸樹
回歸樹總體流程也是類似,不過在每個節點(不一定是葉子節點)都會得一個預測值,以年齡為例,該預測值等于屬于這個節點的所有人年齡的平均值。分枝時窮舉每一個feature的每個閾值找最好的分割點,但衡量最好的標準不再是最大熵,而是最小化均方差,比如(每個人的年齡-預測年齡)^2 的總和 / N,或者說是每個人的預測誤差平方和除以 N。這很好理解,被預測出錯的人數越多,錯的越離譜,均方差就越大,通過最小化均方差能夠找到最靠譜的分枝依據。分枝直到每個葉子節點上人的年齡都唯一(這太難了)或者達到預設的終止條件(如葉子個數上限),若最終葉子節點上人的年齡不唯一,則以該節點上所有人的平均年齡做為該葉子節點的預測年齡。
分類樹和回歸樹基本流程一致都是根據feature找閾值(分裂值),但是閾值的衡量標準不同,即選擇的優化函數不同。分類樹選擇閾值的標準是實現每個分枝都盡可能只有一個分類,即性別分類中,男性分枝上盡可能多的是男性,女性盡可能少;女性分枝上盡可能多的是女性,男性盡可能少。用數學表示即男女比例原理1:1?;貧w樹選擇閾值的標準是實現預測值和真實值的最小化均方差。
回歸和分類從實現上,分別用不同的方法實現了"動態確定樣本權值"這一目標?;貧w是用擬合殘差,分類是用錯誤率來調整樣本權值。
?
Gradient Boosting(梯度提升)
提升的方法基于這樣一個思想:對于一個復雜任務來說,將多個專家的判斷進行適當的綜合所得出的判斷,要比其中任何一個專家單獨的判斷好。這種在函數域的梯度提升觀點對機器學習的很多領域有深刻影響。
提升是一個機器學習技術,可以用于回歸和分類問題,它每一步產生一個弱預測模型(如決策樹),并加權累加到總模型中,最終得帶一個強預測模型;如果每一步的弱預測模型生成都是依據損失函數的梯度方向,則稱之為梯度提升(Gradient boosting)。
梯度提升算法首先給定一個目標損失函數,它的定義域是所有可行的弱函數集合(基函數);提升算法通過迭代的選擇一個負梯度方向上的基函數來逐漸逼近局部極小值。
梯度提升算法實際上和梯度下降算法是一樣的,只不過看問題的角度不同,比如在線性回歸中,我們通過梯度下降來優化參數 ?,使損失函數能達到(局部)最小值;如果我們換個角度,我們優化的不是參數,而是這個函數,再通過沿梯度方向下降的方法達到損失函數(局部)最小值,就變成了梯度提升算法。
如下圖是梯度提升算法和梯度下降算法的對比情況??梢园l現,兩者都是在每一輪迭代中,利用損失函數相對于模型的負梯度方向的信息來對當前模型進行更新,只不過在梯度下降中,模型是以參數化形式表示,從而模型的更新等價于參數的更新。而在梯度提升中,模型并不需要進行參數化表示,而是直接定義在函數空間中,從而大大擴展了可以使用的模型種類。
原始的Boost算法(例如Adaboost)是在算法開始的時候,為每一個樣本賦上一個權重值,初始的時候,大家都是一樣重要的。在每一步訓練中得到的模型,會使得數據點的估計有對有錯,我們就在每一步結束后,增加分錯的點的權重,減少分對的點的權重,這樣使得某些點如果老是被分錯,那么就會被“嚴重關注”,也就被賦上一個很高的權重。然后等進行了N次迭代(由用戶指定),將會得到N個簡單的分類器(basic learner),然后我們將它們組合起來(比如說可以對它們進行加權、或者讓它們進行投票等),得到一個最終的模型。
GBDT的每一棵樹學的是之前所有樹結論和的殘差,這個殘差就是一個加預測值后能得真實值的累加量。比如A的真實年齡是18歲,但第一棵樹的預測年齡是12歲,差了6歲,即殘差為6歲。那么在第二棵樹里我們把A的年齡設為6歲去學習。如果第二棵樹真的能把A分到6歲的葉子節點,那累加兩棵樹的結論就是A的真實年齡。如果第二棵樹的結論是5歲,則A仍然存在1歲的殘差,第三棵樹里A的年齡就變成1歲,繼續學習,這就是Gradient Boosting在GBDT中的意義。
而Gradient Boost與傳統的Boost的區別是,每一次的計算是為了減少上一次的殘差(residual),而為了消除殘差,我們可以在殘差減少的梯度(Gradient)方向上建立一個新的模型。所以說,在Gradient Boost中,每個新的模型的建立是為了使得之前模型的殘差往梯度方向減少,與傳統Boost對正確、錯誤的樣本進行加權有著很大的區別。
在線性回歸中,我們希望找到一組參數使得模型的殘差最小化。如果只使用一次項來解釋二次曲線,那么就會存有大量殘差,此時就可以用二次項來繼續解釋殘差,所以可在模型中加入這個二次項。同樣的,GB是先根據初始模型計算偽殘差,之后建立一個學習器來解釋偽殘差,該學習器是在梯度方向上減少殘差。再將該學習器乘上權重系數(學習速率)和原來的模型進行線性組合形成新的模型。這樣反復迭代就可以找到一個使損失函數的期望達到最小的模型。
總的來說,對于一個樣本,最理想的梯度是越接近0的梯度。所以,我們要能夠讓函數的估計值能夠使得梯度往反方向移動(>0的維度上,往負方向移動,<0的維度上,往正方向移動)最終使得梯度盡量=0),并且該算法在會嚴重關注那些梯度比較大的樣本,跟Boost的意思類似。得到梯度之后,就是如何讓梯度減少了。這里是用的一個迭代+決策樹的方法,當初始化的時候,隨便給出一個估計函數F(x)(可以讓F(x)是一個隨機的值,也可以讓F(x)=0),然后之后每迭代一步就根據當前每一個樣本的梯度的情況,建立一棵決策樹。就讓函數往梯度的反方向前進,最終使得迭代N步后,梯度越小。這里建立的決策樹和普通的決策樹不太一樣,首先,這個決策樹是一個葉子節點數J固定的,當生成了J個節點后,就不再生成新的節點了。
?
Shrinkage(漸變)
Shrinkage是GBDT的第三個基本概念,中文含義為“縮減”。它的基本思想就是:每次走一小步逐漸逼近結果的效果,要比每次邁一大步很快逼近結果的方式更容易避免過擬合。換句話說縮減思想不完全信任每一個棵殘差樹,它認為每棵樹只學到了真理的一小部分,累加的時候只累加一小部分,只有通過多學幾棵樹才能彌補不足。
Shrinkage不是Gradient的步長,Shrinkage只是一種大步變小步的逐步求精方法。這點看起來和Gradient目標=Gradient單位方向*步長挺像。但其實很不同:
(1)shrinkage的處理對象不一定是Gradient方向,也可以是殘差,可以是任何增量,即目標=任何東西*shrinkage步長。
(2)shrinkage決定的是最終走出的一步大小,而不是希望走出的一步大小。前者是對于已有的學習結果打折,后者是在決定學習目標時對局部最優方向上走多遠負責。
(3)shrinkage設小了只會讓學習更慢,設大了就等于沒設,它適用于所有增量迭代求解問題;而Gradient的步長設小了容易陷入局部最優點,設大了容易不收斂。它僅用于用梯度下降求解。這兩者其實沒太大關系。LambdaMART中其實兩者都用了,而外部可配的參數是shrinkage而不是Gradient步長。
即Shrinkage仍然以殘差作為學習目標,但對于殘差學習出來的結果,只累加一小部分(step*殘差)逐步逼近目標,step一般都比較小,如0.01~0.001(注意該step非gradient的step),導致各個樹的殘差是漸變的而不是陡變的。直覺上這也很好理解,不像直接用殘差一步修復誤差,而是只修復一點點,其實就是把大步切成了很多小步。本質上,Shrinkage為每棵樹設置了一個weight,累加時要乘以這個weight,但和Gradient并沒有關系。這個weight就是step。就像Adaboost一樣,Shrinkage能減少過擬合發生也是經驗證明的,目前還沒有看到從理論的證明。
?
GBDT算法流程
回歸算法
輸入:訓練樣本
迭代次數(基學習器數量):T
損失函數:L
輸出:強學習器H(x)
二分類算法
多分類算法
GBDT損失函數
這里我們再看看GBDT分類算法,GBDT的分類算法從思想上和GBDT的回歸算法沒有區別,但是由于樣本輸出不是連續的值,而是離散的類別,導致我們無法直接從輸出類別去擬合類別輸出的誤差。
為了解決這個問題,主要有兩個方法,一個是用指數損失函數,此時GBDT退化為Adaboost算法。另一種方法是用類似于邏輯回歸的對數似然損失函數的方法。也就是說,我們用的是類別的預測概率值和真實概率值的差來擬合損失,本文僅討論用對數似然損失函數的GBDT分類。
?
GBDT正則化
針對GBDT正則化,我們通過子采樣比例方法和定義步長v方法來防止過擬合。
-
**子采樣比例:**通過不放回抽樣的子采樣比例(subsample),取值為(0,1]。如果取值為1,則全部樣本都使用。如果取值小于1,利用部分樣本去做GBDT的決策樹擬合。選擇小于1的比例可以減少方差,防止過擬合,但是會增加樣本擬合的偏差。因此取值不能太低,推薦在[0.5, 0.8]之間。
-
**定義步長v:**針對弱學習器的迭代,我們定義步長v,取值為(0,1]。對于同樣的訓練集學習效果,較小的v意味著我們需要更多的弱學習器的迭代次數。通常我們用步長和迭代最大次數一起來決定算法的擬合效果。
?
GBDT的兩個不同版本
目前GBDT有兩個不同的描述版本,兩者各有支持者,讀文獻時要注意區分。
殘差版本把GBDT說成一個殘差迭代樹,認為每一棵回歸樹都在學習前N-1棵樹的殘差,在ELF開源軟件實現中用的也是這一版本。
Gradient版本把GBDT說成一個梯度迭代樹,使用梯度下降法求解,認為每一棵回歸樹在學習前N-1棵樹的梯度下降值,之前leftnoteasy的博客中介紹的為此版本,umass的源碼實現中用的則是這一版本(準確的說是LambdaMART中的MART為這一版本,MART實現則是前一版本)。?
總的來說兩者相同之處在于,都是迭代回歸樹,都是累加每顆樹結果作為最終結果(Multiple Additive Regression Tree),每棵樹都在學習前N-1棵樹尚存的不足,從總體流程和輸入輸出上兩者是沒有區別的;兩者的不同主要在于每步迭代時,是否使用Gradient作為求解方法。前者不用Gradient而是用殘差,殘差是全局最優值,Gradient是局部最優方向*步長,即前者每一步都在試圖讓結果變成最好,后者則每步試圖讓結果更好一點。
兩者優缺點。看起來前者更科學一點,有絕對最優方向不學,為什么舍近求遠去估計一個局部最優方向呢?原因在于靈活性。前者最大問題是,由于它依賴殘差,cost function一般固定為反映殘差的均方差,因此很難處理純回歸問題之外的問題。而后者求解方法為梯度下降,只要可求導的cost function都可以使用,所以用于排序的LambdaMART就是用的后者。
GBDT中的Boost是樣本目標的迭代,不是re-sampling的迭代,也不是Adaboost。
Adaboost中的boosting指從樣本中按分類對錯,分配不同的weight,計算cost function時使用這些weight,從而讓“錯分的樣本權重越來越大,直到它們被分對”。Bootstrap也有類似思想,只不過它可以利用不同的weight作為sample概率對訓練樣本集做re-sample,讓錯分的樣本被進一步學習,而分類正確的樣本就不用再學了。但GBDT中的boost完全不同,跟上述邏輯沒有任何關系,GBDT中每步boost的樣本集都是不變的,變的是每個樣本的回歸目標值。
?
sklearn參數
GradientBoostingRegressor(loss=’ls’, learning_rate=0.1, n_estimators=100, subsample=1.0, criterion=’friedman_mse’, min_samples_split=2,min_samples_leaf=1, min_weight_fraction_leaf=0.0, max_depth=3,min_impurity_decrease=0.0, min_impurity_split=None, init=None, random_state=None, max_features=None, alpha=0.9, verbose=0, max_leaf_nodes=None, warm_start=False, presort=’auto’, validation_fraction=0.1, n_iter_no_change=None, tol=0.0001)參數說明:
- n_estimators:弱學習器的最大迭代次數,也就是最大弱學習器的個數。
- learning_rate:步長,即每個學習器的權重縮減系數a,屬于GBDT正則化方化手段之一。
- subsample:子采樣,取值(0,1]。決定是否對原始數據集進行采樣以及采樣的比例,也是GBDT正則化手段之一。
- init:我們初始化的時候的弱學習器。若不設置,則使用默認的。
- loss:損失函數,可選{'ls'-平方損失函數,'lad'絕對損失函數-,'huber'-huber損失函數,'quantile'-分位數損失函數},默認'ls'。
- alpha:當我們在使用Huber損失"Huber"和分位數損失"quantile"時,需要指定相應的值。默認是0.9,若噪聲點比較多,可適當降低這個分位數值。
- criterion:決策樹節搜索最優分割點的準則,默認是"friedman_mse",可選"mse"-均方誤差與'mae"-絕對誤差。
- max_features:劃分時考慮的最大特征數,就是特征抽樣的意思,默認考慮全部特征。
- max_depth:樹的最大深度。
- min_samples_split:內部節點再劃分所需最小樣本數。
- min_samples_leaf:葉子節點最少樣本數。
- max_leaf_nodes:最大葉子節點數。
- min_impurity_split:節點劃分最小不純度。
- presort:是否預先對數據進行排序以加快最優分割點搜索的速度。默認是預先排序,若是稀疏數據,則不會預先排序,另外,稀疏數據不能設置為True。
- validationfraction:為提前停止而預留的驗證數據比例。當n_iter_no_change設置時才能用。
- n_iter_no_change:當驗證分數沒有提高時,用于決定是否使用早期停止來終止訓練。
?
GBDT算法優缺點
GBDT的優點
(1)防止過擬合;
(2)每一步的殘差計算其實變相地增大了分錯instance的權重,而已經分對的instance則都趨向于0;
(3)殘差作為全局最優的絕對方向;
(4)使用一些健壯的損失函數,對異常值的魯棒性非常強。比如 Huber損失函數和Quantile損失函數。
GBDT的缺點
(1)Boost是一個串行過程,不好并行化,而且計算復雜度高,比較耗時(大數據量非常耗時);
(2)同時不太適合高維特征,如果數據維度較高時會加大算法的計算復雜度,具體的復雜度可以參考XGBoost、lightGBM的改進點;
?
?
?
參考鏈接:https://zhuanlan.zhihu.com/p/58105824
參考鏈接:https://www.jianshu.com/p/b954476a00d9
參考鏈接:https://www.zybuluo.com/Dounm/note/1031900
參考鏈接:https://zhuanlan.zhihu.com/p/30736738
參考鏈接:https://blog.csdn.net/XiaoYi_Eric/article/details/80167968
?
《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀總結
以上是生活随笔為你收集整理的集成学习-Boosting集成学习算法GBDT的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Hadoop中任务提交运行流程
- 下一篇: 集成学习-Boosting集成学习算法X