XGBoost + Boosting 原理簡介

XGBoost原理簡介

1. 背景

今天聽了貪心學院主辦,李文哲老師主講的《XGBoost的技術剖析》直播,讓我對XGB的原理有了一些瞭解。於是我想寫一篇筆記整理一下聽課的內容。

老師講得挺通俗易懂的,不過由於XGB本身具有一定的複雜性,要看懂這篇筆記需要有如下的背景知識:

  1. 決策樹的原理
  2. 泰勒級數
  3. 損失函數
  4. 懲罰函數

如果對這些概念不太瞭解,推薦閱讀復旦大學邱錫鵬老師的開源書《神經網絡與深度學習》還有人民郵電出版社的《機器學習實戰》,泰勒級數可以參考高數課本和網絡資料。

2. Boosting

XGBoost 這個名字就能看出來,這個模型使用了 Boosting 的方法,那麼我們就來先了解一下 Boosting 它是個啥玩意兒。

Bagging vs Boosting

Figure 1. Bagging vs Boosting \text{Figure 1. Bagging vs Boosting}

老師的PPT中對比了 BaggingBoosting 兩種常用的集成學習方法。

  • Bagging:利用多個過擬合的弱學習器來獲得更好的效果。典型的算法有隨機森林。

  • Boosting:利用多個欠擬合的弱學習器來獲得更好的效果。典型的算法有GBDT/GBRT,Adaboost,XGBoost和LightGBM。

Boosting 本身在不同算法中的具體應用也不完全相同,而從 XGBoost 1論文 中我們能夠瞭解到,它主要借鑑了 GBDTBoosting 方法

爲了加深對 Boosting 的瞭解,我把 GBDT 2論文也找出來看了一下。

2.1. 建立映射

首先,我們通過公式(1)(1)建立從 x\mathbf{x}yy 的映射。

y^=F(x;{βm,am}1M)=m=1Mβmh(x;am)(1) \widehat{y} = F\left(\mathbf{x} ;\left\{\beta_{m}, \mathbf{a}_{m}\right\}_{1}^{M}\right)=\sum_{m=1}^{M} \beta_{m} h\left(\mathbf{x} ; \mathbf{a}_{m}\right) \tag{1}

這裏的 x\mathbf{x}am\mathbf{a}_{m} 用粗體顯示,表示它們都是向量,y^\widehat{y} 表示模型的預測值。

公式(1)(1)中的 h(x;am)h\left(\mathbf{x} ; \mathbf{a}_{m}\right) 表示一個個弱分類器, am\mathbf{a}_{m} 是弱分類器的參數,βm\beta_m 是其權重,{βm,am}1M\left\{\beta_{m}, \mathbf{a}_{m}\right\}_{1}^{M}am\mathbf{a}_{m}βm\beta_mMM 個組合。MM表示弱分類器的數量。

公式(1)(1)表示 GBDT 是通過對多個弱分類器結果進行線性加權求和從而求出最終結果的。

2.2. 計算參數

建立了x\mathbf{x}yy 的映射之後,我們就需要考慮如何去計算函數中的參數。

(βm,am)=argminβ,ai=1NL(yi,Fm1(xi)+βh(xi;a))(2) \left(\beta_{m}, \mathbf{a}_{m}\right)=\arg \min _{\beta, \mathbf{a}} \sum_{i=1}^{N} L\left(y_{i}, F_{m-1}\left(\mathbf{x}_{i}\right)+\beta h\left(\mathbf{x}_{i} ; \mathbf{a}\right)\right) \tag{2}

公式 (2)(2) 中,argminβ,a\displaystyle\arg \min _{\beta, \mathbf{a}} 表示使其右邊的表達式最小的 (β,a)(\beta, \mathbf{a}) 組合,L(yi,yi^)L(y_i, \hat{y_i}) 爲損失函數。

公式 (2)(2) 說明參數 (βm,am)\left(\beta_{m}, \mathbf{a}_{m}\right)是通過使得損失函數最小化計算出來的,具體如何計算就取決於我們使用什麼具體的損失函數和優化器了。

同時, 我們還可以推出公式 (3)(3)

Fm(x)=Fm1(x)+βmh(x;am)(3) F_{m}(\mathbf{x})=F_{m-1}(\mathbf{x})+\beta_{m} h\left(\mathbf{x} ; \mathbf{a}_{m}\right) \tag{3}

公式 (3)(3)Fm(x)F_{m}(\mathbf{x}) 是訓練完 mm 個弱分類器以後,模型的輸出結果。

公式 (3)(3) 說明 GBDT 在訓練每第 mm 個弱分類器時,我們需要先將前 m1m-1 個弱分類器的預測結果求和,從而獲得一個新的預測結果,在此基礎上對第 mm 個弱分類器進行訓練和預測。即新的弱分類器是在已有模型的殘差上進行訓練的。

可理解爲如下公式。

βmh(x;am)(yik=1m1βkh(x;ak))(4) \beta_{m} h\left(\mathbf{x} ; \mathbf{a}_{m}\right) \to (y_i - \sum_{k=1}^{m-1} \beta_{k} h\left(\mathbf{x} ; \mathbf{a}_{k}\right)) \tag{4}

即第 mm 個弱分類器的訓練目標是輸出趨近於 yiy_i 和 前m1m - 1 個弱分類器的結果之和的差值。

再結合老師PPT中的例子,應該就能夠很好地理解 Boosting 的作用。

Boost Tree

Figure 2. Boost Tree \text{Figure 2. Boost Tree}

Model Predict

Figure 3. Model Predict \text{Figure 3. Model Predict}

3. XGBoost的目標函數

瞭解了 Boosting 之後,我們就可以開始學習 XGBoost 了,首先從它的目標函數開始分析。

Object Function

Figure 4. Object Function \text{Figure 4. Object Function}

我們一般使用樹模型來作爲弱分類器,假設有 KK 顆樹,對第 ii 個輸入,它們的預測值爲 y^i\widehat{y}_i

y^i=k=1Kfk(xi),  fkF(5) \widehat{y}_{i}=\sum_{k=1}^{K} f_{k}\left(\mathbf{x}_{i}\right),\ \ f_{k} \in {\mathcal{F}} \tag{5}

公式 (5)(5)fk(xi)f_k(\mathbf{x}_i) 表示第 kk 顆樹對第 ii 個輸入向量的預測輸出。

XGBoost 的目標函數由損失函數和懲罰函數組成,這一點大多數機器學習模型都差不多。通過最小化損失函數來提高預測精度,引入懲罰函數來控制模型複雜度,防止過擬合。

Obj=i=1nl(yi,y^i)+k=1KΩ(fk)(6) Obj = \sum_{i = 1}^n {l(y_i, \widehat{y}_{i})} + \sum_{k = 1}^K \Omega (f_k) \tag{6}

公式 (6)(6) 中的 nn 表示輸入數據的總數目,我們的優化目標就是最小化目標函數。

minObj(7) \min Obj \tag{7}

4. 化簡目標函數

有了目標函數以後,我們還沒有好的辦法直接對它進行求解,還需要進行化簡。圖5是老師的PPT。

Additive Traning

Figure 5. Additive Traning \text{Figure 5. Additive Traning}

圖5的左半部分主要在解釋Additive Traning,和我們在 Boosting 部分提到的類似。我們主要關注右半部分的化簡過程。

通過將 y^i\widehat{y}_{i} 展開,去除常數項,可以將目標函數化簡爲

Obj=i=1nl(yi,y^i(k))+k=1KΩ(fk)=i=1nl(yi,y^i(k1)+fk(xi))+Ω(fk)(8) { \begin{aligned} Obj &= \sum_{i = 1}^n {l(y_i, \widehat{y}_{i}^{(k)})} + \sum_{k = 1}^K \Omega (f_k) & \\ &= \sum_{i = 1}^n {l(y_i, \widehat{y}_{i}^{(k-1)} + f_k(\mathbf{x}_i) )} + \Omega (f_k) & \\ \end{aligned} } \tag{8}

此處利用了公式 (5)(5)y^i(k)\widehat{y}_{i}^{(k)} 中前 k1k-1 項分離了出來。因爲前 k1k-1 項已經在各自的訓練過程中優化過了,在這裏可以視爲常數項,所以我們將懲罰函數中的前 k1k-1 項去除,僅考慮要優化的 fkf_k 部分。

5. 使用泰勒級數近似目標函數

儘管我們對目標函數進行了化簡,但直接對目標函數進行求解,運算的複雜度會非常高,所以我們選擇對目標函數進行二級泰勒展開,提高模型的訓練速度。

Taylor Expansion

Figure 6. Taylor Expansion \text{Figure 6. Taylor Expansion}

根據公式 (9)(9) 中的二級泰勒展開式。

f(x+Δx)f(x)+f(x)Δx+12f(x)Δx2(9) f(x + \Delta x) \approx f(x) + f'(x) \cdot \Delta x + \frac{1}{2} f''(x) \cdot \Delta x^2 \tag{9}

對目標函數進行展開:

Obj=i=1nl(yi,y^i(k1)+fk(xi))+Ω(fk)=i=1n[l(yi,y^(k1))+gifk(xi)+12hifk2(xi)]+Ω(fk)(10) { \begin{aligned} Obj &= \sum_{i = 1}^n {l(y_i, \widehat{y}_{i}^{(k-1)} + f_k(\mathbf{x}_i) )} + \Omega (f_k) & \\ &= \sum_{i=1}^{n}\left[l\left(y_{i}, \hat{y}^{(k-1)}\right)+g_{i} f_{k}\left(\mathbf{x}_{i}\right)+\frac{1}{2} h_{i} f_{k}^{2}\left(\mathbf{x}_{i}\right)\right]+\Omega\left(f_{k}\right) &\\ \end{aligned} } \tag{10}

其中 gi=y^(k1)l(yi,y^(k1))g_{i}=\partial_{\hat{y}(k-1)} l\left(y_{i}, \hat{y}^{(k-1)}\right)hi=y^(k1)2l(yi,y^(k1))h_{i}=\partial_{\hat{y}(k-1)}^{2} l\left(y_{i}, \hat{y}^{(k-1)}\right), 對應二級泰勒展開式中的一階導數和二階導數,由於它們都是基於前 k1k - 1 個模型的,所以在訓練第 kk 個模型時也是已知的,可以視爲常數項。

公式 (10)(10) 中,l(yi,y^(k1))l(y_{i}, \hat{y}^{(k-1)}) 也可視爲常數項,並且這一項沒有和變量 fk(xi)f_k(\mathbf{x}_i)相乘,所以我們可以將展開後的目標函數再次進行化簡,結果爲:

Obj=i=1n[gifk(xi)+12hifk2(xi)]+Ω(fk)(11) Obj =\sum_{i=1}^{n}\left[g_{i} f_{k}\left(\mathbf{x}_{i}\right)+\frac{1}{2} h_{i} f_{k}^{2}\left(\mathbf{x}_{i}\right)\right]+\Omega\left(f_{k}\right) \tag{11}

6. 模型參數化

在公式 (5)(5) 中 ,我們提到fk(xi)f_k(\mathbf{x}_i) 表示第 kk 顆樹對第 ii 個輸入向量的預測輸出。那麼我們又應該如何在公式中將 fk(xi)f_k(\mathbf{x}_i) 展開,從而進行訓練和調優,最終達到優化模型的目的呢。這裏我們就需要將模型參數化,將問題轉化爲參數優化的問題。

那麼我們這一節要解決的子問題就是,如何用參數的形式來表示一顆決策樹,或者說,如何將決策樹的模型參數化。

我們參考周志華老師《機器學習》 3 書中的一個例子。

清晰
稍糊
硬滑
軟粘
模糊
紋理
密度 <= 0.381?
壞瓜1
好瓜2
觸感=?
壞瓜3
好瓜4
壞瓜5

Figure 7. Decision Tree \text{Figure 7. Decision Tree}

y^i=1\widehat{y}_i = 1表示模型預測第 ii 個瓜爲好瓜,y^i=0\widehat{y}_i = 0表示模型預測第 ii 個瓜爲壞瓜。葉子節點標籤後的數字爲葉子節點的標號。

Ij={iq(xi)=j}I_j = \{i | q(\mathbf{x}_{i}) = j\} 爲被分到第 jj 個葉子節點中的 xi\mathbf{x}_{i} 的序號集合。q(xi)q(\mathbf{x}_{i}) 爲輸入 xi\mathbf{x}_{i}到葉子節點序號的映射。

wj=α(j)w_j = \alpha (j) 爲第 jj 個葉子節點的 y^\widehat{y} 值。取樣例數據進行說明:

Table 1. Sample Data \text{Table 1. Sample Data}

序號 紋理 觸感 密度 好瓜
1 清晰 硬滑 0.697
2 清晰 軟粘 0.267
3 稍糊 硬滑 0.091

fk(x1)=α(q(x1))=α(2)=1=w2fk(x2)=α(q(x2))=α(1)=0=w1fk(x3)=α(q(x3))=α(3)=0=w3 { \begin{aligned} f_k(\mathbf{x}_{1}) = \alpha (q(\mathbf{x}_{1})) =\alpha(2)=1 = w_2 & \\ f_k(\mathbf{x}_{2}) = \alpha (q(\mathbf{x}_{2})) =\alpha(1)=0 = w_1 & \\ f_k(\mathbf{x}_{3}) = \alpha (q(\mathbf{x}_{3})) =\alpha(3)=0 = w_3 & \\ \end{aligned} }


根據上面的定義,我們繼續對目標函數進行化簡。

首先展開懲罰函數:

Ω(f)=γT+12λw2(12) \Omega(f)=\gamma T+\frac{1}{2} \lambda\|w\|^{2} \tag{12}

Obj=i=1n[gifk(xi)+12hifk2(xi)]+γT+12λj=1Twj2(13) \begin{aligned} Obj &=\sum_{i=1}^{n}\left[g_{i} f_{k}\left(\mathbf{x}_{i}\right)+\frac{1}{2} h_{i} f_{k}^{2}\left(\mathbf{x}_{i}\right)\right]+\gamma T+\frac{1}{2} \lambda \sum_{j=1}^{T} w_{j}^{2}\\ \end{aligned} \tag{13}

公式 (12)(12)γ\gamma 爲樹的深度,TT 爲葉子節點個數,λ\lambda 爲懲罰項係數。w2\|w\|^{2} 爲L2正則化項。公式 (13)(13) 爲將懲罰函數帶入後的目標函數。

下面將fk(xi)f_{k}\left(\mathbf{x}_{i}\right) 從對每一項輸入數據的輸出求和,轉爲對每一個葉子節點的輸出求和。

Obj=j=1T[(iIjgi)wj+12(iIjhi+λ)wj2]+γT(14) Obj=\sum_{j=1}^{T}\left[\left(\sum_{i \in I_{j}} g_{i}\right) w_{j}+\frac{1}{2}\left(\sum_{i \in I_{j}} h_{i}+\lambda\right) w_{j}^{2}\right]+\gamma T \tag{14}

公式 (14)(14)Ij={iq(xi)=j}I_j = \{i | q(\mathbf{x}_{i}) = j\} 是被分到第 jj 個葉子節點中的 xi\mathbf{x}_{i} 的序號集合。

7. 尋找最佳分裂點

我們假設樹的結構 q(xi)q(\mathbf{x}_{i}) 是確定的,即公式 (13)(13) 中,γ\gammaTT 兩個參數是確定的,IjI_j 也是確定的,剩下的自變量就只有 wj2w_j^2,我們就得到了一個一元二次方程。

要使這個一元二次方程最小,我們就需要找到它的極值點。

首先考慮二次項係數的正負性。λ\lambda 是懲罰項係數,是非負的,而
hi=y^(k1)2l(yi,y^(k1))h_{i}=\partial_{\hat{y}(k-1)}^{2} l\left(y_{i}, \hat{y}^{(k-1)}\right),是損失函數的二階導數。

我們參考《神經網絡與深度學習》 4 中給出的常用損失函數。

Loss Function

Figure 8. Loss Function \text{Figure 8. Loss Function}

XGBoost 常用的是平方損失,它的二階導函數恆爲正數。所以目標函數二次項係數也恆爲正。

所以我們根據一元二次方程的性質,求解目標函數的最小值。

wj=iIjgiiIjhi+λ(15) w_{j}^{*}=-\frac{\sum_{i \in I_{j}} g_{i}}{\sum_{i \in I_{j}} h_{i}+\lambda} \tag{15}

帶入公式 (14)(14) 可求得

Obj(q)=12j=1T(iIjgi)2iIjhi+λ+γT(16) Obj(q)=-\frac{1}{2} \sum_{j=1}^{T} \frac{\left(\sum_{i \in I_{j}} g_{i}\right)^{2}}{\sum_{i \in I_{j}} h_{i}+\lambda}+\gamma T \tag{16}

公式 (16)(16)qq 爲某一確定的樹結構。Obj(q)Obj(q) 可以作爲評分函數,用來計算樹結構的得分。類似於決策樹模型中的信息熵(Information Entropy)。

由於遍歷所有的樹結構是一個 NPNP 問題,所以 XGBoost 採用了貪心算法來求得樹結構的局部最優解。

假設 ILI_LIRI_R 是分割後的左節點和右節點的xi\mathbf{x}_{i} 的序號集合,I=ILIRI = I_L \bigcup I_R,那麼每次分裂後 Obj(q)Obj(q) 的減少值爲:

Lsplit=12[(iILgi)2iILhi+λ+(iIRgi)2iIRhi+λ(iIgi)2iIhi+λ]γ(17) \mathcal{L}_{s p l i t}=\frac{1}{2}\left[\frac{\left(\sum_{i \in I_{L}} g_{i}\right)^{2}}{\sum_{i \in I_{L}} h_{i}+\lambda}+\frac{\left(\sum_{i \in I_{R}} g_{i}\right)^{2}}{\sum_{i \in I_{R}} h_{i}+\lambda}-\frac{\left(\sum_{i \in I} g_{i}\right)^{2}}{\sum_{i \in I} h_{i}+\lambda}\right]-\gamma \tag{17}

這個公式可以用來搜索最佳的分裂點,類似於決策樹中的信息增益(Information Gain)。

接下來的過程就和一般的決策樹訓練過程類似了,論文中也給了兩個搜索最佳分裂點的算法,我們就不做詳細討論了。

Algorithm 1

Figure 9. Algorithm 1 \text{Figure 9. Algorithm 1}

Algorithm 2

Figure 10. Algorithm 2 \text{Figure 10. Algorithm 2}

XGBoost 主要的內容大概就是這些,希望瞭解更加詳細內容的同學可以查看原始論文

8. 參考文獻

[1] T. Chen, C. Guestrin, Xgboost: A scalable tree boosting system, CoRR abs/1603.02754. arXiv:1603.02754.

[2] J. Friedman, Greedy function approximation: A gradient boosting machine, The Annals of Statistics 29. doi:10.1214/aos/1013203451.

[3] 周志華, 機器學習, no. 84-85, 清華大學出版社, 2016.

[4] 邱錫鵬, 神經網絡與深度學習, no. 74, Github, 2020.


聯繫郵箱:[email protected]

Github:https://github.com/CurrenWong

歡迎轉載/Star/Fork,有問題歡迎通過郵箱交流。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章