机器学习算法总结--GBDT
參考如下
- 機器學習(四)— 從gbdt到xgboost
- 機器學習常見算法個人總結(面試用)
- xgboost入門與實戰(原理篇)
簡介
GBDT是一個基于迭代累加的決策樹算法,它通過構造一組弱的學習器(樹),并把多顆決策樹的結果累加起來作為最終的預測輸出。
算法介紹
GBDT是希望組合一組弱的學習器的線性組合,即有:
上述公式中 pm表示步長,我們可以在函數空間形式上使用梯度下降法求解,首先固定 x,然后對F(x)求其最優解。下面先給出框架流程:
我們需要做的是估計gm(x),它是梯度方向;通過使用決策樹實現來逼近gm(x),使得兩者之間的距離盡可能的近,而距離的衡量方式有多種,包括均方誤差和LogLoss誤差。下面給出使用LogLoss損失函數的具體推導:
Step1 首先求解初始值F0,令其偏導為0。(實現時是第1棵樹需要擬合的殘差):
Step 2 估計gm(x),并用決策樹對其進行擬合。gm(x)是梯度,實現時是第m棵樹需要擬合的殘差:
Step 3 使用牛頓法求解下降方向步長。rjm是擬合的步長,實現時是每棵樹的預測值。(通常實現中這一步是被省略的,改為使用Shrinkage的策略通過參數設置步長,避免過擬合。
Step 4 預測時只需要把每棵樹的預測值乘以縮放因子然后相加即可得到最終的預測值:
若需要預測值輸出區間在 [0,1],可作如下轉換:
probability=11+e?2?predict
GBDT中的樹是回歸樹,不是分類樹。
RF與GBDT對比
(1)RF中樹的棵樹是并行生成的;GBDT中樹是順序生成的;兩者中過多的樹都會過擬合,但是GBDT更容易過擬合;
(2)RF中每棵樹分裂的特征比較隨機;GBDT中前面的樹優先分裂對大部分樣本區分的特征,后面的樹分裂對小部分樣本區分特征;
(3)RF中主要參數是樹的棵數;GBDT中主要參數是樹的深度,一般為1;
Shrinkage
Shrinkage認為,每次走一小步逐步逼近的結果要比每次邁一大步逼近結果更加容易避免過擬合。
y(1~i)=y(1~i?1)+step?yi
優缺點
優點
缺點
調參
xgboost
xgboost是boosting Tree的一個很牛的實現,它在最近Kaggle比賽中大放異彩。它 有以下幾個優良的特性:
在項目實測中使用發現,Xgboost的訓練速度要遠遠快于傳統的GBDT實現,10倍量級。
特點
這部分內容參考了知乎上的一個問答—機器學習算法中GBDT和XGBOOST的區別有哪些?,答主是wepon大神
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 —還是為了防止過擬合
(1)shrinkage縮減類似于學習速率,在每一步tree boosting之后增加了一個參數n(權重),通過這種方式來減小每棵樹的影響力,給后面的樹提供空間去優化模型。
(2)column subsampling列(特征)抽樣,說是從隨機森林那邊學習來的,防止過擬合的效果比傳統的行抽樣還好(行抽樣功能也有),并且有利于后面提到的并行化處理算法。
5.split finding algorithms(劃分點查找算法):
(1)exact greedy algorithm—貪心算法獲取最優切分點
(2)approximate algorithm— 近似算法,提出了候選分割點概念,先通過直方圖算法獲得候選分割點的分布情況,然后根據候選分割點將連續的特征信息映射到不同的buckets中,并統計匯總信息。
(3)Weighted Quantile Sketch—分布式加權直方圖算法
這里的算法(2)、(3)是為了解決數據無法一次載入內存或者在分布式情況下算法(1)效率低的問題,以下引用的還是wepon大神的總結:
可并行的近似直方圖算法。樹節點在進行分裂時,我們需要計算每個特征的每個分割點對應的增益,即用貪心法枚舉所有可能的分割點。當數據無法一次載入內存或者在分布式情況下,貪心算法效率就會變得很低,所以xgboost還提出了一種可并行的近似直方圖算法,用于高效地生成候選的分割點。
6.對缺失值的處理。對于特征的值有缺失的樣本,xgboost可以自動學習出它的分裂方向。 —稀疏感知算法
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選擇合適的塊大小
代碼使用
下面給出簡單使用xgboost這個框架的例子。
# 劃分數據集 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.01, random_state=1729) print(X_train.shape, X_test.shape)#模型參數設置 xlf = xgb.XGBRegressor(max_depth=10, learning_rate=0.1, n_estimators=10, silent=True, objective='reg:linear', nthread=-1, gamma=0,min_child_weight=1, max_delta_step=0, subsample=0.85, colsample_bytree=0.7, colsample_bylevel=1, reg_alpha=0, reg_lambda=1, scale_pos_weight=1, seed=1440, missing=None)xlf.fit(X_train, y_train, eval_metric='rmse', verbose = True, eval_set = [(X_test, y_test)],early_stopping_rounds=100)# 計算 auc 分數、預測 preds = xlf.predict(X_test)一個運用到實際例子的代碼,來自xgboost入門與實戰(實戰調參篇)
import numpy as np import pandas as pd import xgboost as xgb from sklearn.cross_validation import train_test_split#from xgboost.sklearn import XGBClassifier #from sklearn import cross_validation, metrics #Additional scklearn functions #from sklearn.grid_search import GridSearchCV #Perforing grid search # #import matplotlib.pylab as plt #from matplotlib.pylab import rcParams#記錄程序運行時間 import time start_time = time.time()#讀入數據 train = pd.read_csv("Digit_Recognizer/train.csv") tests = pd.read_csv("Digit_Recognizer/test.csv") params={ 'booster':'gbtree', 'objective': 'multi:softmax', #多分類的問題 'num_class':10, # 類別數,與 multisoftmax 并用 'gamma':0.1, # 用于控制是否后剪枝的參數,越大越保守,一般0.1、0.2這樣子。 'max_depth':12, # 構建樹的深度,越大越容易過擬合 'lambda':2, # 控制模型復雜度的權重值的L2正則化項參數,參數越大,模型越不容易過擬合。 'subsample':0.7, # 隨機采樣訓練樣本 'colsample_bytree':0.7, # 生成樹時進行的列采樣 'min_child_weight':3, # 這個參數默認是 1,是每個葉子里面 h 的和至少是多少,對正負樣本不均衡時的 0-1 分類而言 #,假設 h 在 0.01 附近,min_child_weight 為 1 意味著葉子節點中最少需要包含 100 個樣本。 #這個參數非常影響結果,控制葉子節點中二階導的和的最小值,該參數值越小,越容易 overfitting。 'silent':0 ,#設置成1則沒有運行信息輸出,最好是設置為0. 'eta': 0.007, # 如同學習率 'seed':1000, 'nthread':7,# cpu 線程數 #'eval_metric': 'auc' }plst = list(params.items()) num_rounds = 5000 # 迭代次數train_xy,val = train_test_split(train, test_size = 0.3,random_state=1) #random_state is of big influence for val-auc y = train_xy[:, 0] X = train_xy[:, 1:] val_y = val[:, 0] val_X = val[:, 1:]xgb_val = xgb.DMatrix(val_X,label=val_y) xgb_train = xgb.DMatrix(X, label=y) xgb_test = xgb.DMatrix(tests)watchlist = [(xgb_train, 'train'),(xgb_val, 'val')]# training model # early_stopping_rounds 當設置的迭代次數較大時,early_stopping_rounds 可在一定的迭代次數內準確率沒有提升就停止訓練 model = xgb.train(plst, xgb_train, num_rounds, watchlist,early_stopping_rounds=100)model.save_model('./model/xgb.model') # 用于存儲訓練出的模型 print "best best_ntree_limit",model.best_ntree_limit print "跑到這里了model.predict" preds = model.predict(xgb_test,ntree_limit=model.best_ntree_limit)np.savetxt('xgb_submission.csv',np.c_[range(1,len(tests)+1),preds],delimiter=',',header='ImageId,Label',comments='',fmt='%d')#輸出運行時長 cost_time = time.time()-start_time print "xgboost success!",'\n',"cost time:",cost_time,"(s)"所使用的數據集是Kaggle上的Classify handwritten digits using the famous MNIST data–手寫數字識別數據集,即Mnist數據集。
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的机器学习算法总结--GBDT的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【bzoj4987】Tree【树形dp】
- 下一篇: 比尔盖茨的30条经典语录