集成學習綜合

前言

關於與集成學習相關的基礎決策樹 CART 的相關原理這裏不再介紹,請參考 決策樹 ★★

一、概念

集成學習的思想在於運用集體智慧,將多個弱學習器集成爲一個強學習器,常見的集成類型有 Bagging 和 Boosting 兩種,而對弱學習器的選擇有三種:1)不同類型的弱學習器;2)相同類型但參數不同的弱學習器;3)相同類型但訓練集不同的弱學習器。

Bagging

Bagging 運用的即是以上第三種思路。簡單而言,分爲三個步驟:

  • 使用 Bootstrap 生成若干個數據集;
  • 將這若干個數據集分別餵給若干個弱學習器訓練;
  • 預測時,將這若干個弱學習器的輸出結果簡單合成(分類時投票表決/迴歸時取平均)。

Bootstrap 有放回地從原樣本集中隨機抽取平均 63.2%個樣本的組合,具體原理在此不贅述。其隨機性使得基於 Bagging 原理的模型能夠有效避免過擬合。但萬物都有兩面,這樣的做法同時也對樣本的分佈提出更高的要求

Boosting

Bagging 對弱學習器的訓練是並行的,加入了更多的隨機過程,而串行處理的 Boosting 則賦予了弱學習器之間更大的依賴性,每一個弱學習器的變現都會對整體模型的表現有相當大的影響,因此需要對異常數據特別小心。分爲以下幾個步驟:

  • 訓練一個弱學習器;
  • 根據弱學習器的表現調整樣本數據;
  • 將調整過後的樣本餵給一個新的弱學習器訓練,重複以上步驟直到滿足停止條件。

二、算法

隨機森林

隨機森林是 Bagging 思想下最爲知名的算法應用,該算法不僅對樣本進行 Bootstrap 採樣,還新增了兩項特殊處理以增強隨機性:1)對每個新數據集隨機挑選特徵組成新的特徵空間;2)決策樹生成後不進行後剪枝,保持原有形式。在基礎決策樹的代碼已完備的基礎上,隨機森林的實現其實相當簡單,在此直接跳過。

AdaBoost

Abbr. Adaptive Boosting,最爲經典的 Boosting 分類模型,通過指數損失函數賦予分類錯誤的樣本更高的權重;每個弱學習器也會依據其分類精度獲取相應的最終投票權重係數。AdaBoost 一般用於分類任務,其具有普適性的思想使其也能應用於迴歸任務,只需要加入一定的判別條件 —— 迴歸值是否落在標籤值一定範圍之內。AdaBoost 對弱學習器的選擇沒有強制性要求,原則上弱學習器不應該太強,否則 AdaBoost 很難起到提升的效果。

Algorithm AdaBoost(DD,ff,mm):
Input: Sample data D={(Xi,yi)i=1,...,n}D=\{(X_i,y_i)|i=1,...,n\}, basic classifier/regressor ff, maximum iteration times mm.
Output: Prediction result y^\hat{y}.
 initialize weight array ww of sample data
for each epoch tt in mm epoches do
  construct a new sample data DD' by applying ww on original data DD
  feed DD' to a new weak classifier/regressor ftf'_t
  calculate error rate ete_t [0,1]\in[0,1]
  calculate voting weight of ftf'_t as αt=12ln1etet\alpha_t=\frac{1}{2}\cdot \ln \frac{1-e_{t}}{e_t}
  update ww based on the prediction performance, wi=wiexp[αtI]w_i=w_i\cdot \exp[-\alpha_t\mathbb{I}], indicator function I{1,1}\mathbb{I}\in\{1,-1\}
  normalize ww
 normalize α\alpha
 aggregate weak classifiers/regressors into a strong classifier/regressor F=t=1mαtftF=\sum_{t=1}^m \alpha_tf'_t
return F(X)F(X)

GBDT

Abbr. Gradient Boosting Decision Tree,梯度提升樹。與 AdaBoost 不同,GBDT 不調整樣本權重,而是在每次迭代時使用上一輪學習器損失函數的負梯度替代原有的數據標籤,訓練新的學習器。模型的預測結果將順着梯度方向逐步向標籤值靠近。在迴歸任務中,損失函數一般爲殘差的平方:L(yi,f(Xi))=(yif(Xi))2L(y_i,f(X_i))=\big(y_i-f(X_i)\big)^2gi=L(yi,f(Xi))f(Xi)=2[yif(Xi)]g_i=-\frac{\partial L(y_i,f(X_i))}{\partial f(X_i)}=2\big[y_i-f(X_i)\big]

二元分類任務中,當 yi{1,1}y_i\in\{1,-1\}
L(yi,f(Xi))=log[1+exp(yif(Xi))]L(y_i,f(X_i))=\log[1+\exp(-y_i\cdot f(X_i))]gi=L(yi,f(Xi))f(Xi)=yi1+exp(yif(Xi))g_i=-\frac{\partial L(y_i,f(X_i))}{\partial f(X_i)}=\frac{y_i}{1+\exp(y_if(X_i))}

多元分類任務相較而言更爲複雜,在每一輪迭代中,GBDT 會爲每一種分類生成一次決策樹,各個分類下決策樹的生成結果通過歸一化即爲樣本屬於各個分類的概率。假設一共有 KK 種分類,歸屬於 kk 分類的樣本標籤值 yi,k=1y_{i,k}=1yi,s=0(sk)y_{i,s}=0(s\ne k)
L(yi,f1(Xi),...,fK(Xi))=k=1Kyi,klogpk(Xi)L\big(y_i,f_1(X_i),...,f_K(X_i)\big)=\sum_{k=1}^Ky_{i,k}\log p_k(X_i)pk(Xi)=exp(fk(Xi))kexp(fk(Xi))p_k(X_i)=\frac{\exp(f_k(X_i))}{\sum_k\exp(f_k(X_i))}gi=L(yi,f1(Xi),...,fK(Xi))f(Xi)=yi,kpk(Xi)g_i=-\frac{\partial L\big(y_i,f_1(X_i),...,f_K(X_i)\big)}{\partial f(X_i)}=y_{i,k}-p_k(X_i)

不同於迴歸任務,由於分類模型最終生成的結果爲連續值,需要通過近似處理將連續值轉換爲離散值,以輸出分類結果。以下僞代碼及相關公式進行了適當的簡化處理,如有疑問請提出。

Algorithm GBDT(DD,TT,mm):
Input: Sample data D={(Xi,yi)i=1,...,n}D=\{(X_i,y_i)|i=1,...,n\}, basic classifier/regressor TT, maximum iteration times mm.
Output: Prediction result y^\hat{y}.
 initialize prediction result f0(Xi)=argminci=1nL(yi,c)f_0(X_i)=\arg\min_c\sum_{i=1}^nL(y_i,c)
for each epoch tt in mm epoches do
  calculate gradient for each sample (Xi,yi)(X_i,y_i), gi=L(yi,ft1(Xi))ft1(Xi)g_{i}=-\frac{\partial L(y_i,f_{t-1}(X_i))}{\partial f_{t-1}(X_i)}_{}
  use {(Xi,gi)}\{(X_i,g_i)\} to train a new classifier/regression TtT_t
  # at each node jj with subsample data dd, cj=argmincXidL(yi,ft1(Xi)+c)c_j^*=\arg\min_c\sum_{X_i\in d}L(y_i,f_{t-1}(X_i)+c)
  update ft(Xi)ft1(Xi)+Tt(Xi)f_t(X_i)\leftarrow f_{t-1}(X_i)+T_t(X_i)
return fm(X)f_m(X)

AdaBoost 中的 α\alpha 權重同樣也可應用於 GBDT 中,這樣一來通過迭代靠近標籤值的速度將減慢,意味着我們需要更多的迭代次數完成訓練。更多關於 GBDT 的介紹請見 相關論文相關博客

XGBoost

Abbr. eXtreme Gradient Boosting,由華盛頓大學的陳天奇帶領團隊開發,一經問世便大放異彩,至今仍然廣爲使用。該算法在 GBDT 的基礎上,進行了諸多優化和調整,最核心的幾項:1)在損失函數中引入正則項;2)使用擬牛頓法,引入泰勒二階展開式更新目標函數;3)對特徵的分佈進行分桶,取邊界作爲切割候選點;4)對分類型特徵自動進行 one-hot 特徵編碼。正則化後的損失函數表達式爲:Lr(yi,f(Xi))=L(yi,f(Xi))+Ω(f)L_r(y_i,f(X_i))=L(y_i,f(X_i))+\Omega(f) Ω(f)=γTleaf+12λw2\Omega(f)=\gamma T_{leaf}+\frac{1}{2}\lambda ||w||^2其中,Ω(f)\Omega(f) 即爲代表樹複雜度的正則項,TleafT_{leaf} 代表葉節點數目,w||w|| 爲葉節點固定輸出值的 L2 範數,γ\gammaλ\lambda 爲相應的懲罰係數。引入正則項後算法的泛化性能得到一定提升。在梯度更新方面,GBDT 通過計算負梯度 (一階求導) 擬合新的決策樹,而 XGBoost 採用擬牛頓法應用二階導數信息,加快優化速率。拋開數學理論層面,Python 中的 XGBoost 庫還通過以下方面實現優化:1)支持更多類型的基礎學習器;2)如同隨機森林,支持特徵子採樣及樣本子採樣,作爲過擬合的解決方案;3)添加了對稀疏數據集和缺失值的處理,將是否缺失認定爲一種劃分方式;4)通過特殊的內存處理方式,使得最優特徵的選取能夠並行化處理。更詳細的原理,推薦博文:XGBoost 的前世今生

LightGBM

XGBoost 的表現已非常優異,但在面對大批量數據時常常耗時過久。爲應對此問題,微軟在 2017 年初發布了 LightGBM,在不大幅度降低 XGBoost 準確度的基礎上對其運行速度與空間效率進行了大大提升。LightGBM 最核心的優化稱爲 直方圖優化,相對於 XGBoost,不僅僅在遍歷尋求最優切割點時應用直方圖,在節點分裂時通過將父節點與數據量較小的子節點進行直方圖做差,從而直接獲取另一個子節點的分佈,大幅度提高效率。此外,LightGBM 還修改了枝葉生長的方式 (level-wise to leaf-wise),將分類型特徵的處理從 XGBoost 的 one-hot 編碼改爲二分類條件判斷。更詳細的介紹,推薦博文:LightGBM——提升機器算法

CatBoost

Abbr. Category Boosting,由 Yandex 公司開發,基於 XGBoost 和 LightGBM 對 GBDT 算法做進一步調整,旨在解決各類因訓練數據和測試數據分佈不同而產生的數據偏移問題,在應對分類型變量時表現更爲優異。CatBoost 的兩大特性包括:1)針對分類型特徵進行獨特的數值化處理,Vk=Dxi=k+priorD+1V_k=\frac{|D_{x_i=k}|+prior}{|D|+1} (XGBoost 進行 one-hot 等方式處理,LightGBM 採用二分類條件判斷);2)對不同特徵進行組合。經過反覆測試,XGBoost 準確度最高但運行速度最慢,LightGBM 準確度稍次但速度快數倍以上,CatBoost 屬於均衡型選手,表現相對不太穩定。網絡上針對三種算法的實驗和對比並不少,讀者可自行查閱。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章