Python XGBoost演算法代碼實現和篩選特徵應用

2018-02-22 L 數據分析聯盟

XGBoost演算法在機器學習中是一個比較重要的演算法模塊,過去我們經常處理連續特徵用GBDT,而現在更多的是用XGBoost,特別是在數據預處理和特徵工程上,XGBoost有很多明顯的優勢。

一、演算法原理

之前一直有聽說GBM,GBDT(Gradient Boost Decision Tree)漸進梯度決策樹GBRT(Gradient Boost RegressionTree)漸進梯度回歸樹是GBDT的一種,因為GBDT核心是累加所有樹的結果作為最終結果,而分類樹的結果是沒法累加的,所以GBDT中的樹都是回歸樹,不是分類樹。

XGBoost(eXtreme Gradient Boosting)是工業界逐漸風靡的基於GradientBoosting演算法的一個優化的版本,可以給預測模型帶來能力的提升。

回歸樹的分裂結點對於平方損失函數,擬合的就是殘差;對於一般損失函數(梯度下降),擬合的就是殘差的近似值,分裂結點劃分時枚舉所有特徵的值,選取劃分點。 最後預測的結果是每棵樹的預測結果相加。

XGBoost演算法的步驟和GB基本相同,都是首先初始化為一個常數,gb是根據一階導數ri,xgboost是根據一階導數gi和二階導數hi,迭代生成基學習器,相加更新學習器。

二、相比較GBDT優勢

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選擇合適的塊大小

三、Python代碼(參數說明)

from sklearn.model_selection import train_test_splitfrom sklearn import metricsfrom sklearn.datasets import make_hastie_10_2from xgboost.sklearn import XGBClassifierX, y = make_hastie_10_2(random_state=0)X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.5, random_state=0)##test_size測試集合所佔比例 clf = XGBClassifier(silent=0 ,#設置成1則沒有運行信息輸出,最好是設置為0.是否在運行升級時列印消息。#nthread=4,# cpu 線程數 默認最大learning_rate= 0.3, # 如同學習率min_child_weight=1, # 這個參數默認是 1,是每個葉子裡面 h 的和至少是多少,對正負樣本不均衡時的 0-1 分類而言#,假設 h 在 0.01 附近,min_child_weight 為 1 意味著葉子節點中最少需要包含 100 個樣本。#這個參數非常影響結果,控制葉子節點中二階導的和的最小值,該參數值越小,越容易 overfitting。max_depth=6, # 構建樹的深度,越大越容易過擬合gamma=0, # 樹的葉子節點上作進一步分區所需的最小損失減少,越大越保守,一般0.1、0.2這樣子。subsample=1, # 隨機採樣訓練樣本 訓練實例的子採樣比max_delta_step=0,#最大增量步長,我們允許每個樹的權重估計。colsample_bytree=1, # 生成樹時進行的列採樣 reg_lambda=1, # 控制模型複雜度的權重值的L2正則化項參數,參數越大,模型越不容易過擬合。#reg_alpha=0, # L1 正則項參數#scale_pos_weight=1, #如果取值大於0的話,在類別樣本不平衡的情況下有助於快速收斂。平衡正負權重#objective= multi:softmax, #多分類的問題 指定學習任務和相應的學習目標#num_class=10, # 類別數,多分類與 multisoftmax 並用n_estimators=100, #樹的個數seed=1000 #隨機種子#eval_metric= auc )clf.fit(X_train,y_train,eval_metric=auc)y_true, y_pred = y_test, clf.predict(X_test)print"Accuracy : %.4g" % metrics.accuracy_score(y_true, y_pred)

四、特徵篩選

XGBoost篩選特徵其實很簡單,主要就是通過zip將模型的importance和feature合併就可以了。

weixin.qq.com/r/V3XUzBb (二維碼自動識別)

新書(Pdf/Kindle版)[複製下面文字,打開手機淘寶]:

【數據分析俠 《人人都會數據分析》20萬字書籍】m.tb.cn/h.AJEkoq 點擊鏈接,再選擇瀏覽器打開;或複製這條信息¥fSnh09F0Vpy¥後打開??手淘??

weixin.qq.com/g/AXKUWuy (二維碼自動識別)

推薦閱讀:

集智:負基礎也能學會的機器學習(三)
深度森林(deep forest)
微分方程和矩陣指數【MIT線代第二十三課】
BOW 演算法,被CNN 打爆之前的王者
Learning Explanatory Rules from Noisy Data 閱讀筆記0

TAG:演算法 | Python | 機器學習 |