1. 程式人生 > >boosting系列演算法

boosting系列演算法

boosting是一種整合學習演算法,由一系列基本分類器按照不同的權重組合成為一個強分類器,這些基本分類器之間有依賴關係。包括Adaboost演算法、提升樹、GBDT演算法。

一、Adaboost演算法

1、基本思想
通過兩個問題:
1)如何更新樣本權重D? 提高被弱分類器錯分樣本的權值,降低正分樣本的權值,作為下一輪基本分類器的訓練樣本。
2)如何將弱分類器組合成強分類器? 加權多數表決,誤差率小的分類器的權值大,使其在表決過程中起較大作用。
AdaBoost是個二分類演算法。
2、推導
Adaboost的基本分類器的損失函式為指數函式,推導過程就是圍繞最小化損失函式展開的。主要目的是推匯出樣本權值的更新公式、基本分類器的權值計算公式。
在這裡插入圖片描述


3、演算法描述
在這裡插入圖片描述

二、提升樹演算法

1、基本思想
當Adaboost演算法中的基本分類器是cart迴歸樹時,就是提升樹,同時,損失函式變為平方誤差損失函式。在Adaboost演算法中通過改變樣本的權重來進行每一輪的基本分類器的學習,在提升樹演算法中,是通過上一輪學習的殘差進行本輪的學習。

2、推導
和Adaboost演算法一樣,也是求最小化損失函式下第m顆樹模型的引數 θ m

\theta_m
在這裡插入圖片描述
f m ( x ) f_m(x) 是第m輪迭代的提升樹模型, T
( x ; θ m ) T(x;\theta_m)
是第m輪的樹模型。最後我們得到的模型是 f M ( x ) f_M(x)
通過推導發現,每一輪擬合的是上一輪的殘差,通過最小化平方損失函式來擬合。

3、演算法描述
在這裡插入圖片描述
一棵迴歸樹: T ( x ; θ m ) = j = 1 J c j I ( x R j ) T(x;\theta_m)=\sum_{j=1}^J{c_jI( x \in R_j)}
4、舉例
在這裡插入圖片描述

三、GBDT

1、基本思想
和提升樹演算法差不多,只不過GBDT的損失函式是不再是平方損失函式,而是一般的損失函式,所以用損失函式的負梯度來代替殘差,也就是說,每一輪擬合的是上一輪損失函式的負梯度,擬合的過程也是求最小二乘迴歸樹的過程。

2、演算法描述
在這裡插入圖片描述
GBDT不再使用殘差作為新的訓練資料而是使用損失函式的梯度作為新的新的訓練資料的y值,具體的來說就是使用損失函式對 f ( x ) f(x) 求梯度然後帶入 f m 1 ( x ) f_{m-1}(x) 計算。

GBDT與提升樹之間的關係:
 提升樹模型每一輪的訓練都是靠上次的預測結果與真實值的差值作為新的訓練資料進行重新訓練,GBDT則是將殘差計算替換成了損失函式的梯度方向,將上一次的預測結果帶入梯度中求出本輪的訓練資料,這兩種模型就是在生成新的訓練資料時採用了不同的方法。
 boosting tree和GBDT,每一輪的樹都是二層的(根節點+葉子節點),與一般的決策樹的對比:
 在這裡插入圖片描述

四、XGBoost

XGBoost 就是對GBDT的實現,但是一般來說,gradient boosting 的實現是比較慢的,因為每次都要先構造出一個樹並新增到整個模型序列中。而 XGBoost 的特點就是計算速度快,模型表現好.
表現快是因為它具有這樣的設計:
1、Parallelization: 訓練時可以用所有的 CPU 核心來並行化建樹。
2、Distributed Computing : 用分散式計算來訓練非常大的模型。
3、Out-of-Core Computing: 對於非常大的資料集還可以進行 Out-of-Core Computing。
4、Cache Optimization of data structures and algorithms: 更好地利用硬體。

xgboost和GBDT的不同之處? 參考:https://www.zhihu.com/question/41354392/answer/98658997

1、傳統GBDT以CART作為基分類器,xgboost還支援線性分類器,傳統GBDT在優化時只用到一階導數資訊,xgboost則對代價函式進行了二階泰勒展開,同時用到了一階和二階導數。順便提一下,xgboost工具支援自定義代價函式,只要函式可一階和二階求導。
2、xgboost在代價函式里加入了正則項,用於控制模型的複雜度。正則項裡包含了樹的葉子節點個數、每個葉子節點上輸出的score的L2模的平方和。從Bias-variance tradeoff角度來講,正則項降低了模型的variance,使學習出來的模型更加簡單,防止過擬合,這也是xgboost優於傳統GBDT的一個特性。
3、Shrinkage(縮減),相當於學習速率(xgboost中的eta)。xgboost在進行完一次迭代後,會將葉子節點的權重乘上該係數,主要是為了削弱每棵樹的影響,讓後面有更大的學習空間。實際應用中,一般把eta設定得小一點,然後迭代次數設定得大一點。(補充:傳統GBDT的實現也有學習速率)
4、列抽樣(column subsampling)。xgboost借鑑了隨機森林的做法,支援列抽樣,不僅能降低過擬合,還能減少計算,這也是xgboost異於傳統gbdt的一個特性。
5、對缺失值的處理。對於特徵的值有缺失的樣本,xgboost可以自動學習出它的分裂方向。
6、xgboost工具支援並行。boosting不是一種序列的結構嗎?怎麼並行的?注意xgboost的並行不是tree粒度的並行,xgboost也是一次迭代完才能進行下一次迭代的(第t次迭代的代價函式裡包含了前面t-1次迭代的預測值)。xgboost的並行是在特徵粒度上的。我們知道,決策樹的學習最耗時的一個步驟就是對特徵的值進行排序(因為要確定最佳分割點),xgboost在訓練之前,預先對資料進行了排序,然後儲存為block結構,後面的迭代中重複地使用這個結構,大大減小計算量。這個block結構也使得並行成為了可能,在進行節點的分裂時,需要計算每個特徵的增益,最終選增益最大的那個特徵去做分裂,那麼各個特徵的增益計算就可以開多執行緒進行。
可並行的近似直方圖演算法。樹節點在進行分裂時,我們需要計算每個特徵的每個分割點對應的增益,即用貪心法列舉所有可能的分割點。當資料無法一次載入記憶體或者在分散式情況下,貪心演算法效率就會變得很低,所以xgboost還提出了一種可並行的近似直方圖演算法,用於高效地生成候選的分割點。
7、內建交叉驗證,XGBoost允許在每一輪boosting迭代中使用交叉驗證。
呼叫:

import xgboost
watchlist = [(train_matrix, 'train'), (val_matrix, 'eval')]
model = xgboost.train(param, train_matrix, num_boost_round=num_round, evals=watchlist, early_stopping_rounds=early_stopping_rounds)

1、params 引數字典,裡面包含著訓練中的引數關鍵字和對應的值,形式是

init_param = {
        'max_depth': 8,
        'eta': 0.1,#學習速率
        'silent': 1,
        'seed': 13,
        'objective': 'binary:logistic',
        'eval_metric': 'auc',
        'scale_pos_weight': 2,
        'subsample': 0.8,#每棵樹,隨機取樣的比例。
        'colsample_bytree': 0.7,#列取樣
        'min_child_weight': 100,
        'max_delta_step': 20
    }

2、train_matrix:訓練的資料
3、num_boost_round :迭代的輪數
4、evals :對evals列表中的元素在訓練過程中進行評估。形式是evals = [(dtrain,’train’),(dval,’val’)],它使得我們可以在訓練過程中觀察驗證集的效果。
5、early_stopping_rounds,早期停止次數 ,假設為100,驗證集的誤差迭代到一定程度在100次內不能再繼續降低,就停止迭代。這要求evals 裡至少有 一個元素,如果有多個,按最後一個去執行。返回的是最後的迭代次數(不是最好的)。如果early_stopping_rounds 存在,則模型會生成三個屬性,bst.best_score,bst.best_iteration,和bst.best_ntree_limit