一文理清集成學習知識點(Boosting&Bagging)
導讀
相信這個環節的內容大家都會比較熟悉的,因爲我們經常用到的XGBoost、GBDT就是集成模型,今天這裏就給大家系統地梳理一下知識點和原理,做到了然於胸。
目錄
-
集成學習的主要類型
-
集成學習的基本步驟
-
談談基分類器
-
GBDT與XGBoost的區別與聯繫
-
算法實踐Demo
集成學習的主要類型
集成學習是一大類模型融合策略和方法的統稱,我們經常用到的兩類是Boosting和Bagging,這兩者的區別與聯繫經常會被問到,在回答這些問題前,需要對兩者的原理進行統一瞭解。
Boosting
Boosting方法在訓練基分類器時採用的是串行的方法,每一個基分類器依賴前面的結果。它的基本思路就是將基分類器層層疊加,每層在訓練時都會對前一層基分類器的分類錯誤情況去改變當前樣本的分佈,具體來說就是將分類錯誤的樣本給予更高的權重,所以每一次的迭代,數據分佈都是不一樣的。
Boosting的迭代過程與人類的學習過程有點類似,也就是說我們在學習新知識的時候,會記住部分信息,也會遺忘部分信息,所以在下一次中會着重去關注沒記住的內容,加強訓練,這樣子不斷地去循環學習,直到我們能夠全部吸收。
Boosting通過逐步聚焦於基分類器分錯的樣本,減少集成分類器的偏差。
Bagging
而對於Bagging,它則是並行訓練的,各個基分類器之間無依賴,而且每個基分類器訓練的樣本都是一樣的(也可以不同),但由於每個基分類器的"學習能力"不同,會出現很多的學習結果,最終的決策會參考這些基分類器的結果,一般是採用投票的方式,基分類器之間的權重都是一樣的。
Bagging採取分而治之的策略,通過對訓練樣本多次採樣,並分別訓練出多個不同模型,然後做綜合,來減少集成分類器的方差。
集成學習的基本步驟
集成學習一般可以分爲以下3個步驟:
1、找到誤差互相獨立的基分類器
2、訓練基分類器
3、合併基分類器的結果
合併基分類器的方法有voting和stacking兩種,前者是用投票的方法,將獲得最多選票的結果作爲最終的結果。後者則是使用串行的方法,把前一個基分類器的結果輸出到下一個基分類器中,將所有基分類器的輸出結果相加融合作爲輸出。
比如,針對Adaboost,大致的步驟如下:
(1) 確定基分類器:一般都是採用樹形模型,因爲它結構簡單且隨機性強。
(2) 訓練基分類器:假設有T個基分類器,則可以按照如下過程來訓練基分類器:
(3) 合併基分類器:給定一個未知樣本z,輸出分誒結果爲加權投票的結果。
從上面的例子中我們可以看出來Boosting一個很重要的思想,那就是它會對分類錯誤的樣本進行權重的加強,對分類正確的樣本降低權重,在最後的模型融合時根據錯誤率對基分類器進行加權融合,錯誤率低的分類器也擁有更大的"話語權"。
還有一種比較流行的Boosting模型,那就是 梯度提升決策樹(GBDT) 。其核心思想就是每一棵樹學的是之前所有樹結論和的殘差,這個殘差是一個加預測值後能得到真實值的累加(減)量。
談談基分類器
基分類器作爲Boosting的基本單元,而且一般也是會採用決策樹來作爲分類器,原因有三:
(1) 決策樹可以較爲方便地將樣本的權重整合到訓練過程中,而不需要使用過採樣的方法來調整樣本權重;
(2) 決策樹的表達能力和泛化能力都是有很大的調節性,比如可以通過數的深度來調整;
(3) 決策樹的隨機性較強,所以不同的訓練集都會比較隨機地生成不同的決策樹模型,這樣子的"不穩定學習器"更能勝任基分類器的職責,很好的解決了數據樣本擾動的影響,同時解決過擬合情況。
Q: 可否將RF中的決策樹基分類器,替換爲K-Mean或者線性分類器呢?
有了上面我們對於基分類器的認識,因爲RF屬於Bagging,它要求的基分類器最好是對樣本分佈較爲敏感,這樣子基分類器之間的方差就會較大,然後綜合起來之後就可以達到一個較優的結果。而如果換成K-Mean或者線性分類器,這些分類器本身會非常穩定,這樣子的話其實基分類器訓練出來的模型都是十分相似,方差很小,即便Bagging之後不能獲得更好的表現,失去了Bagging的優勢。
GBDT與XGBoost的區別與聯繫
GBDT
Gradient Boosting Decision Tree,簡稱GBDT,中文名爲梯度提升決策樹,作爲"網紅"算法,時常出現在各大競賽平臺和商業應用,它的核心思想就是從錯誤中學習,基於決策樹預測的殘差進行迭代優化學習,具體做法就是根據當前模型損失函數的負梯度信息來訓練新加入的弱分類器,然後將訓練好的弱分類器以累加的形式結合到現有模型中。
XGBoost
作爲一個比GBDT更加"網紅"的機器學習算法,XGBoost可謂是鼎鼎大名,它高效地實現了GBDT算法並進行算法和工程層面上的優化改進,它直接並行訓練模型(這裏的並行指的是節點分裂上的並行,模型的訓練還是串行的,畢竟還是屬於Boosting),然後對過擬合做了一些優化措施,也優化了Cost Function。
區別與聯繫
這裏就羅列一些內容:
(1) 在使用CART作爲基分類器的時候,XGBoost顯式地加入了正則項來控制模型的複雜度,有利於改善模型的過擬合情況,從而提高模型的泛化能力;
(2) GBDT在訓練模型的時候只是使用Cost Function的一階導數部分信息,而XGBoost則是進行二階泰勒展開,用到了二階導數;
(3) 傳統的GBDT只是採用CART作爲基分類器,而XGBoost支持多種基分類器,比如線性分類器;
(4) GBDT每次訓練模型的樣本都是一樣的,但是XGBoost則支持對數據進行採用,數據分佈有可能會發生改變;
(5) GBDT沒有對缺失值進行處理,XGBoost對這塊有針對性的解決措施。
算法實踐Demo
先前的一篇文章中,有讀者在諮詢有沒有調用這些算法的例子,這邊的話就根據算法的官方文檔,整理出一份demo,希望也可以幫助到正在初學的朋友。
XGBoost
我們在Python裏用XGBoost,主要就是通過調用Scikit_learn的包,裏面有一個類叫 xgboost。當我們對樣本進行處理後,得到一個很規範的DataFrame格式的數據集,這個時候就可以調用這個算法類來進行模型構建,具體參數如下:
Scikit-Learn Wrapper interface for XGBoost.
-
class xgboost.XGBRegressor(max_depth=3, learning_rate=0.1, n_estimators=100, verbosity=1, objective='reg:squarederror', booster='gbtree', tree_method='auto', n_jobs=1, gamma=0, min_child_weight=1, max_delta_step=0, subsample=1, colsample_bytree=1, colsample_bylevel=1, colsample_bynode=1, reg_alpha=0, reg_lambda=1, scale_pos_weight=1, base_score=0.5, random_state=0, missing=None, num_parallel_tree=1, importance_type='gain', **kwargs)
下面是一個具體的實例,大家可以結合代碼裏的註釋來理解這段代碼:
# 導入相關庫
import xgboost as xgb
from xgboost.sklearn import XGBClassifier
# 初始化xgb
xgb = XGBClassifier(learning_rate =0.1,eta=0.5, max_depth=3,min_child_weight=2,gamma=0.2, subsample=0.7, colsample_bytree=0.9,
objective= 'binary:logistic', scale_pos_weight=10, seed=10)
# 用樣本數據訓練模型
xgb.fit(X_train, y_train)
# 對訓練好的模型進行預測應用,分別對訓練集和測試集進行計算
train_y_pred = xgb.predict(X_train)
train_y_predprob = xgb.predict_proba(X_train)[:,1]
test_y_pred = xgb.predict(X_test)
test_y_predprob = xgb.predict_proba(X_test)[:,1]
# 計算KS值,並打印出來,看模型效果(這裏除了KS值,還有很多其他的指標,具體根據實際情況選擇)
get_ks = lambda y_pred,y_true: ks_2samp(y_pred[y_true==1], y_pred[y_true!=1]).statistic
print('訓練KS值: %s' %get_ks(train_y_predprob,y_train))
print('驗證KS值: %s' %get_ks(test_y_predprob,y_test))
References
[1] 百面機器學習 Chapter12 (文中未標識來源的圖片均來自本書內容)
[2] XGBoost Documentation
https://xgboost.readthedocs.io/en/latest/
封面圖來源:Photo by Matthew Guay on Unsplash