機器學習XGBoost模型調參技巧和代碼實現

常規操作,先吹一下XGBoost:

XGBoost的核心思想是不斷地添加樹,不斷地進行特徵分裂來生長一棵樹,每次添加一個樹,其實是學習一個新函數f(x),去擬合上次預測的殘差。當我們訓練完成得到k棵樹,我們要預測一個樣本的分數,其實就是根據這個樣本的特徵,在每棵樹中會落到對應的一個葉子節點,每個葉子節點就對應一個分數。最後只需要將每棵樹對應的分數加起來就是該樣本的預測值。

XGBoost對GBDT進行了一系列優化,比如損失函數進行了二階泰勒展開、目標函數加入正則項、支持並行和默認缺失值處理等,在可擴展性和訓練速度上有了巨大的提升,但其核心思想沒有大的變化。

XGBoost官方文檔:傳送門


目錄

 

一、Xgboost的優勢

二、Xgboost的參數

 三、Xgboost參數調優實例


一、Xgboost的優勢

1、Regularization(正則化)

2、Parallel Processing(並行處理):

3、High Flexibility(高度靈活)

4、Handling Missing Values(處理缺失值)值,並作爲參數傳遞。

5、Tree Pruning(樹剪枝)

6、Built-in Cross-Validation(內置的交叉驗證)

7、Continue on Existing Model(繼續現有模型)

二、Xgboost的參數

Xgboost將工具分成了三大類:

-- General Parameters(通用參數):設置整體功能,宏觀函數控制

-- Booster Parameters(提升參數):選擇你每一步的booster(tree/regression),booster參數一般可以調控模型的效果和計算代價。我們所說的調參,很這是大程度上都是在調整booster參數。

-- Learning Task Parameters(學習目標參數):指導優化任務的執行,控制訓練目標的表現。我們對於問題的劃分主要體現在學習目標參數上。比如我們要做分類還是迴歸,做二分類還是多分類,這都是目標參數所提供的。

1、通用參數

--booster [default=gbtree]
選擇每次迭代過程中需要運行的模型,一共有兩種選擇:
gbtree: tree-based models,採用樹的結構來運行數據;
gblinear:基於線性模型;

--silent [default=0]
設置模型是否有logo打印:
0:有打印
1:無打印

--nthread [default to maximum number of threads available if not set]
這個主要用於並行處理的,如果不指定值,工具會自動檢測。一般我們設置成-1,使用所有線程。
剩餘兩個參數是Xgboost自動指定的,無需設置

2、提升參數

雖然有兩種類型的booster,但是我們這裏只介紹tree。因爲tree的性能比線性迴歸好得多,因此我們很少用線性迴歸。

--eta [default=0.3, alias: learning_rate]
學習率,可以縮減每一步的權重值,使得模型更加健壯:
典型值一般設置爲:0.01-0.2

--min_child_weight [default=1]
定義了一個子集的所有觀察值的最小權重和。
這個可以用來減少過擬合,但是過高的值也會導致欠擬合,因此可以通過CV來調整min_child_weight。
 
 --max_depth [default=6]
樹的最大深度,值越大,樹越複雜。
這個可以用來控制過擬合,典型值是3-10。

--gamma [default=0, alias: min_split_loss]
這個指定了一個結點被分割時,所需要的最小損失函數減小的大小。
這個值一般來說需要根據損失函數來調整。

--max_delta_step(默認= 0)
這個參數通常並不需要。

--subsample [default=1]
樣本的採樣率,如果設置成0.5,那麼Xgboost會隨機選擇一半的樣本作爲訓練集。

--colsample_bytree [default=1]
構造每棵樹時,列採樣率(一般是特徵採樣率)。

--colsample_bylevel [default=1]
每執行一次分裂,列採樣率。這個一般很少用,有subsample、colsample_bytree 就可以。

--lambda [default=1, alias: reg_lambda]
L2正則化(與嶺迴歸中的正則化類似:傳送門)這個其實用的很少。

--alpha [default=0, alias: reg_alpha]
L1正則化(與lasso迴歸中的正則化類似:傳送門)這個主要是用在數據維度很高的情況下,可以提高運行速度。

--scale_pos_weight, [default=1]
在類別高度不平衡的情況下,將參數設置大於0,可以加快收斂。

3、學習任務參數

這類參數主要用來明確學習任務和相應的學習目標的

--objective [default=reg:linear]
這個主要是指定學習目標的:而分類,還是多分類or迴歸
“reg:linear” –linear regression:迴歸
“binary:logistic”:二分類
“multi:softmax” :多分類,這個需要指定類別個數

--eval_metric [default according to objective]
*評估方法,主要用來驗證數據,根據一個學習目標會默認分配一個評估指標
“rmse”:均方根誤差(迴歸任務)
“error”:分類任務
“map”:Mean average precision(平均準確率,排名任務)

--seed [default=0]
隨機數種子,可以用來生成可複製性的結果,也可用來調參

 三、Xgboost參數調優實例

調參的通用方法:

-- 選擇一個相對較高的學習率。通常來說學習率設置爲0.1。但是對於不同的問題可以講學習率設置在0.05-0.3。通過交叉驗證來尋找符合學習率的最佳樹的個數。

-- 當確定好學習率與最佳樹的個數時,調整樹的某些特定參數。比如:max_depth, min_child_weight, gamma, subsample, colsample_bytree

-- 調整正則化參數 ,比如: lambda, alpha。這個主要是爲了減少模型複雜度和提高運行速度的。適當地減少過擬合。

1、首先我們設置一些參數的初始值(你可以設置不同的值):

#Choose all predictors except target & IDcols
predictors = [x for x in train.columns if x not in [target, IDcol]]
xgb1 = XGBClassifier(
 learning_rate =0.1,
 n_estimators=20,
 max_depth=5,
 min_child_weight=1,
 gamma=0,
 subsample=0.8,
 colsample_bytree=0.8,
 objective= 'binary:logistic',
 nthread=4,
 scale_pos_weight=1,
 seed=27)
modelfit(xgb1, train, predictors)

2、調整max_depth 和min_child_weight

我們調整這兩個參數是因爲這兩個參數對輸出結果的影響很大。我們首先將這兩個參數設置爲較大的數,然後通過迭代的方式不斷修正,縮小範圍。

param_test1 = {
 'max_depth':list(range(3,10,2)),
 'min_child_weight':list(range(1,6,2))
}
gsearch1 = GridSearchCV(estimator = XGBClassifier( learning_rate =0.1, n_estimators=20, max_depth=5,
 min_child_weight=1, gamma=0, subsample=0.8, colsample_bytree=0.8,
 objective= 'binary:logistic', nthread=4, scale_pos_weight=1, seed=27), 
 param_grid = param_test1, scoring='roc_auc',n_jobs=4,iid=False, cv=5)
gsearch1.fit(train[predictors],train[target])
gsearch1.grid_scores_, gsearch1.best_params_, gsearch1.best_score_

接下來縮小範圍,將兩個序列範圍約束在[8,9,10];[1,2,3]

param_test2 = {
 'max_depth':[8,9,10],
 'min_child_weight':[1,2,3]
}
gsearch2 = GridSearchCV(estimator = XGBClassifier( learning_rate=0.1, n_estimators=20, max_depth=5,
 min_child_weight=2, gamma=0, subsample=0.8, colsample_bytree=0.8,
 objective= 'binary:logistic', nthread=4, scale_pos_weight=1,seed=27), 
 param_grid = param_test2, scoring='roc_auc',n_jobs=4,iid=False, cv=5)
gsearch2.fit(train[predictors],train[target])
gsearch2.grid_scores_, gsearch2.best_params_, gsearch2.best_score_

3、調整gamma

param_test3 = {
 'gamma':[i/10.0 for i in range(0,5)]
}
gsearch3 = GridSearchCV(estimator = XGBClassifier( learning_rate =0.1, n_estimators=20, max_depth=10,
 min_child_weight=1, gamma=0, subsample=0.8, colsample_bytree=0.8,
 objective= 'binary:logistic', nthread=4, scale_pos_weight=1,seed=27), 
 param_grid = param_test3, scoring='roc_auc',n_jobs=4,iid=False, cv=5)
gsearch3.fit(train[predictors],train[target])
gsearch3.grid_scores_, gsearch3.best_params_, gsearch3.best_score_

 這裏gamma已經從我們前面默認的0,變成了0.2了。

最後我們用最優參數再次運行一下程序:

xgb1 = XGBClassifier(
 learning_rate =0.1,
 n_estimators=20,
 max_depth=10,
 min_child_weight=1,
 gamma=0.2,
 subsample=0.8,
 colsample_bytree=0.8,
 objective= 'binary:logistic',
 nthread=4,
 scale_pos_weight=1,
 seed=27)
modelfit(xgb1, train, predictors)

4、調整subsample 和colsample_bytree

param_test5 = {
 'subsample':[i/100.0 for i in range(75,90,5)],
 'colsample_bytree':[i/100.0 for i in range(75,90,5)]
}
gsearch5 = GridSearchCV(estimator = XGBClassifier( learning_rate =0.1, n_estimators=20, max_depth=10,
 min_child_weight=1, gamma=0.2, subsample=0.8, colsample_bytree=0.8,
 objective= 'binary:logistic', nthread=4, scale_pos_weight=1,seed=27), 
 param_grid = param_test5, scoring='roc_auc',n_jobs=4,iid=False, cv=5)
gsearch5.fit(train[predictors],train[target])
gsearch5.grid_scores_, gsearch5.best_params_, gsearch5.best_score_

 5、調整正則化參數

param_test6 = {
 'reg_alpha':[1e-5, 1e-2, 0.1, 1, 100]
}
gsearch6 = GridSearchCV(estimator = XGBClassifier( learning_rate =0.1, n_estimators=20, max_depth=10,
 min_child_weight=1, gamma=0.2, 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)
gsearch6.fit(train[predictors],train[target])
gsearch6.grid_scores_, gsearch6.best_params_, gsearch6.best_score_

6、減小學習率

param_test6 = {
 'reg_alpha':[1e-5, 1e-2, 0.1, 1, 100]
}
gsearch6 = GridSearchCV(estimator = XGBClassifier( learning_rate =0.1, n_estimators=20, max_depth=10,
 min_child_weight=1, gamma=0.2, 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)
gsearch6.fit(train[predictors],train[target])
gsearch6.grid_scores_, gsearch6.best_params_, gsearch6.best_score_

最後補充的是:

數據和特徵工程決定了模型效果的上限,而模型的調參只是逼近這個上限。

特徵工程傳送門在此

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章