機器學習回顧篇(15):集成學習之GDBT

 

 

 

 

 

1 引言

梯度提高樹算法(Gradient Boosting Decision Tree,GBDT)是一個很是經典的機器學習算法,和咱們前面介紹過的Adaboost算法同樣,都是提高學習系列算法中的一員。從「梯度提高樹」這個算法名稱中咱們也能夠看出,這又是一個決策樹的集成算法,更進一步地說,這個算法是以CART決策樹算法做爲基學習算法的一種集成算法。對於CART決策樹算法,在以前的博客中已經有詳細的介紹,在閱讀本文以前請務必先理解CART決策樹算法。接下來,本文將會從提高樹開始,逐漸深刻的介紹GBDT算法。javascript

 

2 提高樹

關於提高樹,咱們能夠從字面上進行理解,能夠認爲提高樹就是一種以決策樹做爲基學習算法的一種提高學習算法,能夠用來解決分類問題,也能夠用於解決迴歸問題。當用於分類問題時,提高樹算法只需將AdaBoost算法中的基本學習器限制爲二類分類樹便可,能夠說這時的提高樹算法是AdaBoost算法的特殊狀況,本文再也不細述,且本文主要介紹的GBDT算法不管是在分類問題中仍是迴歸問題彙總,都是從迴歸提高樹的優化而來,因此下面敘述內容主要以迴歸提高樹爲主。
提高樹模型能夠看作是使用加法模型對決策樹的線性組合: $${f_M}(x) = \sum\limits_{m = 1}^M {T(x;{\Theta _m})} \tag {1}$$ 式中,${f_M}(x)$是提高樹的數學模型,$M$表示決策樹的數量,${T(x;{\Theta _m})}$表示第$m$棵決策樹,${{\Theta _m}}$表示決策樹的參數。對於參數${{\Theta _m}}$的集合$\Theta = \{ {\Theta _1},{\Theta _2}, \cdots ,{\Theta _M}\} $,咱們選取的準則是對於集合$D = \{ ({x_1},{y_1}),({x_2},{y_2}), \cdots ,({x_N},{y_N})\} $使得損失函數$\sum {L\left( {{y_i},{f_M}({x_i})} \right)} $最小化,即: $$\arg \mathop {\min }\limits_\Theta \sum\limits_{i = 1}^N {L\left( {{y_i},{f_M}({x_i})} \right)} = \arg \mathop {\min }\limits_\Theta \sum\limits_{i = 1}^N {L\left( {{y_i},\sum\limits_{m = 1}^M {T(x_i;{\Theta _m})} } \right)} \tag {2}$$ 在前面介紹Adaboost算法博文中,咱們說過,提高學習系列算法採用前向分步算法來迭代訓練個體學習器,提高樹固然也不例外,因此提高樹的迭代訓練過程能夠表示爲: $${f_m}(x) = {f_{m - 1}}(x) + T(x;{\Theta _m}),m = 1,2, \cdots ,M \tag {3}$$ 在這個迭代訓練過程當中,每一次迭代都訓練完成一顆新的決策樹${T(x;{\Theta _m})}$,在這一過程當中,也必須知足整體損失函數最小化,也就是說,對於第$m$次迭代所肯定的決策樹${T(x;{\Theta _m})}$的參數${{\Theta _m}}$有: $${{\hat \Theta }_m} = \arg \mathop {\min }\limits_\Theta \sum\limits_{i = 1}^N {L\left( {{y_i},{f_m}({x_i})} \right)} \tag {4}$$ 將式(3)代入式(4)中,有: $${{\hat \Theta }_m} = \arg \mathop {\min }\limits_\Theta \sum\limits_{i = 1}^N {L\left( {{y_i},{f_{m - 1}}({x_i}) + T({x_i};{\Theta _m})} \right)} \tag {5}$$css

在提高樹算法中,通常採用平方損失函數,因而: $$L\left( {{y_i},{f_{m - 1}}({x_i}) + T({x_i};{\Theta _m})} \right) = {\left[ {{y_i} - {f_{m - 1}}({x_i}) - T({x_i};{\Theta _m})} \right]^2} \tag {6}$$ 式(6)中,${{y_i} - {f_{m - 1}}({x_i})}$是上一輪迭代中預測值與真實值之間的誤差,這個誤差在提高樹中稱爲殘差,用${{r_{m,i}}}$表示,因而式(6)能夠表示爲: $$L\left( {{y_i},{f_{m - 1}}({x_i}) + T({x_i};{\Theta _m})} \right) = {\left[ {{r_{m,i}} - T({x_i};{\Theta _m})} \right]^2} \tag {7}$$ 這就是第$m$次迭代訓練第$m$棵決策樹時的損失函數。能夠看出,第$m$次迭代實際上是對上一次迭代的殘差進行擬合,而不是相似Adaboost算法中利用上一輪迭代中的偏差率來更新樣本權重,這就是提高樹算法與Adaboost算法的根本性區別。所以,每一次迭代結束後,提高樹算法使用訓練樣本$x_i$與當前的殘差${{r_{m,i}}}$組成新的訓練樣本集${\{ (xi,{r_{m,i}})\} _{i = 1,2, \cdots ,N}}$來做爲下一輪決策樹的訓練樣本集。
用一個例子來加深理解,假如要預測人的年齡,假設真實年齡爲30歲,第一棵決策樹預測結果爲20歲,那麼有10歲的殘差;第二棵樹對10歲的殘差進行擬合,輸出結果爲6歲,有4歲的殘差;第3棵樹繼續對4歲的殘差進行擬合……重複這個過程,知道最終的殘差在可接受範圍,最終的輸出結果是每一棵樹的預測結果之和。
總結一下提高樹的流程:
輸入:數據集$D = \{ ({x_1},{y_1}),({x_2},{y_2}), \cdots ,({x_N},{y_N})\} $
(1)初始化個體學習器${f_0}(x) = 0$;
(2)進行$M$次迭代,其中第$m$次迭代的具體過程以下:
       (a)針對數據集$D$中每個樣本$(x_i,y_i)$計算殘差${r_{m,i}} = {y_i} - {f_{m - 1}}({x_i})$;
       (b)利用${\{ (xi,{r_{m,i}})\} _{i = 1,2, \cdots ,N}}$來訓練一棵新的決策樹${T(x;{\Theta _m})}$;
       (c)更新組合:${f_m}(x) = {f_{m - 1}}(x) + T(x;{\Theta _m})$;
(3)對$M$次迭代得到的$M$棵決策樹進行集成,獲得最終的提高樹模型:${f_M}(x) = \sum\limits_{m = 1}^M {T(x;{\Theta _m})} $。html

上述過程當中,咱們使用的是平方偏差做爲損失函數,這時候對殘差的計算會比較簡單,可是在不少狀況下,咱們可能會使用其餘的損失函數,這時候對殘差的計算就變得複雜起來。爲了更好地解決這一問題這一問題,也就有了梯度提高樹。html5

 

3 梯度提高樹

從梯度提高樹這個算法的名稱,咱們容易想到梯度降低法,在我看來,梯度提高樹中確實也應用了梯度降低法的思想,在梯度降低法中是對模型的權重參數進行擬合,而在梯度提高樹中,是將整個決策樹模型做爲參數進行擬合,能夠證實,模型對梯度的負方向進行擬合,總能達到收斂的目的,並且是近似最速的方向,根據這一思想,Fredman提出了梯度提高算法,梯度提高法的核心思想就是利用損失函數的負梯度在當前模型的具體值來替代提高樹算法中的殘差來擬合一棵迴歸樹,使得提高樹思想在更加通常化的損失函數中也能快速優化求解,具備更高的適用性。
梯度提高法與提高樹算法的結合,就是本篇的主角——梯度提高樹算法。須要注意的是,在梯度提高樹中,不管是用於迴歸問題仍是分類問題,所使用的的基學習算法都是CART迴歸樹,區別在於所使用的的損失函數有所區別。
下面分別介紹梯度提高樹是如何解決迴歸問題和分類問題的。java

3.1 迴歸問題

先來看看梯度提高樹算法在解決迴歸問題時的步驟流程。
輸入:數據集$D = \{ ({x_1},{y_1}),({x_2},{y_2}), \cdots ,({x_N},{y_N})\} $
(1)初始化個體學習器 $${f_0}(x) = \arg \mathop {\min }\limits_c \sum\limits_{i = 1}^N {L\left( {{y_i},c} \right)} $$
(2)進行$M$次迭代,其中第$m$次迭代的具體過程以下:
       (a)針對數據集$D$中每個樣本$(x_i,y_i)$計算負梯度在當前模型的值: $${r_{m,i}} = - {\left[ {\frac{{\partial L\left( {{y_i},f({x_i})} \right)}}{{\partial f({x_i})}}} \right]_{f(x) = {f_{m - 1}}(x)}}$$        (b)利用${\{ (xi,{r_{m,i}})\} _{i = 1,2, \cdots ,N}}$來訓練一棵新的迴歸樹$T({x_i};{\Theta _m}) = \sum\limits_{j = 1}^J {{c_{m,j}}I(x \in {R_{m,j}})} $;
       (c)對迴歸樹${T(x;{\Theta _m})}$肯定其每個葉節點${R_{m,j}},j = 1,2, \cdots ,J$上的最優輸出值${c_{m,j}}$:node

$${c_{m,j}} = \arg \min \sum\limits_{{x_i} \in {R_{m,j}}} {L\left( {{y_i},{f_{m - 1}}({x_i}) + c} \right)} $$

       (d)更新組合:${f_m}(x) = {f_{m - 1}}(x) + \sum\limits_{j = 1}^J {{c_{m,j}}I(x \in {R_{m,j}})} $;
(3)對$M$次迭代得到的$M$棵決策樹進行集成,獲得最終的提高樹模型:${f_M}(x) = \sum\limits_{m = 1}^M {\sum\limits_{j = 1}^J {{c_{m,j}}I(x \in {R_{m,j}})} } $。python

對比第2章節中的提高樹與本節講的梯度提高樹流程,能夠發現,主要的區別就在於在提高提高樹中使用負梯度進行擬合而再也不是殘差。另外,因爲在梯度提高樹中損失函數不在限制於平方損失函數,所以在步驟(2)(c)中肯定每個葉節點上樣本輸出時,須要結合實際使用的損失函數來進行肯定,例如當使用平方損失函數時,葉節點上的輸出值是該節點全部樣本的均值,當使用絕對值損失函數時,輸出值爲該節點樣本的中位數。jquery

3.2 分類問題

不管是分類問題仍是迴歸問題,本質都是對損失函數進行優化,區別就在於使用何種損失函數。在多數分類算法中,損失函數都是使用最大似然估計來構造,也包括本文的梯度提高樹。linux

 

(1)二分類問題
在二分類問題中,損失函數爲:
$$L(y,f(x)) = \log \left( {1 + \exp ( - yf(x)} \right) \tag {8}$$ 對式(8)進行求導,可得負梯度: $${r_{mi}} = - {\left[ {\frac{{\partial L({y_i},f({x_i}))}}{{\partial f({x_i})}}} \right]_{f(x) = {f_{m - 1}}(x)}} = \frac{{{y_i}}}{{1 + \exp \left( {{y_i}f({x_i})} \right)}} \tag {9}$$ 在每一次迭代構建一棵決策樹時,都須要肯定在每個分支節點上的最優輸出值。第$m$棵決策樹的第$j$個節點輸出值爲:
$${c_{mj}} = \arg \mathop {\min }\limits_c \sum\limits_{{x_i} \in {R_{mj}}} {\log \left( {1 + \exp ( - {y_i}({f_{m - 1}}({x_i}) + c))} \right)} \tag {10}$$ 通常而言,因爲式(10)計算量比較大,難以優化,因此更可能是經過下式來代替式(10):
$${c_{mj}} = \frac{{\sum\limits_{{x_i} \in {R_{mj}}} {{r_{mi}}} }}{{\sum\limits_{{x_i} \in {R_{mj}}} {\frac{{|{r_{mi}}|}}{{1 - |{r_{mi}}|}}} }} \tag {11}$$ 總結一下在二分類問題上,梯度提高樹算法流程:
輸入:數據集$D = \{ ({x_1},{y_1}),({x_2},{y_2}), \cdots ,({x_N},{y_N})\} $ ,其中${y_i} \in \{ - 1, + 1\} $
(1)初始化個體學習器 $${f_0}(x) = \arg \mathop {\min }\limits_c \sum\limits_{i = 1}^N {L\left( {{y_i},p} \right)} $$
(2)進行$M$次迭代,其中第$m$次迭代的具體過程以下:
       (a)針對數據集$D$中每個樣本$(x_i,y_i)$根據式(9)計算負梯度在當前模型的值${r_{mi}}$;
       (b)利用${\{ (x_i,{r_{mi}})\} _{i = 1,2, \cdots ,N}}$來訓練一棵新的迴歸樹$T({x_i};{\Theta _m}) = \sum\limits_{j = 1}^J {{c_{m,j}}I(x \in {R_{mj}})} $;
       (c)對迴歸樹${T(x;{\Theta _m})}$利用式(10)或者式(11)肯定其每個葉節點${R_{mj}},j = 1,2, \cdots ,J$上的最優輸出值${c_{mj}}$;
       (d)更新組合:${f_m}(x) = {f_{m - 1}}(x) + \sum\limits_{j = 1}^J {{c_{m,j}}I(x \in {R_{mj}})} $;
(3)對$M$次迭代得到的$M$棵決策樹進行集成,獲得最終的提高樹模型:${f_M}(x) = \sum\limits_{m = 1}^M {\sum\limits_{j = 1}^J {{c_{m,j}}I(x \in {R_{m,j}})} } $;
能夠看出,出了負梯度計算和肯定葉節點輸出值外,其餘全部過程基本是和迴歸問題中的流程是同樣的。android

 

(2)多分類問題 梯度提高樹算法在處理多分類問題時過程要比處理二分類問題複雜一些。假設數據集樣本類別數量爲$K$,則梯度提高樹算法中損失函數能夠表示爲:
$$L(y,f(x)) = - \sum\limits_{k = 1}^K {{y_k}\log {p_k}(x)} \tag {12}$$ 其中,$p_k(x)$爲樣本$x$屬於第$k$類的機率,有: $${p_k}(x){\text{ = }}\frac{{\exp \left( {{f_k}(x)} \right)}}{{\sum\limits_{l = 1}^K {\exp \left( {{f_l}(x)} \right)} }} \tag {13}$$ 結合式(12)(13)進行求導可得在第$m$次迭代時,第$i$個樣本在類別$l$上的負梯度爲:
$${r_{mil}} = - {\left[ {\frac{{\partial L({y_i},f({x_i}))}}{{\partial f({x_i})}}} \right]_{{f_k}(x) = {f_{l,m - 1}}(x)}} = {y_{il}} - {p_{l,m - 1}}({x_i}) \tag{14}$$ 從式(14)能夠看出,負梯度其實就是真實值與預測機率的差值。
肯定每個樹節點的輸出值:
$${c_{mjl}} = \arg \mathop {\min }\limits_{{c_{jl}}} \sum\limits_{i = 0}^m {\sum\limits_{k = 1}^K {L\left( {{y_k},{f_{m - 1}}_{,l}(x) + \sum\limits_{j = 0}^J {{c_{jl}}I({x_i} \in {R_{mjl}}} } \right)} } \tag {15}$$ 對於式(15),也有一個更加簡化的計算用於替代:
$${c_{mjl}} = \frac{{K - 1}}{K}\frac{{\sum\limits_{{x_i} \in {R_{mjl}}} {{r_{mil}}} }}{{\sum\limits_{{x_i} \in {R_{mil}}} {|{r_{mil}}|} (1 - |{r_{mil}}|)}} \tag {16}$$ 明白這些,就能夠來梳理一下在多分類問題中,梯度提高樹算法流程。
輸入:數據集$D = \{ ({x_1},{y_1}),({x_2},{y_2}), \cdots ,({x_N},{y_N})\} $
(1)初始化個體學習器 $${f_{k0}} = 0,k = 1,2, \ldots ,K$$ (2)進行$M$次迭代,其中第$m$次迭代的具體過程以下:
       (a)經過式(13)計算樣本點屬於每個類別的機率;
       (b) 對$k = 1,2, \ldots ,K$進行迭代:
              1)經過式(14)計算負梯度;
              2)利用負梯度$\{ ({x_1},{r_{k1}}), \cdots ,({x_N},{r_{kN}})\} $擬合一棵決策樹;
              3)使用式(15)或(16)肯定決策樹每個節點上的輸出值;
              4)更新組合:${f_{mk}}(x) = {f_{m - 1,k}}(x) + \sum\limits_{j = 1}^J {{c_{mkj}}I(x \in {R_{mkj}})} $;
       (c)對迴歸樹${T(x;{\Theta _m})}$利用式(10)或者式(11)肯定其每個葉節點${R_{mj}},j = 1,2, \cdots ,J$上的最優輸出值${c_{mj}}$;
       (d)更新組合:${f_m}(x) = {f_{m - 1}}(x) + \sum\limits_{j = 1}^J {{c_{m,j}}I(x \in {R_{mj}})} $;
(3)獲得最終的提高樹模型:${f_{Mk}}(x) = \sum\limits_{m = 1}^M {\sum\limits_{j = 1}^J {{c_{mkj}}I(x \in {R_{mkj}})} } $。
縱觀整個過程,其實不管是迴歸問題、二分類問題仍是如今說的多分類問題,思路和流程都是基本同樣的。對於多分類問題,區別就在於對每個類別都須要單獨創建一棵決策樹。上面的描述可能還不夠直觀,下面經過更加直白的描述來進一步分析多分類問題中的梯度提高樹算法。
假設咱們如今須要分類的數據集有3個類別標籤,即$k=3$,分別用$(A, B, C)$表示。在正式開始訓練以前,咱們須要對每一個樣本的類別標籤進行獨熱編碼轉換爲向量的形式,例如,某個屬於第二個分類樣本$X=(x, B)$獨熱編碼轉換後類別能夠用向量表示爲[0, 1, 0],咱們能夠將向量每個維度看作是屬於對應類別的機率,即第一位和第三位的0分別表示該樣本屬於第一個類別和第三類別的機率爲0,第二位上的1表示該樣本屬於第二類的機率爲1,這樣的話能夠方便得將樣本$X$拆分爲3個樣本:
$X_1=(x, 0)$表示樣本$x$屬於第1類的機率;
$X_2=(x, 1)$表示樣本$x$屬於第2類的機率;
$X_3=(x, 0)$表示樣本$x$屬於第3類的機率。

 

用這三個樣本,咱們能夠去訓練三棵迴歸樹,假設三棵樹的擬合值分別爲${f_1}(x)$、${f_2}(x)$、${f_3}(x)$,經過式(13)能夠將擬合值轉換爲屬於三個類別的機率$p_1$、$p_2$、$p_3$,再經過式(14)求負梯度,即:
$${r_{111}} = 0 - {p_1}$$ $${r_{112}} = 0 - {p_2}$$ $${r_{113}} = 0 - {p_3}$$ 有了負梯度以後,能夠繼續第二輪訓練,第二輪訓練時在第一輪的基礎上繼續訓練三棵樹,新的三棵樹分別用$(x,{r_{111}}$、$(x,{r_{112}}$、$(x,{r_{113}}$進行訓練。這一過程重複迭代$M$次,每次得到3棵決策樹。最終咱們能夠得到三個樹的集成,每一個集成樹的最終輸出都對應一個類別的輸出。

 

4 總結

In [ ]:
相關文章
相關標籤/搜索