常規操作,先吹一下XGBoost:
XGBoost的核心思想是不斷地添加樹,不斷地進行特徵分裂來生長一棵樹,每次添加一個樹,其實是學習一個新函數f(x),去擬合上次預測的殘差。當我們訓練完成得到k棵樹,我們要預測一個樣本的分數,其實就是根據這個樣本的特徵,在每棵樹中會落到對應的一個葉子節點,每個葉子節點就對應一個分數。最後只需要將每棵樹對應的分數加起來就是該樣本的預測值。
XGBoost對GBDT進行了一系列優化,比如損失函數進行了二階泰勒展開、目標函數加入正則項、支持並行和默認缺失值處理等,在可擴展性和訓練速度上有了巨大的提升,但其核心思想沒有大的變化。
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_
最後補充的是:
數據和特徵工程決定了模型效果的上限,而模型的調參只是逼近這個上限。
特徵工程傳送門在此。