xgboost入門與實戰(原理篇)

https://blog.csdn.net/sb19931201/article/details/52557382

xgboost入門與實戰(原理篇)

前言:

xgboost是大規模並行boosted tree的工具,它是目前最快最好的開源boosted tree工具包,比常見的工具包快10倍以上。在數據科學方面,有大量kaggle選手選用它進行數據挖掘比賽,其中包括兩個以上kaggle比賽的奪冠方案。在工業界規模方面,xgboost的分佈式版本有廣泛的可移植性,支持在YARN, MPI, Sungrid Engine等各個平臺上面運行,並且保留了單機並行版本的各種優化,使得它可以很好地解決於工業界規模的問題。

花了幾天時間粗略地看完了xgboost原論文和作者的slide講解,僅僅是入門入門入門筆記。給我的感覺就是xgboost算法比較複雜,針對傳統GBDT算法做了很多細節改進,包括損失函數、正則化、切分點查找算法優化、稀疏感知算法、並行化算法設計等等。本文主要介紹xgboost基本原理以及與傳統gbdt算法對比總結,後續會基於python版本做了一些實戰調參試驗。想詳細學習xgboost算法原理建議通讀作者原始論文與slide講解。

相關文獻資料:
Xgboost Slides
XGBoost中文版原理介紹
原始論文XGBoost: A Scalable Tree Boosting System
XGBoost Parameters (official guide)

精彩博文:
XGBoost淺入淺出——wepon
xgboost: 速度快效果好的boosting模型
Complete Guide to Parameter Tuning in XGBoost (with codes in Python)

XGBoost Plotting API以及GBDT組合特徵實踐

補充!LightGBM!:

微軟出了個LightGBM,號稱性能更強勁,速度更快。簡單實踐了一波,發現收斂速度要快一些,不過調參還不6 ,沒有權威。看了GitHub上的介紹以及知乎上的一些回答,大致理解了性能提升的原因。
主要是兩個:①histogram算法替換了傳統的Pre-Sorted,某種意義上是犧牲了精度(但是作者聲明實驗發現精度影響不大)換取速度,直方圖作差構建葉子直方圖挺有創造力的。(xgboost的分佈式實現也是基於直方圖的,利於並行)②帶有深度限制的按葉子生長 (leaf-wise) 算法代替了傳統的(level-wise) 決策樹生長策略,提升精度,同時避免過擬合危險。

細節大家直接看作者的解釋以及GitHub上的介紹吧,還是挺好理解的~
鏈接:
https://www.zhihu.com/question/51644470/answer/130946285
https://github.com/Microsoft/LightGBM/wiki/Features

一、xgboost基本原理介紹


1.提升方法是一種非常有效的機器學習方法,在前幾篇筆記中介紹了提升樹與GBDT基本原理,xgboost(eXtreme Gradient Boosting)可以說是提升方法的完全加強版本。xgboost算法在各大比賽中展現了強大的威力。

2.Regression Tree and Ensemble (What are we Learning,得到學習目標)
(1).Regression Tree (CART)迴歸樹

(2).Regression Tree Ensemble 迴歸樹集成

在上面的例子中,我們用兩棵樹來進行預測。我們對於每個樣本的預測結果就是每棵樹預測分數的和。

(3).Objective for Tree Ensemble 得到學習目標函數

這裏是構造一個目標函數,然後我們要做的就是去嘗試優化這個目標函數。讀到這裏,感覺與gbdt好像沒有什麼區別,確實如此,不過在後面就能看到他們的不同了(構造(學習)模型參數)。

3.Gradient Boosting (How do we Learn,如何學習)
(1).So How do we Learn?
目標函數:

We can not use methods such as SGD, to find f (since they are
trees, instead of just numerical vectors)
Solution: Additive Training (Boosting)
Start from constant prediction, add a new function each time

這裏理解很關鍵,這裏目標函數優化的是整體的模型,yi’是整個累加模型的輸出,正則化項是所有樹的複雜度之和,這個複雜度組成後面(6)會講。這種包含樹的模型不適合直接用SGD等優化算法直接對整體模型進行優化,因而採用加法學習方法,boosting的學習策略是每次學習當前的樹,找到當前最佳的樹模型加入到整體模型中,因此關鍵在於學習第t棵樹。
(2).Additive Training :定義目標函數,優化,尋找最佳的ft。

• How do we decide which f to add?
 Optimize the objective!! 目標優化

如圖所示,第t輪的模型預測等於前t-1輪的模型預測y(t-1)加上ft,因此誤差函數項記爲l(yi,y(t-1)+ft),後面一項爲正則化項。
在當前步,yi以及y(t-1)都是已知值,模型學習的是ft。
(3).Taylor Expansion Approximation of Loss 對誤差函數進行二階泰勒近似展開

把平方損失函數的一二次項帶入原目標函數,你會發現與之前那張ppt的損失函數是一致的 。
至於爲什麼要這樣展開呢,這裏就是xgboost的特點了,通過這種近似,你可以自定義一些損失函數(只要保證二階可導),樹分裂的打分函數是基於gi,hi(Gj,Hj)計算的。

(4).Our New Goal 得到了新的目標函數

從這裏就可以看出xgboost的不同了,目標函數保留了泰勒展開的二次項。

這裏寫圖片描述

(5).Refine the definition of tree 重新定義每棵樹

• We define tree by a vector of scores in leafs, and a leaf index
用葉子節點集合以及葉子節點得分表示
mapping function that maps an instance to a leaf
每個樣本都落在一個葉子節點上
q(x)表示樣本x在某個葉子節點上,wq(x)是該節點的打分,即該樣本的模型預測值。

(6).Define the Complexity of Tree 樹的複雜度項

• Define complexity as (this is not the only possible definition)

從圖中可以看出,xgboost算法中對樹的複雜度項包含了兩個部分,一個是葉子節點總數,一個是葉子節點得分L2正則化項,針對每個葉結點的得分增加L2平滑,目的也是爲了避免過擬合。

(7).Revisit the Objectives 更新

注意,這裏優化目標的n->T,T是葉子數。???
論文中定義了:Define I j = {i|q(x i ) = j} as the instance set of leaf j.這一步是由於xgb加了兩個正則項,一個是葉子節點個數(T),一個是葉節點分數(w). 原文中的等式4,加了正則項的目標函數裏就出現了兩種累加,一種是i->n(樣本數),一種是j->T(葉子節點數)。這步轉換是爲了統一目標函數中的累加項,Ij是每個葉節點j上的樣本集合。

(8).The Structure Score 這個score是用來評價樹結構的。根據目標函數得到(見論文公式(4)、(5)、(6)),用於切分點查找算法。
這裏寫圖片描述

這裏寫圖片描述
The Structure Score Calculation:

(9)切分點查找算法


如上圖可見Gain還加了一個葉子節點複雜度項,有點類似CART的剪枝。

這裏寫圖片描述
上圖中G都是各自區域內的gi總和,根據Gain(max)選擇最優分割點。此外,作者針對算法設計對特徵進行了排序,分位點劃分等,有興趣的可以閱讀原始論文,這裏不做詳解。

算法步驟:
這裏寫圖片描述

根據特徵劃分有無數可能的樹結構,因此採用近似算法(特徵分位點,候選分割點)
這裏寫圖片描述
(10)小結一下: Boosted Tree Algorithm

二、xgboost特點(與gbdt對比)


說明一下:這部分內容參考了知乎上的一個問答—機器學習算法中GBDT和XGBOOST的區別有哪些?,答主是wepon大神,根據他的總結我自己做了一理解和補充。

1.傳統GBDT以CART作爲基分類器,xgboost還支持線性分類器,這個時候xgboost相當於帶L1和L2正則化項的邏輯斯蒂迴歸(分類問題)或者線性迴歸(迴歸問題)。 —可以通過booster [default=gbtree]設置參數:gbtree: tree-based models/gblinear: linear models

2.傳統GBDT在優化時只用到一階導數信息,xgboost則對代價函數進行了二階泰勒展開,同時用到了一階和二階導數。順便提一下,xgboost工具支持自定義代價函數,只要函數可一階和二階求導。 —對損失函數做了改進(泰勒展開,一階信息g和二階信息h,上一章節有做介紹)

3.xgboost在代價函數里加入了正則項,用於控制模型的複雜度。正則項裏包含了樹的葉子節點個數、每個葉子節點上輸出的score的L2模的平方和。從Bias-variance tradeoff角度來講,正則項降低了模型variance,使學習出來的模型更加簡單,防止過擬合,這也是xgboost優於傳統GBDT的一個特性
—正則化包括了兩個部分,都是爲了防止過擬合,剪枝是都有的,葉子結點輸出L2平滑是新增的。

4.shrinkage and column subsampling —還是爲了防止過擬合,論文2.3節有介紹,這裏答主已概括的非常到位

(1)shrinkage縮減類似於學習速率,在每一步tree boosting之後增加了一個參數n(權重),通過這種方式來減小每棵樹的影響力,給後面的樹提供空間去優化模型。

(2)column subsampling列(特徵)抽樣,說是從隨機森林那邊學習來的,防止過擬合的效果比傳統的行抽樣還好(行抽樣功能也有),並且有利於後面提到的並行化處理算法。

5.split finding algorithms(劃分點查找算法):—理解的還不夠透徹,需要進一步學習
(1)exact greedy algorithm—貪心算法獲取最優切分點
(2)approximate algorithm— 近似算法,提出了候選分割點概念,先通過直方圖算法獲得候選分割點的分佈情況,然後根據候選分割點將連續的特徵信息映射到不同的buckets中,並統計彙總信息。詳細見論文3.3節
(3)Weighted Quantile Sketch—分佈式加權直方圖算法,論文3.4節
這裏的算法(2)、(3)是爲了解決數據無法一次載入內存或者在分佈式情況下算法(1)效率低的問題,以下引用的還是wepon大神的總結:

可並行的近似直方圖算法。樹節點在進行分裂時,我們需要計算每個特徵的每個分割點對應的增益,即用貪心法枚舉所有可能的分割點。當數據無法一次載入內存或者在分佈式情況下,貪心算法效率就會變得很低,所以xgboost還提出了一種可並行的近似直方圖算法,用於高效地生成候選的分割點。

6.對缺失值的處理。對於特徵的值有缺失的樣本,xgboost可以自動學習出它的分裂方向。 —稀疏感知算法,論文3.4節,Algorithm 3: Sparsity-aware Split Finding

7.Built-in Cross-Validation(內置交叉驗證)

XGBoost allows user to run a cross-validation at each iteration of the boosting process and thus it is easy to get the exact optimum number of boosting iterations in a single run.
This is unlike GBM where we have to run a grid-search and only a limited values can be tested.

8.continue on Existing Model(接着已有模型學習)

User can start training an XGBoost model from its last iteration of previous run. This can be of significant advantage in certain specific applications.
GBM implementation of sklearn also has this feature so they are even on this point.

9.High Flexibility(高靈活性)

**XGBoost allow users to define custom optimization objectives and evaluation criteria.
This adds a whole new dimension to the model and there is no limit to what we can do.**

10.並行化處理 —系統設計模塊,塊結構設計等

xgboost工具支持並行。boosting不是一種串行的結構嗎?怎麼並行的?注意xgboost的並行不是tree粒度的並行,xgboost也是一次迭代完才能進行下一次迭代的(第t次迭代的代價函數裏包含了前面t-1次迭代的預測值)。xgboost的並行是在特徵粒度上的。我們知道,決策樹的學習最耗時的一個步驟就是對特徵的值進行排序(因爲要確定最佳分割點),xgboost在訓練之前,預先對數據進行了排序,然後保存爲block結構,後面的迭代中重複地使用這個結構,大大減小計算量。這個block結構也使得並行成爲了可能,在進行節點的分裂時,需要計算每個特徵的增益,最終選增益最大的那個特徵去做分裂,那麼各個特徵的增益計算就可以開多線程進行。

此外xgboost還設計了高速緩存壓縮感知算法,這是系統設計模塊的效率提升。
當梯度統計不適合於處理器高速緩存和高速緩存丟失時,會大大減慢切分點查找算法的速度。
(1)針對 exact greedy algorithm採用緩存感知預取算法
(2)針對 approximate algorithms選擇合適的塊大小

我覺得關於xgboost並行化設計僅僅從論文PPT博客上學習是遠遠不夠的,有時間還要從代碼層面去學習分佈式 xgboost的設計理念。

三、xgboost參數詳解


官方參數介紹看這裏:
Parameters (official guide)

General Parameters(常規參數)
1.booster [default=gbtree]:選擇基分類器,gbtree: tree-based models/gblinear: linear models
2.silent [default=0]:設置成1則沒有運行信息輸出,最好是設置爲0.
3.nthread [default to maximum number of threads available if not set]:線程數

Booster Parameters(模型參數)
1.eta [default=0.3]:shrinkage參數,用於更新葉子節點權重時,乘以該係數,避免步長過大。參數值越大,越可能無法收斂。把學習率 eta 設置的小一些,小學習率可以使得後面的學習更加仔細。
2.min_child_weight [default=1]:這個參數默認是 1,是每個葉子裏面 h 的和至少是多少,對正負樣本不均衡時的 0-1 分類而言,假設 h 在 0.01 附近,min_child_weight 爲 1 意味着葉子節點中最少需要包含 100 個樣本。這個參數非常影響結果,控制葉子節點中二階導的和的最小值,該參數值越小,越容易 overfitting。
3.max_depth [default=6]: 每顆樹的最大深度,樹高越深,越容易過擬合。
4.max_leaf_nodes:最大葉結點數,與max_depth作用有點重合。
5.gamma [default=0]:後剪枝時,用於控制是否後剪枝的參數。
6.max_delta_step [default=0]:這個參數在更新步驟中起作用,如果取0表示沒有約束,如果取正值則使得更新步驟更加保守。可以防止做太大的更新步子,使更新更加平緩。
7.subsample [default=1]:樣本隨機採樣,較低的值使得算法更加保守,防止過擬合,但是太小的值也會造成欠擬合。
8.colsample_bytree [default=1]:列採樣,對每棵樹的生成用的特徵進行列採樣.一般設置爲: 0.5-1
9.lambda [default=1]:控制模型複雜度的權重值的L2正則化項參數,參數越大,模型越不容易過擬合。
10.alpha [default=0]:控制模型複雜程度的權重值的 L1 正則項參數,參數值越大,模型越不容易過擬合。
11.scale_pos_weight [default=1]:如果取值大於0的話,在類別樣本不平衡的情況下有助於快速收斂。

Learning Task Parameters(學習任務參數)
1.objective [default=reg:linear]:定義最小化損失函數類型,常用參數:
binary:logistic –logistic regression for binary classification, returns predicted probability (not class)
multi:softmax –multiclass classification using the softmax objective, returns predicted class (not probabilities)
you also need to set an additional num_class (number of classes) parameter defining the number of unique classes
multi:softprob –same as softmax, but returns predicted probability of each data point belonging to each class.
2.eval_metric [ default according to objective ]
The metric to be used for validation data.
The default values are rmse for regression and error for classification.
Typical values are:
rmse – root mean square error
mae – mean absolute error
logloss – negative log-likelihood
error – Binary classification error rate (0.5 threshold)
merror – Multiclass classification error rate
mlogloss – Multiclass logloss
auc: Area under the curve
3.seed [default=0]
The random number seed. 隨機種子,用於產生可復現的結果
Can be used for generating reproducible results and also for parameter tuning.

注意: python sklearn style參數名會有所變化
eta –> learning_rate
lambda –> reg_lambda
alpha –> reg_alpha

四、實戰


官方樣例:
XGBoost Python API Reference (official guide)
XGBoost Demo Codes (xgboost GitHub repository)

xgboost參數設置代碼示例:

# 劃分數據集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.01, random_state=1729)
print(X_train.shape, X_test.shape)

#模型參數設置
xlf = xgb.XGBRegressor(max_depth=10, 
                        learning_rate=0.1, 
                        n_estimators=10, 
                        silent=True, 
                        objective='reg:linear', 
                        nthread=-1, 
                        gamma=0,
                        min_child_weight=1, 
                        max_delta_step=0, 
                        subsample=0.85, 
                        colsample_bytree=0.7, 
                        colsample_bylevel=1, 
                        reg_alpha=0, 
                        reg_lambda=1, 
                        scale_pos_weight=1, 
                        seed=1440, 
                        missing=None)

xlf.fit(X_train, y_train, eval_metric='rmse', verbose = True, eval_set = [(X_test, y_test)],early_stopping_rounds=100)

# 計算 auc 分數、預測
preds = xlf.predict(X_test)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

實戰待續…

                    <link rel="stylesheet" href="https://csdnimg.cn/release/phoenix/production/markdown_views-68a8aad09e.css">
                        </div>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章