GBDT:梯度提升樹演算法

以下內容來自劉建平Pinard-博客園的學習筆記,總結如下:

本文對Boosting家族中一個重要的演算法梯度提升樹(Gradient Boosting Decison Tree, 簡稱GBDT)做一個總結。GBDT有很多簡稱,有GBT(Gradient Boosting Tree), GTB(Gradient Tree Boosting ), GBRT(Gradient Boosting Regression Tree), MART(Multiple Additive Regression Tree),其實都是指的同一種演算法,本文統一簡稱GBDT。

1 GBDT概述

GBDT也是集成學習Boosting家族的成員,但是卻和傳統的Adaboost有很大的不同。Adaboost是利用前一輪迭代弱學習器的誤差率來更新訓練集的權重,這樣一輪輪的迭代下去。GBDT也是迭代,使用了前向分布演算法,但是弱學習器限定了只能使用CART回歸樹模型,同時迭代思路和Adaboost也有所不同。

在GBDT的迭代中,假設前一輪迭代得到的強學習器是 f_{t-1}(x) ,損失函數是 L(y,f_{t-1}(x)) ,本輪迭代的目標是找到一個CART回歸樹模型的弱學習器 h_{t}(x) ,讓本輪的損失函數 L(y,f_{t}(x)) = L(y,f_{t-1}(x) + h_{t}(x)) 最小 。即本輪迭代找到決策樹,要讓樣本的損失盡量變得更小。

GBDT的思想可以用一個通俗的例子解釋,假如有個人30歲,我們首先用20歲去擬合,發現損失有10歲,這時我們用6歲去擬合剩下的損失,發現差距還有4歲,第三輪我們用3歲擬合剩下的差距,差距就只有一歲了。如果我們的迭代輪數還沒有完,可以繼續迭代下面,每一輪迭代,擬合的歲數誤差都會減小。

2 GBDT的負梯度擬合

用損失函數的負梯度來擬合本輪損失的近似值,進而擬合一個CART回歸樹。第t輪的第i個樣本的損失函數的負梯度表示為

r_{ti} = - [ frac{partial L(y,f(x_{i}))}{partial f(x_{i})}]_{f(x) = f_{t-1}}(x)

利用 (x_{i},r_{ti}) i = 1,2,...m ,可以擬合一棵CART回歸樹,得到第t課回歸樹,其對應的葉結點區域 R_{tj},j = 1,2...,J 。其中j為葉結點的個數。

針對每一個葉結點裡的樣本,求出使損失函數最小,即擬合葉結點最好的輸出值 c_{tj}

c_{tj} = arg min sum_{x_{i}in R_{tj}}^{}{L(y_{i},f_{t-1}(x_{i}) + c)}

得到本輪的決策樹擬合函數

h_{t}(x) = sum_{j=1}^{J}{c_{tj}I(xin R_{tj})}

從而本輪最終得到的強學習器表達式如下

f_{t}(x) = f_{t-1}(x) + sum_{j=1}^{J}{c_{tj}I(xin R_{tj})}

通過損失函數的負梯度來擬合,我們找到了一種通用的擬合損失誤差的辦法,這樣無論是分類問題還是回歸問題,我們通過其損失函數的負梯度的擬合,就可以用GBDT來解決我們的分類回歸問題。區別僅僅在於損失函數不同導致的負梯度不同而已。

3 GBDT回歸演算法

輸入:訓練集樣本 T = left{ {(x_{1},y_{1}),(x_{2},y_{2}),...,(x_{m},y_{m})} 
ight} ,最大迭代次數T,損失函數L。

輸出:強學習器 f(x)

(1)初始化弱學習器

f_{0}(x) = arg min sum_{i=1}^{m}{L(y_{i},c)}

(2)對迭代輪數 t = 1,2,...,T,有

a)對樣本i = 1,2,...,m,計算負梯度

b) 利用 (x_{i},r_{ti}),i = 1,2,...,m ,擬合一棵CART回歸樹,得到第t棵回歸樹,其對應的葉結點區域為 R_{tj},j = 1,2,...,J 。其中j為回歸樹t的葉結點的個數。

c)對葉子區域 j = 1,2,...,J ,計算最佳擬合值

d)更新強學習器

(3)得到強學習器 f(x) 的表達式

f(x) = f_{T}(x) = sum_{t=1}^{T}{sum_{j=1}^{J}{c_{tj}I(xin R_{tj})}}

4 GBDT分類演算法

GBDT的分類演算法從思想上和GBDT的回歸演算法沒有區別,但是由於樣本輸出不是連續的值,而是離散的類別,導致我們無法直接從輸出類別去擬合類別輸出的誤差。

  為了解決這個問題,主要有兩個方法,一個是用指數損失函數,此時GBDT退化為Adaboost演算法。另一種方法是用類似於邏輯回歸的對數似然損失函數的方法。也就是說,我們用的是類別的預測概率值和真實概率值的差來擬合損失。本文僅討論用對數似然損失函數的GBDT分類。而對於對數似然損失函數,我們又有二元分類和多元分類的區別。

4.1 二元GBDT分類演算法

對於二元GBDT,如果用類似於邏輯回歸的對數似然損失函數,則損失函數為

L(y,f(x)) = log(1 + exp(-yf(x)))

其中 y in left{ -1,+1 
ight} 。則此時的負梯度誤差為

r_{ti} = -left[ frac{partial L(y,f(x_{i}))}{partial f(x_{i})} 
ight]_{f(x) = f_{t-1}(x)} = frac{y_{i}}{1 + exp(y f(x_{i}))}

對於生成的決策樹,各個葉子節點的最佳殘差擬合值為

c_{tj} = arg min sum_{x_{i}in R_{tj}}^{}{log(1+exp(y_{i}(f_{t-1}(x_{i})+c)))}

由於上式比較難優化,一般使用近似值代替

c_{tj} = frac{sum_{x_{i}in R_{tj}}^{}{}}{sum_{x_{i}in R_{tj}}^{}{left| r_{ti} 
ight|}(2-left| r_{ti} 
ight|}

除了負梯度計算和葉子節點的最佳殘差擬合的線性搜索,二元GBDT分類和GBDT回歸演算法過程相同。

4.2 多元GBDT分類演算法

多元GBDT要比二元GBDT複雜一些,對應的是多元邏輯回歸和二元邏輯回歸的複雜度差別。假設類別數為K,則此時我們的對數似然損失函數為

L(y,f(x)) = -sum_{k=1}^{K}{y_{k}log p_{k}(x)}

其中如果樣本輸出類別為K,則 y_{k} = 1 .第k類的概率 p_{k}(x) 的表達式為

p_{k}(x) = frac{exp(f_{k}(x))}{sum_{l=1}^{k}{exp(f_{l}(x))}}

除了負梯度計算和葉子節點的最佳殘差擬合的線性搜索,多元GBDT分類和二元GBDT分類以及GBDT回歸演算法過程相同。

5 GBDT常用損失函數

(1)對於分類演算法,其損失函數一般有對數損失函數和指數損失函數兩種。

a) 如果是指數損失函數,則損失函數表達式為

L(y,f(x)) = exp(-yf(x))

b) 如果是對數損失函數,分為二元分類和多元分類兩種

(2)對於回歸演算法,常用損失函數有如下4種。

a)均方差,這個是最常見的回歸損失函數。

L(y,f(x)) = (y-f(x))^{2}

b)絕對損失。

L(y,f(x)) = left| y-f(x) 
ight|

對應負梯度誤差為

sign(y_{i}-f(x_{i}))

c)Huber損失,它是均方差和絕對損失的折衷產物,對於遠離中心的異常點,採用絕對損失,而中心附近的點採用均方差。這個界限一般用分位數點度量。損失函數如下

d) 分位數損失。它對應的是分位數回歸的損失函數,表達式為

對於Huber損失和分位數損失,主要用於健壯回歸,也就是減少異常點對損失函數的影響。

6 GBDT正則化

對GBDT進行正則化,防止過擬合。GBDT的正則化主要有三種方式。

第一種是和Adaboost類似的正則化項,即步長(learning rate)。

定義為ν,對於前面的弱學習器的迭代

如果加上正則化項,則有

v的取值範圍為 0<vleq 1 .對於同樣的訓練集學習效果,較小的v意味著需要更多的弱學習器的迭代次數。通常用步長和迭代最大次數一起來決定演算法的擬合效果。

第二種正則化的方式是通過子採樣比例(subsample)。取值為(0,1]。

注意這裡的子採樣和隨機森林不一樣,隨機森林使用的是放回抽樣,而這裡是不放回抽樣。如果取值為1,則全部樣本都使用,等於沒有使用子採樣。如果取值小於1,則只有一部分樣本會去做GBDT的決策樹擬合。選擇小於1的比例可以減少方差,即防止過擬合,但是會增加樣本擬合的偏差,因此取值不能太低。推薦在[0.5, 0.8]之間。

使用了子採樣的GBDT有時也稱作隨機梯度提升樹(Stochastic Gradient Boosting Tree, SGBT)。由於使用了子採樣,程序可以通過採樣分發到不同的任務去做boosting的迭代過程,最後形成新樹,從而減少弱學習器難以並行學習的弱點。

第三種是對於弱學習器即CART回歸樹進行正則化剪枝

7 GBDT小結

目前GBDT的演算法比較好的庫是xgboost。scikit-learn也可以。

最後總結下GBDT的優缺點。

GBDT主要的優點有

(1)可以靈活處理各種類型的數據,包括連續值和離散值。

(2)在相對少的調參時間情況下,預測的準備率也可以比較高。這個是相對SVM來說的。

(3)使用一些健壯的損失函數,對異常值的魯棒性非常強。比如 Huber損失函數和Quantile損失函數。

GBDT的主要缺點有

由於弱學習器之間存在依賴關係,難以並行訓練數據。不過可以通過自採樣的SGBT來達到部分並行。

8 scikit-learn GBDT類庫概述

在sacikit-learn中,GradientBoostingClassifier為GBDT的分類類, 而GradientBoosting Regressor為GBDT的回歸類。兩者的參數類型完全相同,有些參數比如損失函數loss的可選擇項並不相同。這些參數中,類似於Adaboost,我們把重要參數分為兩類,第一類是Boosting框架的重要參數,第二類是弱學習器即CART回歸樹的重要參數。

9 GBDT類庫boosting框架參數

首先,我們來看boosting框架相關的重要參數。由於GradientBoostingClassifier和GradientBoostingRegressor的參數絕大部分相同,我們下面會一起來講,不同點會單獨指出。

(1) n_estimators: 也就是弱學習器的最大迭代次數,或者說最大的弱學習器的個數。一般來說n_estimators太小,容易欠擬合,n_estimators太大,又容易過擬合,一般選擇一個適中的數值。默認是100。在實際調參的過程中,我們常常將n_estimators和下面介紹的參數learning_rate一起考慮。

(2) learning_rate: 即每個弱學習器的權重縮減係數ν,也稱作步長,加上了正則化項,我們的強學習器的迭代公式為 f_{k}(x) = f_{k-1}(x) + v h_{k}(x) 。v的取值範圍為 0<vleq 1 .

對於同樣的訓練集擬合效果,較小的ν意味著我們需要更多的弱學習器的迭代次數。通常我們用步長和迭代最大次數一起來決定演算法的擬合效果。所以這兩個參數n_estimators和learning_rate要一起調參。一般來說,可以從一個小一點的ν開始調參,默認是1。

(3)subsample: 子採樣,取值為(0,1]。注意這裡的子採樣和隨機森林不一樣,隨機森林使用的是放回抽樣,而這裡是不放回抽樣。如果取值為1,則全部樣本都使用,等於沒有使用子採樣。如果取值小於1,則只有一部分樣本會去做GBDT的決策樹擬合。選擇小於1的比例可以減少方差,即防止過擬合,但是會增加樣本擬合的偏差,因此取值不能太低。推薦在[0.5, 0.8]之間,默認是1.0,即不使用子採樣。

(4)init: 即我們的初始化的時候的弱學習器,如果不輸入,則用訓練集樣本來做樣本集的初始化分類回歸預測。否則用init參數提供的學習器做初始化分類回歸預測。一般用在我們對數據有先驗知識,或者之前做過一些擬合的時候,如果沒有的話就不用管這個參數了。

(5)loss: 即我們GBDT演算法中的損失函數。分類模型和回歸模型的損失函數是不一樣的。

  對於分類模型,有對數似然損失函數"deviance"和指數損失函數"exponential"兩者輸入選擇。默認是對數似然損失函數"deviance"。一般來說,推薦使用默認的"deviance"。它對二元分離和多元分類各自都有比較好的優化。而指數損失函數等於把我們帶到了Adaboost演算法。

  對於回歸模型,有均方差"ls", 絕對損失"lad", Huber損失"huber"和分位數損失「quantile」。默認是均方差"ls"。一般來說,如果數據的噪音點不多,用默認的均方差"ls"比較好。如果是噪音點較多,則推薦用抗噪音的損失函數"huber"。而如果我們需要對訓練集進行分段預測的時候,則採用「quantile」。

(6)alpha:這個參數只有GradientBoostingRegressor有,當我們使用Huber損失"huber"和分位數損失「quantile」時,需要指定分位數的值。默認是0.9,如果噪音點較多,可以適當降低這個分位數的值。

10 GBDT類庫弱學習器參數

由於GBDT使用了CART回歸決策樹,因此它的參數基本來源於決策樹類,也就是說,和DecisionTreeClassifier和DecisionTreeRegressor的參數基本類似。

(1)劃分時考慮的最大特徵數max_features: 可以使用很多種類型的值,默認是"None",意味著劃分時考慮所有的特徵數;如果是"log2"意味著劃分時最多考慮 log_{2}N 個特徵;如果是 "sqrt"或者"auto"意味著劃分時最多考慮 sqrt{N} 個特徵。如果是整數,代表考慮的特徵絕對數。如果是浮點數,代表考慮特徵百分比,即考慮(百分比xN)取整後的特徵數。其中N為樣本總特徵數。一般來說,如果樣本特徵數不多,比如小於50,我們用默認的"None"就可以了,如果特徵數非常多,我們可以靈活使用剛才描述的其他取值來控制劃分時考慮的最大特徵數,以控制決策樹的生成時間。

(2)決策樹最大深度max_depth: 默認可以不輸入,如果不輸入的話,決策樹在建立子樹的時候不會限制子樹的深度。一般來說,數據少或者特徵少的時候可以不管這個值。如果模型樣本量多,特徵也多的情況下,推薦限制這個最大深度,具體的取值取決於數據的分布。常用的可以取值10-100之間。

(3)內部節點再劃分所需最小樣本數min_samples_split: 這個值限制了子樹繼續劃分的條件,如果某節點的樣本數少於min_samples_split,則不會繼續再嘗試選擇最優特徵來進行劃分。 默認是2.如果樣本量不大,不需要管這個值。如果樣本量數量級非常大,則推薦增大這個值。

(4)葉子節點最少樣本數min_samples_leaf: 這個值限制了葉子節點最少的樣本數,如果某葉子節點數目小於樣本數,則會和兄弟節點一起被剪枝。 默認是1,可以輸入最少的樣本數的整數,或者最少樣本數占樣本總數的百分比。如果樣本量不大,不需要管這個值。如果樣本量數量級非常大,則推薦增大這個值。

(5)葉子節點最小的樣本權重和min_weight_fraction_leaf:這個值限制了葉子節點所有樣本權重和的最小值,如果小於這個值,則會和兄弟節點一起被剪枝。 默認是0,就是不考慮權重問題。一般來說,如果我們有較多樣本有缺失值,或者分類樹樣本的分布類別偏差很大,就會引入樣本權重,這時我們就要注意這個值了。

(6)最大葉子節點數max_leaf_nodes: 通過限制最大葉子節點數,可以防止過擬合,默認是"None」,即不限制最大的葉子節點數。如果加了限制,演算法會建立在最大葉子節點數內最優的決策樹。如果特徵不多,可以不考慮這個值,但是如果特徵分成多的話,可以加以限制,具體的值可以通過交叉驗證得到。

(7)節點劃分最小不純度min_impurity_split: 這個值限制了決策樹的增長,如果某節點的不純度(基於基尼係數,均方差)小於這個閾值,則該節點不再生成子節點。即為葉子節點 。一般不推薦改動默認值1e-7。

11 GBDT調參實例

用一個二元分類的例子來講解下GBDT的調參。這個例子的數據有87000多行,單機跑會比較慢,下面的例子我只選擇了它的前面20000行。

首先,載入需要的類庫:

接著,把解壓的數據用下面的代碼載入,觀察數據的類別分布。

可以看到類別輸出如下,也就是類別0的佔大多數。

0 19680

1 320

得到訓練集,最後一列Disbursed是分類輸出。前面的所有列(不考慮ID列)都是樣本特徵。

不管任何參數,都用默認的,擬合數據:

輸出如下,可見擬合還可以,我們下面看看怎麼通過調參提高模型的泛化能力。

Accuracy : 0.9852AUC Score (Train): 0.900531

  首先我們從步長(learning rate)和迭代次數(n_estimators)入手。一般來說,開始選擇一個較小的步長來網格搜索最好的迭代次數。這裡,我們將步長初始值設置為0.1。對於迭代次數進行網格搜索如下:

輸出如下,可見最好的迭代次數是60。

([mean: 0.81285, std: 0.01967, params: {n_estimators: 20}, mean: 0.81438, std: 0.01947, params: {n_estimators: 30}, mean: 0.81451, std: 0.01933, params: {n_estimators: 40}, mean: 0.81618, std: 0.01848, params: {n_estimators: 50}, mean: 0.81751, std: 0.01736, params: {n_estimators: 60}, mean: 0.81547, std: 0.01900, params: {n_estimators: 70}, mean: 0.81299, std: 0.01860, params: {n_estimators: 80}], {n_estimators: 60}, 0.8175146087398375)

  找到了一個合適的迭代次數,現在我們開始對決策樹進行調參。首先我們對決策樹最大深度max_depth和內部節點再劃分所需最小樣本數min_samples_split進行網格搜索。

輸出如下,可見最好的最大樹深度是7,內部節點再劃分所需最小樣本數是300。

([mean: 0.81199, std: 0.02073, params: {min_samples_split: 100, max_depth: 3}, mean: 0.81267, std: 0.01985, params: {min_samples_split: 300, max_depth: 3}, mean: 0.81238, std: 0.01937, params: {min_samples_split: 500, max_depth: 3}, mean: 0.80925, std: 0.02051, params: {min_samples_split: 700, max_depth: 3}, mean: 0.81846, std: 0.01843, params: {min_samples_split: 100, max_depth: 5}, mean: 0.81630, std: 0.01810, params: {min_samples_split: 300, max_depth: 5}, mean: 0.81315, std: 0.01898, params: {min_samples_split: 500, max_depth: 5}, mean: 0.81262, std: 0.02090, params: {min_samples_split: 700, max_depth: 5}, mean: 0.81807, std: 0.02004, params: {min_samples_split: 100, max_depth: 7}, mean: 0.82137, std: 0.01733, params: {min_samples_split: 300, max_depth: 7}, mean: 0.81703, std: 0.01773, params: {min_samples_split: 500, max_depth: 7}, mean: 0.81383, std: 0.02327, params: {min_samples_split: 700, max_depth: 7}, mean: 0.81107, std: 0.02178, params: {min_samples_split: 100, max_depth: 9}, mean: 0.80944, std: 0.02612, params: {min_samples_split: 300, max_depth: 9}, mean: 0.81476, std: 0.01973, params: {min_samples_split: 500, max_depth: 9}, mean: 0.81601, std: 0.02576, params: {min_samples_split: 700, max_depth: 9}, mean: 0.81091, std: 0.02227, params: {min_samples_split: 100, max_depth: 11}, mean: 0.81309, std: 0.02696, params: {min_samples_split: 300, max_depth: 11}, mean: 0.81713, std: 0.02379, params: {min_samples_split: 500, max_depth: 11}, mean: 0.81347, std: 0.02702, params: {min_samples_split: 700, max_depth: 11}, mean: 0.81444, std: 0.01813, params: {min_samples_split: 100, max_depth: 13}, mean: 0.80825, std: 0.02291, params: {min_samples_split: 300, max_depth: 13}, mean: 0.81923, std: 0.01693, params: {min_samples_split: 500, max_depth: 13}, mean: 0.81382, std: 0.02258, params: {min_samples_split: 700, max_depth: 13}], {max_depth: 7, min_samples_split: 300}, 0.8213724275914632)   

  由於決策樹深度7是一個比較合理的值,我們把它定下來,對於內部節點再劃分所需最小樣本數min_samples_split,我們暫時不能一起定下來,因為這個還和決策樹其他的參數存在關聯。下面我們再對內部節點再劃分所需最小樣本數min_samples_split和葉子節點最少樣本數min_samples_leaf一起調參。

輸出結果如下,可見這個min_samples_split在邊界值,還有進一步調試小於邊界60的必要。由於這裡只是例子,所以大家可以自己下來用包含小於60的網格搜索來尋找合適的值。

([mean: 0.81828, std: 0.02251, params: {min_samples_split: 800, min_samples_leaf: 60}, mean: 0.81731, std: 0.02344, params: {min_samples_split: 1000, min_samples_leaf: 60}, mean: 0.82220, std: 0.02250, params: {min_samples_split: 1200, min_samples_leaf: 60}, mean: 0.81447, std: 0.02125, params: {min_samples_split: 1400, min_samples_leaf: 60}, mean: 0.81495, std: 0.01626, params: {min_samples_split: 1600, min_samples_leaf: 60}, mean: 0.81528, std: 0.02140, params: {min_samples_split: 1800, min_samples_leaf: 60}, mean: 0.81590, std: 0.02517, params: {min_samples_split: 800, min_samples_leaf: 70}, mean: 0.81573, std: 0.02207, params: {min_samples_split: 1000, min_samples_leaf: 70}, mean: 0.82021, std: 0.02521, params: {min_samples_split: 1200, min_samples_leaf: 70}, mean: 0.81512, std: 0.01995, params: {min_samples_split: 1400, min_samples_leaf: 70}, mean: 0.81395, std: 0.02081, params: {min_samples_split: 1600, min_samples_leaf: 70}, mean: 0.81587, std: 0.02082, params: {min_samples_split: 1800, min_samples_leaf: 70}, mean: 0.82064, std: 0.02698, params: {min_samples_split: 800, min_samples_leaf: 80}, mean: 0.81490, std: 0.02475, params: {min_samples_split: 1000, min_samples_leaf: 80}, mean: 0.82009, std: 0.02568, params: {min_samples_split: 1200, min_samples_leaf: 80}, mean: 0.81850, std: 0.02226, params: {min_samples_split: 1400, min_samples_leaf: 80}, mean: 0.81855, std: 0.02099, params: {min_samples_split: 1600, min_samples_leaf: 80}, mean: 0.81666, std: 0.02249, params: {min_samples_split: 1800, min_samples_leaf: 80}, mean: 0.81960, std: 0.02437, params: {min_samples_split: 800, min_samples_leaf: 90}, mean: 0.81560, std: 0.02235, params: {min_samples_split: 1000, min_samples_leaf: 90}, mean: 0.81936, std: 0.02542, params: {min_samples_split: 1200, min_samples_leaf: 90}, mean: 0.81362, std: 0.02254, params: {min_samples_split: 1400, min_samples_leaf: 90}, mean: 0.81429, std: 0.02417, params: {min_samples_split: 1600, min_samples_leaf: 90}, mean: 0.81299, std: 0.02262, params: {min_samples_split: 1800, min_samples_leaf: 90}, mean: 0.82000, std: 0.02511, params: {min_samples_split: 800, min_samples_leaf: 100}, mean: 0.82209, std: 0.01816, params: {min_samples_split: 1000, min_samples_leaf: 100}, mean: 0.81821, std: 0.02337, params: {min_samples_split: 1200, min_samples_leaf: 100}, mean: 0.81922, std: 0.02377, params: {min_samples_split: 1400, min_samples_leaf: 100}, mean: 0.81545, std: 0.02221, params: {min_samples_split: 1600, min_samples_leaf: 100}, mean: 0.81704, std: 0.02509, params: {min_samples_split: 1800, min_samples_leaf: 100}], {min_samples_leaf: 60, min_samples_split: 1200}, 0.8222032996697154)

  現在我們用新參數擬合數據:

輸出如下:

Accuracy : 0.984AUC Score (Train): 0.908099

  對比我們最開始完全不調參的擬合效果,可見精確度稍有下降,主要原理是我們使用了0.8的子採樣,20%的數據沒有參與擬合。

  現在我們再對最大特徵數max_features進行網格搜索。

輸出如下:

([mean: 0.82220, std: 0.02250, params: {max_features: 7}, mean: 0.82241, std: 0.02421, params: {max_features: 9}, mean: 0.82108, std: 0.02302, params: {max_features: 11}, mean: 0.82064, std: 0.01900, params: {max_features: 13}, mean: 0.82198, std: 0.01514, params: {max_features: 15}, mean: 0.81355, std: 0.02053, params: {max_features: 17}, mean: 0.81877, std: 0.01863, params: {max_features: 19}], {max_features: 9}, 0.822412506351626)

現在我們再對子採樣的比例進行網格搜索:

輸出如下:

([mean: 0.81828, std: 0.02392, params: {subsample: 0.6}, mean: 0.82344, std: 0.02708, params: {subsample: 0.7}, mean: 0.81673, std: 0.02196, params: {subsample: 0.75}, mean: 0.82241, std: 0.02421, params: {subsample: 0.8}, mean: 0.82285, std: 0.02446, params: {subsample: 0.85}, mean: 0.81738, std: 0.02236, params: {subsample: 0.9}], {subsample: 0.7}, 0.8234378969766262)

現在我們基本已經得到我們所有調優的參數結果了。這時我們可以減半步長,最大迭代次數加倍來增加我們模型的泛化能力。再次擬合我們的模型:

輸出如下:

Accuracy : 0.984AUC Score (Train): 0.905324

  可以看到AUC分數比起之前的版本稍有下降,這個原因是我們為了增加模型泛化能力,為防止過擬合而減半步長,最大迭代次數加倍,同時減小了子採樣的比例,從而減少了訓練集的擬合程度。

  下面我們繼續將步長縮小5倍,最大迭代次數增加5倍,繼續擬合我們的模型:

輸出如下,可見減小步長增加迭代次數可以在保證泛化能力的基礎上增加一些擬合程度。

Accuracy : 0.984AUC Score (Train): 0.908581

  最後我們繼續步長縮小一半,最大迭代次數增加2倍,擬合我們的模型:

輸出如下,此時由於步長實在太小,導致擬合效果反而變差,也就是說,步長不能設置的過小。

Accuracy : 0.984AUC Score (Train): 0.908232

以上就是GBDT調參的一個總結。


推薦閱讀:

GBDT與Adaboost的區別與聯繫
BAT機器學習面試1000題系列(286-290)
《DART:Dropouts meet Multiple Additive Regression Trees》
ML筆記 | 零基礎學懂機器學習(六)
即時配送的ETA問題之億級樣本特徵構造實踐

TAG:gbdt | 參數 | boosting |