1. 程式人生 > >xgboost入門與實戰(原理篇)

xgboost入門與實戰(原理篇)

enc 之前 fine 小結 附近 step 參考 search line

http://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算法在各大比賽中展現了強大的威力,引用原論文中的一段描述:

The impact of the system has been widely recognized in a number of machine learning and data mining challenges. Take the challenges hosted by the machine learning competition site Kaggle for example. Among the 29 challenge winning solutions published at Kaggle’s blog during 2015, 17 solutions used XGBoost. Among these solutions, eight solely used XGBoost to train the model,while most others combined XGBoost with neural nets in ensembles. For comparison, the second most popular method,deep neural nets, was used in 11 solutions. The success of the system was also witnessed in KDDCup 2015, where XGBoost was used by every winning team in the top-10.Moreover, the winning teams reported that ensemble methods outperform a well-configured XGBoost by only a small amount.

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
技術分享圖片

(2).Additive Training

? How do we decide which f to add?
? Optimize the objective!! 目標優化
技術分享圖片

(3).Taylor Expansion Approximation of Loss 泰勒近似展開

技術分享圖片

把平方損失函數的一二次項帶入原目標函數,你會發現與之前那張ppt的損失函數是一致的

(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

技術分享圖片

(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是葉子數。???
(8).The Structure Score 這個score你可以理解成類似於信息增益的一個指標,在切分點查找算法中用到。
技術分享圖片

(9)切分點查找算法(貪心算法)
技術分享圖片
技術分享圖片
上圖中G都是各自區域內的gi總和,此外,作者針對算法設計對特征進行了排序,有興趣的可以閱讀原始論文,這裏不做詳解。

(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)

xgboost入門與實戰(原理篇)