1. 程式人生 > >(轉)XGBoost引數調優完全指南

(轉)XGBoost引數調優完全指南

原文(英文)地址:https://www.analyticsvidhya.com/blog/2016/03/complete-guide-parameter-tuning-xgboost-with-codes-python/
原文(翻譯)地址:https://www.2cto.com/kf/201607/528771.html

簡介
如果你的預測模型表現得有些不盡如人意,那就用XGBoost吧。XGBoost演算法現在已經成為很多資料工程師的重要武器。它是一種十分精緻的演算法,可以處理各種不規則的資料。
構造一個使用XGBoost的模型十分簡單。但是,提高這個模型的表現就有些困難(至少我覺得十分糾結)。這個演算法使用了好幾個引數。所以為了提高模型的表現,引數的調整十分必要。在解決實際問題的時候,有些問題是很難回答的——你需要調整哪些引數?這些引數要調到什麼值,才能達到理想的輸出?
這篇文章最適合剛剛接觸XGBoost的人閱讀。在這篇文章中,我們會學到引數調優的技巧,以及XGboost相關的一些有用的知識。以及,我們會用Python在一個數據集上實踐一下這個演算法。

內容列表
1、XGBoost的優勢
2、理解XGBoost的引數

1、XGBoost的優勢
XGBoost演算法可以給預測模型帶來能力的提升。當我對它的表現有更多瞭解的時候,當我對它的高準確率背後的原理有更多瞭解的時候,我發現它具有很多優勢:

1、正則化
標準GBM的實現沒有像XGBoost這樣的正則化步驟。正則化對減少過擬合也是有幫助的。 實際上,XGBoost以“正則化提升(regularized boosting)”技術而聞名。
2、並行處理
XGBoost可以實現並行處理,相比GBM有了速度的飛躍。 不過,眾所周知,Boosting演算法是順序處理的,它怎麼可能並行呢?每一課樹的構造都依賴於前一棵樹,那具體是什麼讓我們能用多核處理器去構造一個樹呢?我希望你理解了這句話的意思。 XGBoost 也支援Hadoop實現。
3、高度的靈活性
XGBoost 允許使用者定義自定義優化目標和評價標準 它對模型增加了一個全新的維度,所以我們的處理不會受到任何限制。
4、缺失值處理
XGBoost內建處理缺失值的規則。 使用者需要提供一個和其它樣本不同的值,然後把它作為一個引數傳進去,以此來作為缺失值的取值。XGBoost在不同節點遇到缺失值時採用不同的處理方法,並且會學習未來遇到缺失值時的處理方法。
5、剪枝
當分裂時遇到一個負損失時,GBM會停止分裂。因此GBM實際上是一個貪心演算法。 XGBoost會一直分裂到指定的最大深度(max_depth),然後回過頭來剪枝。如果某個節點之後不再有正值,它會去除這個分裂。 這種做法的優點,當一個負損失(如-2)後面有個正損失(如+10)的時候,就顯現出來了。GBM會在-2處停下來,因為它遇到了一個負值。但是XGBoost會繼續分裂,然後發現這兩個分裂綜合起來會得到+8,因此會保留這兩個分裂。
6、內建交叉驗證
XGBoost允許在每一輪boosting迭代中使用交叉驗證。因此,可以方便地獲得最優boosting迭代次數。 而GBM使用網格搜尋,只能檢測有限個值。
7、在已有的模型基礎上繼續
XGBoost可以在上一輪的結果上繼續訓練。這個特性在某些特定的應用上是一個巨大的優勢。 sklearn中的GBM的實現也有這個功能,兩種演算法在這一點上是一致的。
相信你已經對XGBoost強大的功能有了點概念。注意這是我自己總結出來的幾點,你如果有更多的想法,儘管在下面評論指出,我會更新這個列表的!

2、XGBoost的引數
XGBoost的作者把所有的引數分成了三類:
1、通用引數:巨集觀函式控制。
2、Booster引數:控制每一步的booster(tree/regression)。
3、學習目標引數:控制訓練目標的表現。
在這裡我會類比GBM來講解,所以作為一種基礎知識。

通用引數
這些引數用來控制XGBoost的巨集觀功能。

1、booster[預設gbtree]
選擇每次迭代的模型,有兩種選擇:
gbtree:基於樹的模型
gbliner:線性模型
2、silent[預設0]
當這個引數值為1時,靜默模式開啟,不會輸出任何資訊。 一般這個引數就保持預設的0,因為這樣能幫我們更好地理解模型。
3、nthread[預設值為最大可能的執行緒數]
這個引數用來進行多執行緒控制,應當輸入系統的核數。 如果你希望使用CPU全部的核,那就不要輸入這個引數,演算法會自動檢測它。
還有兩個引數,XGBoost會自動設定,目前你不用管它。接下來咱們一起看booster引數。

booster引數
儘管有兩種booster可供選擇,我這裡只介紹tree booster,因為它的表現遠遠勝過linear booster,所以linear booster很少用到。

1、eta[預設0.3]
和GBM中的 learning rate 引數類似。 通過減少每一步的權重,可以提高模型的魯棒性。 典型值為0.01-0.2。
2、min_child_weight[預設1]
決定最小葉子節點樣本權重和。 和GBM的 min_child_leaf 引數類似,但不完全一樣。XGBoost的這個引數是最小樣本權重的和,而GBM引數是最小樣本總數。 這個引數用於避免過擬合。當它的值較大時,可以避免模型學習到區域性的特殊樣本。 但是如果這個值過高,會導致欠擬合。這個引數需要使用CV來調整。
3、max_depth[預設6]
和GBM中的引數相同,這個值為樹的最大深度。 這個值也是用來避免過擬合的。max_depth越大,模型會學到更具體更區域性的樣本。 需要使用CV函式來進行調優。 典型值:3-10
4、max_leaf_nodes
樹上最大的節點或葉子的數量。 可以替代max_depth的作用。因為如果生成的是二叉樹,一個深度為n的樹最多生成n2個葉子。 如果定義了這個引數,GBM會忽略max_depth引數。
5、gamma[預設0]
在節點分裂時,只有分裂後損失函式的值下降了,才會分裂這個節點。Gamma指定了節點分裂所需的最小損失函式下降值。 這個引數的值越大,演算法越保守。這個引數的值和損失函式息息相關,所以是需要調整的。
6、max_delta_step[預設0]
這引數限制每棵樹權重改變的最大步長。如果這個引數的值為0,那就意味著沒有約束。如果它被賦予了某個正值,那麼它會讓這個演算法更加保守。 通常,這個引數不需要設定。但是當各類別的樣本十分不平衡時,它對邏輯迴歸是很有幫助的。 這個引數一般用不到,但是你可以挖掘出來它更多的用處。
7、subsample[預設1]
和GBM中的subsample引數一模一樣。這個引數控制對於每棵樹,隨機取樣的比例。 減小這個引數的值,演算法會更加保守,避免過擬合。但是,如果這個值設定得過小,它可能會導致欠擬合。 典型值:0.5-1
8、colsample_bytree[預設1]
和GBM裡面的max_features引數類似。用來控制每棵隨機取樣的列數的佔比(每一列是一個特徵)。 典型值:0.5-1
9、colsample_bylevel[預設1]
用來控制樹的每一級的每一次分裂,對列數的取樣的佔比。 我個人一般不太用這個引數,因為subsample引數和colsample_bytree引數可以起到相同的作用。但是如果感興趣,可以挖掘這個引數更多的用處。
10、lambda[預設1]
權重的L2正則化項。(和Ridge regression類似)。 這個引數是用來控制XGBoost的正則化部分的。雖然大部分資料科學家很少用到這個引數,但是這個引數在減少過擬合上還是可以挖掘出更多用處的。
11、alpha[預設1]
權重的L1正則化項。(和Lasso regression類似)。 可以應用在很高維度的情況下,使得演算法的速度更快。
12、scale_pos_weight[預設1]
在各類別樣本十分不平衡時,把這個引數設定為一個正值,可以使演算法更快收斂。

學習目標引數
這個引數用來控制理想的優化目標和每一步結果的度量方法。

1、objective[預設reg:linear]
這個引數定義需要被最小化的損失函式。最常用的值有:
binary:logistic 二分類的邏輯迴歸,返回預測的概率(不是類別)。 multi:softmax 使用softmax的多分類器,返回預測的類別(不是概率)。
在這種情況下,你還需要多設一個引數:num_class(類別數目)。 multi:softprob 和multi:softmax引數一樣,但是返回的是每個資料屬於各個類別的概率。
2、eval_metric[預設值取決於objective引數的取值]
對於有效資料的度量方法。 對於迴歸問題,預設值是rmse,對於分類問題,預設值是error。 典型值有:
rmse 均方根誤差(∑Ni=1?2N???√) mae 平均絕對誤差(∑Ni=1|?|N) logloss 負對數似然函式值 error 二分類錯誤率(閾值為0.5) merror 多分類錯誤率 mlogloss 多分類logloss損失函式 auc 曲線下面積
3、seed(預設0)
隨機數的種子 設定它可以復現隨機資料的結果,也可以用於調整引數
如果你之前用的是Scikit-learn,你可能不太熟悉這些引數。但是有個好訊息,python的XGBoost模組有一個sklearn包,XGBClassifier。這個包中的引數是按sklearn風格命名的。會改變的函式名是:
1、eta ->learning_rate
2、lambda->reg_lambda
3、alpha->reg_alpha
你肯定在疑惑為啥咱們沒有介紹和GBM中的’n_estimators’類似的引數。XGBClassifier中確實有一個類似的引數,但是,是在標準XGBoost實現中呼叫擬合函式時,把它作為’num_boosting_rounds’引數傳入。

引數調優的一般方法。
我們會使用和GBM中相似的方法。需要進行如下步驟:

  1. 選擇較高的學習速率(learning rate)。一般情況下,學習速率的值為0.1。但是,對於不同的問題,理想的學習速率有時候會在0.05到0.3之間波動。選擇對應於此學習速率的理想決策樹數量。XGBoost有一個很有用的函式“cv”,這個函式可以在每一次迭代中使用交叉驗證,並返回理想的決策樹數量。
  2. 對於給定的學習速率和決策樹數量,進行決策樹特定引數調優(max_depth, min_child_weight, gamma, subsample, colsample_bytree)。在確定一棵樹的過程中,我們可以選擇不同的引數,待會兒我會舉例說明。
  3. xgboost的正則化引數的調優。(lambda, alpha)。這些引數可以降低模型的複雜度,從而提高模型的表現。
  4. 降低學習速率,確定理想引數。