連載|GBDT如何進行迴歸和分類

GBDT

在前幾年的機器學習競賽以及工作中,人們使用着各種傳統算法進行調參取得性能的提升,突然有一天殺出了一種名爲GBDT的算法,改變了當前的格局,該算法在不同的場景中總是能夠產生很好的效果,本文就讓我們來了解一下GBDT。

GBDT(Gradient Boost Decision Tree),中文名稱可以直譯爲“梯度提升決策樹”。要想弄明白GBDT具體是什麼我們就要弄明白這裏面的兩個詞語DT(Decision Tree)和GB(Gradient Boost)。

DT:CART迴歸樹

這裏需要注意的是我們使用的決策樹是CART迴歸樹,無論是我們要處理迴歸問題還是分類問題,我們都需要使用CART迴歸樹,主要是因爲我們的GBDT算法每次迭代要擬合的是梯度值,這是一個連續值,因此我們需要使用CART迴歸樹。

對於迴歸樹算法來說最重要的是尋找最佳的劃分點,那麼迴歸樹中的可劃分點包含了所有特徵的所有可取的值。在分類樹中最佳劃分點的判別標準是熵或者基尼係數,都是用純度來衡量的,但是在迴歸樹中的樣本標籤是連續數值,所以再使用熵之類的指標不再合適,取而代之的是平方誤差,它能很好的評判擬合程度。

關於CART迴歸樹的生成方式具體可以參考我們之前的文章:

GB:梯度提升

我們本文中提到的GBDT其實是提升樹(Boosting Tree)的一種改進算法,我們先來看一下BT是怎樣進行工作的。

Boosting Tree的流程

(1)初始化f0(x)=0f_0(x)=0

(2)對m=1,2,…,M

​ (a)計算殘差

rmi=yifm1(xi),i=1,2,...,Nr_{mi}=y_i-f_{m-1}(x_i),i=1,2,...,N

​ (b)擬合殘差rmir_{mi}學習一個迴歸樹,得到hm(x)h_m(x)

​ (c)更新fm(x)=fm1+hm(x)f_m(x)=f_{m-1}+h_m(x)

(3)得到迴歸問題提升樹

fM(x)=m=1Mhm(x)f_M(x)=\sum_{m=1}^Mh_m(x)

對於上面的流程中殘差又代表着什麼呢?

假設我們前一輪迭代得到的強學習器是:

ft1(x)f_{t-1}(x)

損失函數是:

L(y,ft1(x))L(y,f_{t-1}(x))

我們本輪迭代的目標是找到一個弱學習器:

ht(x)h_t(x)

使得本輪的損失函數最小化:

L(y,ft(x))=L(y,ft1(x)+ht(x))L(y,f_t(x))=L(y,f_{t-1}(x)+h_t(x))

此時的損失採用平方損失函數時:

L(y,ft1(x)+ht(x))L(y,f_{t-1}(x)+h_t(x))

=(yft1(x)ht(x))2=(y-f_{t-1}(x)-h_t(x))^2

=(rht(x))2=(r-h_t(x))^2

此時有殘差:

r=yft1(x)r=y-f_{t-1}(x)

舉個例子來表示一下殘差:

假設小明有100元,第一次我們用80元去擬合,此時的殘差就是20元,第二次我們用10元去擬合剩下的殘差(損失:即20元),此時的殘差是10元,依次類推我們每一次都去擬合剩下的殘差,對於提升樹來說我們把每一次擬合的錢數加起來就是模型最終的輸出結果了。

我們可以發現當我們使用損失函數爲平方損失的提升樹的時候,每一步的迭代過程是很簡單的,但是對於其他的損失函數來說就不能很好的進行每一步的優化了,針對這一問題,Freidman提出了梯度提升(Gradient Boosting)算法,利用最速下降法的近似方法,其關鍵是利用損失函數的負梯度在當前模型的值作爲迴歸問題提升樹算法中的殘差的近似值,擬合一個迴歸樹。

負梯度的表達形式如下:

[L(y,f(xi))f(xi)]f(x)=fm1(x)-[\frac{\partial L(y,f(x_i))}{\partial f(x_i)}]_{f(x)=f_{m-1}(x)}

GBDT迴歸算法的流程

輸入:訓練數據集T={(x1,y1),(x2,y2),...,(xN,yN)}T=\{(x_1,y_1),(x_2,y_2),...,(x_N,y_N)\}xiXRnx_i\in X \subseteq R^nyiYRy_i\in Y \subseteq R;損失函數L(y,f(x))L(y,f(x))

輸出:迴歸樹f^(x)\hat{f}(x)

(1)初始化弱學習器:

f0(x)=argminci=1NL(yi,c)f_0(x)=arg\underset{c}{min}\sum_{i=1}^NL(y_i,c)

(2)對m=1,2,…,M

​ (a)對i=1,2,…,N,計算負梯度(殘差):

rmi=[L(y,f(xi))f(xi)]f(x)=fm1(x)r_{mi}=-[\frac{\partial L(y,f(x_i))}{\partial f(x_i)}]_{f(x)=f_{m-1}(x)}

​ (b)將a中得到的殘差作爲新樣本的真實值,擬合一個迴歸樹,得到第m棵樹的葉子結點區域RmjR_{mj}j=1,2,...,Jj=1,2,...,J。其中JJ爲迴歸樹的葉子結點的個數。

​ (c)對j=1,2,...,Jj=1,2,...,J,計算最佳擬合值:

cmj=argmincxiRmjL(yi,fm1(xi)+c)c_{mj}=arg\underset{c}{min}\sum_{x_i\in R_{mj}}L(y_i,f_{m-1}(x_i)+c)

​ (d)更新強學習器

fm(x)=fm1(x)+j=1JcmjI(xRmj)f_m(x)=f_{m-1}(x)+\sum_{j=1}^Jc_{mj}I(x\in R_{mj})(I爲指示函數)

(3)得到最終的學習器

f^(x)=fM(x)=m=1Mj=1JcmjI(xRmj)\hat{f}(x)=f_M(x)=\sum_{m=1}^{M}\sum_{j=1}^{J}c_{mj}I(x\in R_{mj})

GBDT分類算法

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

解決這個問題的辦法主要有兩種,一種是利用指數損失函數,此時的GBDT也就退化成了Adaboost算法;另一種就是使用類似於邏輯迴歸的對數似然損失函數的方法。也就是說,我們用的是類別的預測概率值和真實概率值的差來擬合損失,下面就讓我們看一下在對數似然損失函數下的二分類和多分類的GBDT算法。

GBDT二分類算法

我們使用類似於邏輯迴歸的對數似然函數時,損失函數爲:

L(y,f(x))=log(1+exp(yf(x)))L(y,f(x))=log(1+exp(-yf(x)))y{1,+1}y\in\{-1,+1\}

則此時的負梯度誤差爲:

rmi=[L(y,f(xi))f(xi)]f(x)=fm1(x)=yi(1+exp(yif(xi)))r_{mi}=-[\frac{\partial L(y,f(x_i))}{\partial f(x_i)}]_{f(x)=f_{m-1}(x)}=\frac{y_i}{(1+exp(y_if(x_i)))}

對於生成的決策樹,我們各個葉子結點的最佳負梯度擬合值爲:

cmj=argmincxiRmjlog(1+exp(yi(fm1(xi)+c)))c_{mj}=arg\underset{c}{min}\sum_{x_i\in R_{mj}}log(1+exp(-y_i(f_{m-1}(x_i)+c)))

由於上式難以優化,我們一般使用近似值代替:

cmj=xiRmjrmixiRmjrmi(1rmi)c_{mj}=\frac{\sum_{x_i\in R_{mj}}r_{mi}}{\sum_{x_i\in R_{mj}}|r_{mi}|(1-|r_{mi}|)}

出了負梯度計算和葉子結點的最佳負梯度擬合的線性搜索,GBDT二元分類和GBDT迴歸算法過程相同。

GBDT多分類算法

假設類別爲K,則此時我們的對數似然損失函數爲:

L(y,f(x))=k=1kyklog(pk(x))L(y,f(x))=-\sum_{k=1}^ky_klog(p_k(x))

其中如果樣本輸出類別爲k,則yk=1y_k=1。第k類的概率pk(x)p_k(x)的表達式爲:

pk(x)=exp(fk(x))l=1kexp(fl(x))p_k(x)=\frac{exp(f_k(x))}{\sum_{l=1}^kexp(f_l(x))}

集合上兩式,我們可以計算出第t輪的第i個樣本對應類別l的負梯度誤差爲:

rmil=[L(y,f(xi))f(xi)]f(x)=fl,m1(x)=yilpl,m1(xi)r_{mil}=-[\frac{\partial L(y,f(x_i))}{\partial f(x_i)}]_{f(x)=f_{l,m-1}(x)}=y_{il}-p_{l,m-1}(x_i)

根據上式我們就能夠知道,這裏得到的負梯度的誤差其實就是真實概率和t-1輪預測概率的差值。

對於生成的決策樹,我們各個葉子結點的最佳負梯度擬合值爲:

cmjl=argmincjli=0mk=1kL(yk,fm1,l(x)+j=1JcjlI(xiRmjl))c_{mjl}=arg\underset{c_{jl}}{min}\sum_{i=0}^{m}\sum_{k=1}^kL(y_k,f_{m-1,l}(x)+\sum_{j=1}^{J}c_{jl}I(x_i\in R_{mjl}))

同理我們使用近似值代替:

cmjl=K1KxiRmjlrmilxiRmjlrmil(1rmil)c_{mjl}=\frac{K-1}{K}\frac{\sum_{x_i\in R_{mjl}}r_{mil}}{\sum_{x_i\in R_{mjl}}|r_{mil}|(1-|r_{mil}|)}

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

GBDT的過擬合

爲了防止過擬合問題的產生,我們也需要對GBDT採取一些措施,主要的方式有以下的三種:

  • 剪枝

剪枝是樹模型中常用的防止過擬合的方法,在GBDT中同樣適用。

  • 定義步長

我們把步長定義爲v,對於前面的弱學習器的迭代:

fk(x)=fk1(x)+hk(x)f_k(x)=f_{k-1}(x)+h_k(x)

如果我們加上了正則化項,則有:

fk(x)=fk1(x)+vhk(x)f_k(x)=f_{k-1}(x)+vh_k(x)

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

  • 子採樣比例

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

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

GBDT的優缺點

優點

  • 預測精度高;
  • 適合低維數據;
  • 能處理非線性數據;
  • 可以靈活處理各種類型的數據,包括連續值和離散值;
  • 在相對少的調參時間情況下,預測的準備率也可以比較高。這個是相對SVM來說的;
  • 使用一些健壯的損失函數,對異常值的魯棒性非常強。比如 Huber損失函數和Quantile損失函數;

缺點

  • 由於弱學習器之間存在依賴關係,難以並行訓練數據。不過可以通過自採樣的SGBT來達到部分並行;
  • 如果數據維度較高時會加大算法的計算複雜度。
    在這裏插入圖片描述
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章