天天看點

XGBoost參數調優摘要:第四步:調整subsample 和 colsample_bytree 參數

摘要:

轉載:http://blog.csdn.NET/han_xiaoyang/article/details/52665396

1. 簡介

如果你的預測模型表現得有些不盡如人意,那就用XGBoost吧。XGBoost算法現在已經成為很多資料工程師的重要武器。它是一種十分精緻的算法,可以處理各種不規則的資料。 

構造一個使用XGBoost的模型十分簡單。但是,提高這個模型的表現就有些困難(至少我覺得十分糾結)。這個算法使用了好幾個參數。是以為了提高模型的表現,參數的調整十分必要。在解決實際問題的時候,有些問題是很難回答的——你需要調整哪些參數?這些參數要調到什麼值,才能達到理想的輸出? 

這篇文章最适合剛剛接觸XGBoost的人閱讀。在這篇文章中,我們會學到參數調優的技巧,以及XGboost相關的一些有用的知識。以及,我們會用Python在一個資料集上實踐一下這個算法。

2. 你需要知道的

XGBoost(eXtreme Gradient Boosting)是Gradient Boosting算法的一個優化的版本。因為我在前一篇文章,基于Python的Gradient Boosting算法參數調整完全指南,裡面已經涵蓋了Gradient Boosting算法的很多細節了。我強烈建議大家在讀本篇文章之前,把那篇文章好好讀一遍。它會幫助你對Boosting算法有一個宏觀的了解,同時也會對GBM的參數調整有更好的體會。

特别鳴謝:我個人十分感謝Mr Sudalai Rajkumar (aka SRK)大神的支援,目前他在AV Rank中位列第二。如果沒有他的幫助,就沒有這篇文章。在他的幫助下,我們才能給無數的資料科學家指點迷津。給他一個大大的贊!

3. 内容清單

1、XGBoost的優勢 

2、了解XGBoost的參數 

3、調參示例

4. XGBoost的優勢

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

4.1 正則化

  • 标準GBM的實作沒有像XGBoost這樣的正則化步驟。正則化對減少過拟合也是有幫助的。
  • 實際上,XGBoost以“正則化提升(regularized boosting)”技術而聞名。

4.2 并行處理

  • XGBoost可以實作并行處理,相比GBM有了速度的飛躍。
  • 不過,衆所周知,Boosting算法是順序處理的,它怎麼可能并行呢?每一課樹的構造都依賴于前一棵樹,那具體是什麼讓我們能用多核處理器去構造一個樹呢?我希望你了解了這句話的意思。如果你希望了解更多,點選這個連結。
  • XGBoost 也支援Hadoop實作。

4.3 高度的靈活性

  • XGBoost 允許使用者定義自定義優化目标和評價标準
  • 它對模型增加了一個全新的次元,是以我們的處理不會受到任何限制。

4.4 缺失值處理

  • XGBoost内置處理缺失值的規則。
  • 使用者需要提供一個和其它樣本不同的值,然後把它作為一個參數傳進去,以此來作為缺失值的取值。XGBoost在不同節點遇到缺失值時采用不同的處理方法,并且會學習未來遇到缺失值時的處理方法。

4.5 剪枝

  • 當分裂時遇到一個負損失時,GBM會停止分裂。是以GBM實際上是一個貪心算法。
  • XGBoost會一直分裂到指定的最大深度(max_depth),然後回過頭來剪枝。如果某個節點之後不再有正值,它會去除這個分裂。
  • 這種做法的優點,當一個負損失(如-2)後面有個正損失(如+10)的時候,就顯現出來了。GBM會在-2處停下來,因為它遇到了一個負值。但是XGBoost會繼續分裂,然後發現這兩個分裂綜合起來會得到+8,是以會保留這兩個分裂。

4.6 内置交叉驗證

  • XGBoost允許在每一輪boosting疊代中使用交叉驗證。是以,可以友善地獲得最優boosting疊代次數。
  • 而GBM使用網格搜尋,隻能檢測有限個值。

4.7、在已有的模型基礎上繼續

  • XGBoost可以在上一輪的結果上繼續訓練。這個特性在某些特定的應用上是一個巨大的優勢。
  • sklearn中的GBM的實作也有這個功能,兩種算法在這一點上是一緻的。

相信你已經對XGBoost強大的功能有了點概念。注意這是我自己總結出來的幾點,你如果有更多的想法,盡管在下面評論指出,我會更新這個清單的!

你的胃口被我吊起來了嗎?棒棒哒!如果你想更深入了解相關資訊,可以參考下面這些文章: 

XGBoost Guide - Introduce to Boosted Trees 

Words from the Auther of XGBoost [Viedo]

5. XGBoost的參數

XGBoost的作者把所有的參數分成了三類:

  1. 通用參數:宏觀函數控制。
  2. Booster參數:控制每一步的booster(tree/regression)。
  3. 學習目标參數:控制訓練目标的表現。

在這裡我會類比GBM來講解,是以作為一種基礎知識,強烈推薦先閱讀這篇文章。

5.1 通用參數

這些參數用來控制XGBoost的宏觀功能。

1、booster[預設gbtree]

  • 選擇每次疊代的模型,有兩種選擇: 

    gbtree:基于樹的模型 

    gbliner:線性模型

2、silent[預設0]

  • 當這個參數值為1時,靜默模式開啟,不會輸出任何資訊。
  • 一般這個參數就保持預設的0,因為這樣能幫我們更好地了解模型。

3、nthread[預設值為最大可能的線程數]

  • 這個參數用來進行多線程控制,應當輸入系統的核數。
  • 如果你希望使用CPU全部的核,那就不要輸入這個參數,算法會自動檢測它。

還有兩個參數,XGBoost會自動設定,目前你不用管它。接下來咱們一起看booster參數。

5.2 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]

  • 在各類别樣本十分不平衡時,把這個參數設定為一個正值,可以使算法更快收斂。

5.3學習目标參數

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

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

參數傳入。 

XGBoost Guide 的一些部分是我強烈推薦大家閱讀的,通過它可以對代碼和參數有一個更好的了解:

XGBoost Parameters (official guide) 

XGBoost Demo Codes (xgboost GitHub repository) 

Python API Reference (official guide)

調參示例

我們從Data Hackathon 3.x AV版的hackathon中獲得資料集,和GBM 介紹文章中是一樣的。更多的細節可以參考competition page 

資料集可以從這裡下載下傳。我已經對這些資料進行了一些處理:

  • City

    變量,因為類别太多,是以删掉了一些類别。
  • DOB

    變量換算成年齡,并删除了一些資料。
  • 增加了 

    EMI_Loan_Submitted_Missing

     變量。如果

    EMI_Loan_Submitted

    變量的資料缺失,則這個參數的值為1。否則為0。删除了原先的

    EMI_Loan_Submitted

    變量。
  • EmployerName

    變量,因為類别太多,是以删掉了一些類别。
  • 因為

    Existing_EMI

    變量隻有111個值缺失,是以缺失值補充為中位數0。
  • 增加了 

    Interest_Rate_Missing

     變量。如果

    Interest_Rate

    變量的資料缺失,則這個參數的值為1。否則為0。删除了原先的

    Interest_Rate

    變量。
  • 删除了

    Lead_Creation_Date

    ,從直覺上這個特征就對最終結果沒什麼幫助。
  • Loan_Amount_Applied, Loan_Tenure_Applied

     兩個變量的缺項用中位數補足。
  • 增加了 

    Loan_Amount_Submitted_Missing

     變量。如果

    Loan_Amount_Submitted

    變量的資料缺失,則這個參數的值為1。否則為0。删除了原先的

    Loan_Amount_Submitted

    變量。
  • 增加了 

    Loan_Tenure_Submitted_Missing

     變量。如果 

    Loan_Tenure_Submitted

     變量的資料缺失,則這個參數的值為1。否則為0。删除了原先的

    Loan_Tenure_Submitted

     變量。
  • 删除了

    LoggedIn

    Salary_Account

     兩個變量
  • 增加了 

    Processing_Fee_Missing

     變量。如果 

    Processing_Fee

     變量的資料缺失,則這個參數的值為1。否則為0。删除了原先的 

    Processing_Fee

     變量。
  • Source

    前兩位不變,其它分成不同的類别。
  • 進行了離散化和獨熱編碼(一位有效編碼)。

如果你有原始資料,可以從資源庫裡面下載下傳

data_preparation

Ipython notebook

 檔案,然後自己過一遍這些步驟。

載入必要庫:

[python] 
    view plain
     copy
    
     
   
  
          
  1. import pandas as pd  
  2. import numpy as np  
  3. import xgboost as xgb  
  4. from xgboost.sklearn import XGBClassifier  
  5. from sklearn.model_selection import GridSearchCV,cross_val_score  
  6. from sklearn import  metrics  
  7. import matplotlib.pylab as plt  

讀取檔案

[python]  view plain  copy

  1. train_df = pd.read_csv('train_modified.csv')  
  2.     train_y = train_df.pop('Disbursed').values  
  3.     test_df = pd.read_csv('test_modified.csv')  
  4.     train_df.drop('ID',axis=1,inplace=True)  
  5.     test_df.drop('ID',axis=1,inplace=True)  
  6.     train_X = train_df.values  

然後評分函數未下:

[python]  view plain  copy

  1. def modelMetrics(clf,train_x,train_y,isCv=True,cv_folds=5,early_stopping_rounds=50):  
  2.     if isCv:  
  3.         xgb_param = clf.get_xgb_params()  
  4.         xgtrain = xgb.DMatrix(train_x,label=train_y)  
  5.         cvresult = xgb.cv(xgb_param,xgtrain,num_boost_round=clf.get_params()['n_estimators'],nfold=cv_folds,  
  6.                           metrics='auc',early_stopping_rounds=early_stopping_rounds)#是否顯示目前幾顆樹額  
  7.         clf.set_params(n_estimators=cvresult.shape[0])  
  8.     clf.fit(train_x,train_y,eval_metric='auc')  
  9.     #預測  
  10.     train_predictions = clf.predict(train_x)  
  11.     train_predprob = clf.predict_proba(train_x)[:,1]#1的機率  
  12.     #列印  
  13.     print("\nModel Report")  
  14.     print("Accuracy : %.4g" % metrics.accuracy_score(train_y, train_predictions))  
  15.     print("AUC Score (Train): %f" % metrics.roc_auc_score(train_y, train_predprob))  
  16.     feat_imp = pd.Series(clf.booster().get_fscore()).sort_values(ascending=False)  
  17.     feat_imp.plot(kind='bar',title='Feature importance')  
  18.     plt.ylabel('Feature Importance Score')  

我們測試下:

Model Report
Accuracy : 0.9854
AUC Score (Train): 0.851058      
XGBoost參數調優摘要:第四步:調整subsample 和 colsample_bytree 參數

我們看下其中具體的cv結果

cvresult.shape[0]是其中我們用的樹的個數

cvresult的結果是一個DataFrame

XGBoost參數調優摘要:第四步:調整subsample 和 colsample_bytree 參數

6.1 參數調優的一般方法

我們會使用和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. 降低學習速率,确定理想參數。

第一步:确定學習速率和tree_based 參數調優的估計器數目

為了确定

boosting

參數,我們要先給其它參數一個初始值。咱們先按如下方法取值:

1、

max_depth

 = 5 :這個參數的取值最好在3-10之間。我選的起始值為5,但是你也可以選擇其它的值。起始值在4-6之間都是不錯的選擇。

2、

min_child_weight

 = 1:在這裡選了一個比較小的值,因為這是一個極不平衡的分類問題。是以,某些葉子節點下的值會比較小。

3、

gamma

 = 0: 起始值也可以選其它比較小的值,在0.1到0.2之間就可以。這個參數後繼也是要調整的。

4、

subsample, colsample_bytree

 = 0.8: 這個是最常見的初始值了。典型值的範圍在0.5-0.9之間。

5、

scale_pos_weight

 = 1: 這個值是因為類别十分不平衡。 

這裡把學習速率就設成預設的0.1。然後用xgboost中的cv函數來确定最佳的決策樹數量。前文中的函數可以完成這個工作。

[python]  view plain  copy

  1. def tun_parameters(train_x,train_y):  
  2.     xgb1 = XGBClassifier(learning_rate=0.1,n_estimators=1000,max_depth=5,min_child_weight=1,gamma=0,subsample=0.8,  
  3.                          colsample_bytree=0.8,objective= 'binary:logistic',nthread=4,scale_pos_weight=1,seed=27)  
  4.     modelMetrics(xgb1,train_x,train_y)  

然後我們得到如下的結果:

是根據交叉驗證中疊代中
       
n_estimators: 112

Model Report
Accuracy : 0.9854
AUC Score (Train): 0.891681      

每一次疊代中使用交叉驗證,并傳回理想的決策樹數量。這個值取決于系統的性能。

第二步: max_depth 和 min_child_weight 參數調優

[python]  view plain  copy

  1. param_test1 = {  
  2.     'max_depth':range(3,10,2),  
  3.     'min_child_weight':range(1,6,2)  
  4. }  
  5. gsearch1 = GridSearchCV(estimator=XGBClassifier( learning_rate =0.1, n_estimators=140, max_depth=5,  
  6. min_child_weight=1, gamma=0, subsample=0.8,colsample_bytree=0.8,  
  7. objective= 'binary:logistic', nthread=4,scale_pos_weight=1, seed=27),  
  8.                         param_grid=param_test1,scoring='roc_auc',iid=False,cv=5)  
  9. gsearch1.fit(train_X,train_y)  
  10. gsearch1.grid_scores_,gsearch1.best_params_,gsearch1.best_score_  
XGBoost參數調優摘要:第四步:調整subsample 和 colsample_bytree 參數

我們看見min_child_weight已經在邊界處了是以我們還可以繼續調整,也可以在下個參數一起調節

我們能夠進一步看是否6比較好,      
[python] 
    view plain
     copy
    
     
   
  
          
  1. param_test2b = {  
  2.     'min_child_weight': [6, 8, 10, 12]  
  3. }  
  4. gsearch2b = GridSearchCV(estimator=XGBClassifier(learning_rate=0.1, n_estimators=140, max_depth=4,  
  5.                                                  min_child_weight=2, gamma=0, subsample=0.8, colsample_bytree=0.8,  
  6.                                                  objective='binary:logistic', nthread=4, scale_pos_weight=1,  
  7.                                                  seed=27), param_grid=param_test2b, scoring='roc_auc', n_jobs=4,  
  8.                          iid=False, cv=5)  
  9. gsearch2b.fit(train_x, train_y)  
  10. gsearch2b.grid_scores_, gsearch2b.best_params_, gsearch2b.best_score_  
  11. modelMetrics(gsearch2b, train_x, train_y)  
XGBoost參數調優摘要:第四步:調整subsample 和 colsample_bytree 參數
6确實是最佳的值了,不用再調節了。      
然後我們拟合一下看下模型評分:      
n_estimators: 140

Model Report
Accuracy : 0.9854
AUC Score (Train): 0.875086      

第三步:gamma參數調優

在已經調整好其它參數的基礎上,我們可以進行gamma參數的調優了。Gamma參數取值範圍可以很大,我這裡把取值範圍設定為5了。你其實也可以取更精确的gamma值。 [python] view plain copy
  1. param_test3 = {  
  2.     'gamma': [i / 10.0 for i in range(0, 5)]  
  3. }  
  4. gsearch3 = GridSearchCV(  
  5.     estimator=XGBClassifier(learning_rate=0.1, n_estimators=140, max_depth=4, min_child_weight=6, gamma=0,  
  6.                             subsample=0.8, colsample_bytree=0.8, objective='binary:logistic', nthread=4,  
  7.                             scale_pos_weight=1, seed=27), param_grid=param_test3, scoring='roc_auc', n_jobs=4,  
  8.     iid=False, cv=5)  
  9. gsearch3.fit(train_x,train_y)  
  10. gsearch3.grid_scores_, gsearch3.best_params_, gsearch3.best_score_  
XGBoost參數調優摘要:第四步:調整subsample 和 colsample_bytree 參數
從這裡,可以看出,得分提高了。是以,最終得到的參數是:
       
xgb2 = XGBClassifier(
 learning_rate =,
 n_estimators=,
 max_depth=,
 min_child_weight=,
 gamma=,
 subsample=,
 colsample_bytree=,
 objective= 'binary:logistic',
 nthread=,
scale_pos_weight=,
seed=)
modelfit(xgb2, train, predictors)
           

第四步:調整subsample 和 colsample_bytree 參數

這兩個參數相當于每個樹的樣本和參數個數
[python] 
    view plain
     copy
    
     
   
  
          
  1. param_test4 = {  
  2.     'subsample': [i / 10.0 for i in range(6, 10)],  
  3.     'colsample_bytree': [i / 10.0 for i in range(6, 10)]  
  4. }  
  5. gsearch4 = GridSearchCV(  
  6.     estimator=XGBClassifier(learning_rate=0.1, n_estimators=177, max_depth=3, min_child_weight=4, gamma=0.1,  
  7.                             subsample=0.8, colsample_bytree=0.8, objective='binary:logistic', nthread=4,  
  8.                             scale_pos_weight=1, seed=27), param_grid=param_test4, scoring='roc_auc', n_jobs=4,  
  9.     iid=False, cv=5)  
  10. gsearch4.fit(train_x, train_y)  
  11. gsearch4.grid_scores_, gsearch4.best_params_, gsearch4.best_score_  
([mean: 0.83836, std: 0.00840, params: {'subsample': 0.6, 'colsample_bytree': 0.6},
  mean: 0.83720, std: 0.00976, params: {'subsample': 0.7, 'colsample_bytree': 0.6},
  mean: 0.83787, std: 0.00758, params: {'subsample': 0.8, 'colsample_bytree': 0.6},
  mean: 0.83776, std: 0.00762, params: {'subsample': 0.9, 'colsample_bytree': 0.6},
  mean: 0.83923, std: 0.01005, params: {'subsample': 0.6, 'colsample_bytree': 0.7},
  mean: 0.83800, std: 0.00853, params: {'subsample': 0.7, 'colsample_bytree': 0.7},
  mean: 0.83819, std: 0.00779, params: {'subsample': 0.8, 'colsample_bytree': 0.7},
  mean: 0.83925, std: 0.00906, params: {'subsample': 0.9, 'colsample_bytree': 0.7},
  mean: 0.83977, std: 0.00831, params: {'subsample': 0.6, 'colsample_bytree': 0.8},
  mean: 0.83867, std: 0.00870, params: {'subsample': 0.7, 'colsample_bytree': 0.8},
  mean: 0.83879, std: 0.00797, params: {'subsample': 0.8, 'colsample_bytree': 0.8},
  mean: 0.84144, std: 0.00854, params: {'subsample': 0.9, 'colsample_bytree': 0.8},
  mean: 0.83878, std: 0.00760, params: {'subsample': 0.6, 'colsample_bytree': 0.9},
  mean: 0.83922, std: 0.00823, params: {'subsample': 0.7, 'colsample_bytree': 0.9},
  mean: 0.83912, std: 0.00765, params: {'subsample': 0.8, 'colsample_bytree': 0.9},
  mean: 0.83926, std: 0.00843, params: {'subsample': 0.9, 'colsample_bytree': 0.9}],
 {'colsample_bytree': 0.8, 'subsample': 0.9},
 0.84143722014693034)      
若我們再将精度增加的話,我們将步長調節到0.05      
XGBoost參數調優摘要:第四步:調整subsample 和 colsample_bytree 參數
我們得到的理想取值還是原來的值。是以,最終的理想取值是:

       
  • subsample: 0.8
  • colsample_bytree: 0.8

第五步:正則化參數調優

下一步是應用正則化來降低過拟合。由于gamma函數提供了一種更加有效地降低過拟合的方法,大部分人很少會用到這個參數。但是我們在這裡也可以嘗試用一下這個參數。

[python]

view plain

copy

  1. param_test6 = {  
  2.  'reg_alpha':[1e-5, 1e-2, 0.1, 1, 100]  
  3. }  
  4. gsearch6 = GridSearchCV(estimator = XGBClassifier( learning_rate =0.1, n_estimators=177, max_depth=4, min_child_weight=6, gamma=0.1, subsample=0.8, colsample_bytree=0.8, objective= 'binary:logistic', nthread=4, scale_pos_weight=1,seed=27), param_grid = param_test6, scoring='roc_auc',n_jobs=4,iid=False, cv=5)  
  5. gsearch6.fit(train_X, train_y)  
  6. gsearch6.grid_scores_, gsearch6.best_params_, gsearch6.best_score_  
([mean: 0.83949, std: 0.00720, params: {'reg_alpha': 1e-05},
  mean: 0.83940, std: 0.00607, params: {'reg_alpha': 0.01},
  mean: 0.84005, std: 0.00638, params: {'reg_alpha': 0.1},
  mean: 0.84062, std: 0.00775, params: {'reg_alpha': 1},
  mean: 0.81217, std: 0.01559, params: {'reg_alpha': 100}],
 {'reg_alpha': 1},
 0.84062434371797357)      

相比之前的結果,CV的得分甚至還降低了。但是我們之前使用的取值是十分粗糙的,我們在這裡選取一個比較靠近理想值(0.01)的取值,來看看是否有更好的表現。

[python] 
    view plain
     copy
    
     
   
  
          
  1. param_test7 = {  
  2.     'reg_alpha': [0, 0.001, 0.005, 0.01, 0.05]  
  3. }  
  4. gsearch7 = GridSearchCV(  
  5.     estimator=XGBClassifier(learning_rate=0.1, n_estimators=177, max_depth=4, min_child_weight=6, gamma=0.1,  
  6.                             subsample=0.8, colsample_bytree=0.8, objective='binary:logistic', nthread=4,  
  7.                             scale_pos_weight=1, seed=27), param_grid=param_test7, scoring='roc_auc', n_jobs=4,  
  8.     iid=False, cv=5)  
  9. gsearch7.fit(train_x, train_y)  
  10. gsearch7.grid_scores_, gsearch7.best_params_, gsearch7.best_score_  
調整精度以後 CV的得分提高了。現在,我們在模型中來使用正則化參數,來看看這個參數的影響。
xgb3 = XGBClassifier(
 learning_rate =,
 n_estimators=,
 max_depth=,
 min_child_weight=,
 gamma=,
 subsample=,
 colsample_bytree=,
 reg_alpha=,
 objective= 'binary:logistic',
 nthread=,
 scale_pos_weight=,
 seed=)
           
[python] 
     view plain
      copy
     
      
    
   
           
現在我們可以來看下reg_lambda參數調節:
([mean: 0.83996, std: 0.00597, params: {'reg_lambda': 1e-05},
  mean: 0.84030, std: 0.00580, params: {'reg_lambda': 0.01},
  mean: 0.83965, std: 0.00574, params: {'reg_lambda': 0.1},
  mean: 0.84035, std: 0.00622, params: {'reg_lambda': 1},
  mean: 0.83601, std: 0.00944, params: {'reg_lambda': 100}],
 {'reg_lambda': 1},
 0.84035395025572046)      
[python] view plain copy
  1. param_test8 = {  
  2.     'reg_lambda': [1e-5, 1e-2, 0.1, 1, 100]  
  3. }  
  4. gsearch8 = GridSearchCV(  
  5.     estimator=XGBClassifier(learning_rate =0.1, n_estimators=177,max_depth=4,min_child_weight=6, gamma=0, subsample=0.8, colsample_bytree=0.8, reg_alpha=0.005,  
  6.                             objective= 'binary:logistic',nthread=4, scale_pos_weight=1,seed=27), param_grid=param_test8, scoring='roc_auc', n_jobs=4,  
  7.     iid=False, cv=5)  
  8. gsearch8.fit(train_X, train_y)  
  9. gsearch8.grid_scores_, gsearch8.best_params_, gsearch8.best_score_  

第6步:降低學習速率

最後,我們使用較低的學習速率,以及使用更多的決策樹。我們可以用XGBoost中的CV函數來進行這一步工作。 xgb4 = XGBClassifier( learning_rate =0.01, n_estimators=5000, max_depth=4, min_child_weight=6, gamma=0, subsample=0.8, colsample_bytree=0.8, reg_alpha=0.005, objective= 'binary:logistic', nthread=4, scale_pos_weight=1, seed=27)
我們看下最後的模型評分      
XGBoost參數調優摘要:第四步:調整subsample 和 colsample_bytree 參數
至此,你可以看到模型的表現有了大幅提升,調整每個參數帶來的影響也更加清楚了。 
在文章的末尾,我想分享兩個重要的思想: 
1、僅僅靠參數的調整和模型的小幅優化,想要讓模型的表現有個大幅度提升是不可能的。GBM的最高得分是0.8487,XGBoost的最高得分是0.8494。确實是有一定的提升,但是沒有達到質的飛躍。 
2、要想讓模型的表現有一個質的飛躍,需要依靠其他的手段,諸如,特征工程(feature egineering) ,模型組合(ensemble of model),以及堆疊(stacking)等。      

繼續閱讀