# Gradient Boosting
:::warning
:notebook_with_decorative_cover: **摘要**
[toc]
:::
# 簡介
:::danger
**注意**
此篇筆記是嘗試將 Gradient Boosting 那些艱澀難懂的數學式,應用在實際例子上(迴歸與分類),建議先看參考資料,瞭解什麼是 Gradient Boosting 再來看這篇會比較有心得(吧
:::
### STEP 0-定義損失函數並推導其梯度
根據任務性質,定義個可微分的損失函數:
:::success
**重點**
$$
\large
L\big(y,~h(x)\big)
$$
:::
給定已經定義好的損失函數,推導其在 $h(x)$ 的梯度(gradient):
:::success
**重點**
$$
\large
\frac{\partial }{\partial h(x)} L\big(y,~h(x)\big)
$$
:::
### STEP 1-初始化基準模型
初始化第 $0$ 個模型 $h_0(x)$,通常稱為 base learner。該模型很簡單,不論輸入什麼,它只輸出一個固定值 $\gamma$。而該值必須最小化總樣本損失:
:::success
**重點**
$$
\large
h_0(x)=\mathop{\arg\min}\limits_{\gamma}\sum_{n=1}^N L(y_n,\gamma)
$$
:::
實際上,我們會將損失函數在 $\gamma$ 的梯度加總起來並設為 $0$,推導出 $\gamma$:
:::success
**重點**
$$
\large
\sum_{n=1}^N \frac{\partial }{\partial \gamma} L\big(y_n,~\gamma\big) = 0
$$
:::
### STEP 2-依序建立 T 個模型
初始化好基準模型後,接下來就是依序建立 $T$ 個模型,疊加在前個模型之上。以下的步驟都是給定我們正在建立第 $t$ 個模型。
#### STEP 2.1-計算樣本負梯度(虛擬殘差)
給定前個模型 $h_{t-1}(x)$,計算每個樣本的負梯度 $r_{tn}$:
:::success
**重點**
$$
r_{tn}=-\Bigg[\frac{\partial }{\partial h(x_n)} L\big(y_n,~h(x_n)\big) \Bigg]_{h(x)=h_{t-1}(x)}~~\forall~~n=1,~\dots,~N
$$
:::
$r_{tn}$ 通常又被稱為虛擬殘差(pseudo residual),後續的實際例子會更瞭解其內涵。
#### STEP 2.2-根據樣本負梯度(虛擬殘差)建立模型
以輔助資料集 $\{(x_n,~r_{tn})\}_{n=1}^{N}$ ,建立第 $t$ 個模型 $h_t(x)$,用來預測虛擬殘差 $r_{tn}$。如此一來,該模型就正朝著正確的方向更新其輸出值了。
#### STEP 2.3-計算模型輸出值
假設模型訓練完成後會有 $K_t$ 個葉節點 $\{R_{tk}\}_{k=1}^{K_t}$。那麼接下來就是計算這些葉節點的輸出應該要是多少。計算每個葉節點的輸出值 $\gamma_{tk}$,負責預測 $r_{tn}$:
:::success
**重點**
$$
\gamma_{tk}=\mathop{\arg\min}\limits_{\gamma}\sum_{x_n~\in~R_{tk}}L\big(y_n,~h_{t-1}(x_n)+\gamma\big)~~\forall~~k=1,~\dots,~K_t
$$
:::
實際上,我們會將損失函數在 $\gamma_{tk}$ 的梯度加總起來並設為 $0$,推導出 $\gamma_{tk}$:
:::success
**重點**
$$
\sum_{x_n~\in~R_{tk}} \frac{\partial}{\partial \gamma_{tk}}L\big(y_n,~h_{t-1}(x_n)+\gamma_{tk}\big)=0 ~~\forall~~ k=1 ,~\dots,~K_t
$$
:::
#### STEP 2.4-更新模型
:::success
**重點**
$$
h_t(x) = h_{t-1}(x) + \nu\sum_{k=1}^{K_t}\gamma_{tk} I\big[x \in R_{tk}\big]
$$
:::
### STEP 3-產出最終模型
:::success
**重點**
$$
H(x)
$$
:::
# 迴歸(Regression)任務
目前還沒整理,但[這篇文章](https://medium.com/@cwchang/gradient-boosting-%E7%B0%A1%E4%BB%8B-f3a578ae7205)已經有很完整的介紹了。
<font size='2'>**STEP 0-定義損失函數並推導其梯度**</font>
<font size='2'>**STEP 1-初始化基準模型**</font>
<font size='2'>**STEP 2-依序建立 T 個模型**</font>
<font size='0.8'>**STEP 2.1-計算樣本負梯度(虛擬殘差)**</font>
<font size='0.8'>**STEP 2.2-根據樣本負梯度(虛擬殘差)建立模型**</font>
<font size='0.8'>**STEP 2.3-計算模型輸出值**</font>
<font size='0.8'>**STEP 2.4-更新模型**</font>
<font size='2'>**STEP 3-產出最終模型**</font>
**STEP 3-產出最終模型**
# 分類(Classification)任務
在分類任務中使用梯度提升樹,會借用到 Logistic 迴歸的理論。
<font size='2'>**STEP 0-定義損失函數並推導其梯度**</font>
首先,分類任務的梯度提升樹的損失函數定義如下:
:::success
**重點**
$$
\large
L(y,h(x)) = -\Bigg(y \log\Big(\sigma\big(h(x)\big)\Big)+(1-y)\log\Big(1-\sigma\big(h(x)\big)\Big)\Bigg)
$$
:::spoiler 其中
$$
\large
\sigma(z)=\frac{1}{1+e^{-z}}
$$
:::
可以看得出來,就是 Logistic 迴歸的 negative log likelihood。
實際上,上述損失函數也可以簡化為以下兩種形式(省略推導過程):
$$
\large
\begin{align}
L(y,h(x))
&= -\Big( (y-1)h(x) - \log\big(1+e^{-h(x)}\big)\Big) \\
&= - \Big(y \cdot h(x)-\log\big( 1+e^{h(x)} \big)\Big)
\end{align}
$$
透過簡化過後的損失函數,我們可以更容易推導出其在 $h(x)$ 的梯度(省略推導過程):
:::success
**重點**
$$
\large
\begin{align}
\frac{\partial}{\partial h(x)}L\big(y,~h(x)\big)
&= -\Big( y-\frac{1}{1+e^{-h(x)}} \Big) \\
&=-\Big( y-\sigma\big(h(x)\big) \Big)
\end{align}
$$
:::
可以觀察到,結果是實際值($0$ 或 $1$)減去預測機率值(介於 $0$ 到 $1$)再加上負號。
<font size='2'>**STEP 1-初始化基準模型**</font>
初始化基準模型 $h_0(x)$:
$$
\begin{align}
h_0(x)
&= \mathop{\arg\min}\limits_{\gamma} \sum_{n=1}^N L(y_n,\gamma) \\
&= \mathop{\arg\min}\limits_{\gamma} \sum_{n=1}^N - \Big(y_n \cdot \gamma-\log\big( 1+e^{\gamma} \big)\Big)
\end{align}
$$
實際上,我們會將損失函數在 $\gamma$ 的梯度加總起來並設為 $0$,推導出 $\gamma$:
$$
\begin{align}
& \sum_{n=1}^N \frac{\partial }{\partial \gamma} L\big(y_n,~\gamma\big) = 0 \\
\implies & \sum_{n=1}^N -\Big( y_n-\sigma\big(\gamma\big) \Big)=0
\end{align}
$$
:::success
**重點**
$$
\large
\gamma=-\log \big(\tfrac{N-\sum y_n}{\sum y_n}\big)=-\log(\text{odds})
$$
:::
可以看到,最小化損失函數的基準模型,固定會輸出 $-\log(\text{odds})$,非常容易計算。
<font size='2'>**STEP 2-依序建立 T 個模型**</font>
初始化好基準模型後,接下來就是依序建立 $T$ 個模型,疊加在前個模型之上。以下的步驟都是給定我們正在建立第 $t$ 個模型。
<font size='0.8'>**STEP 2.1-計算樣本負梯度(虛擬殘差)**</font>
第一步就是計算每個樣本的虛擬殘差,定義如下:
$$
r_{tn} = -\Bigg[\frac{\partial }{\partial h(x_n)} L\big(y_n,~h(x_n)\big) \Bigg]_{h(x)=h_{t-1}(x)}~~\forall~~n=1,~\dots,~N
$$
推導後結果如下所示:
:::success
**重點**
$$
\large
r_{tn} = y_n-\sigma\big(h_{t-1}(x_n)\big) ~~\forall~~n=1,~\dots,~N
$$
:::
$r_{tn}$ 為實際值減去前個模型 $h_{t-1}(x)$ 的預測機率值,可以理解成殘差(residual),但通常被稱為虛擬殘差(pseudo residual),因為會隨著不同的損失函數而變,有時候可能並沒有這麼好的直覺。
<font size='0.8'>**STEP 2.2-根據樣本負梯度(虛擬殘差)建立模型**</font>
以輔助資料集 $\{(x_n,~r_{tn})\}_{n=1}^{N}$ ,建立第 $t$ 個模型 $h_t(x)$,用來預測虛擬殘差 $r_{tn}$。如此一來,該模型就能朝著正確的方向更新其輸出值了。
<font size='0.8'>**STEP 2.3-計算模型輸出值**</font>
假設訓練完成後會有 $K_t$ 個葉節點 $\{R_{tk}\}_{k=1}^{K_t}$。接下來就是計算每個葉節點的輸出值 $\gamma_{tk}$,負責預測 $r_{tn}$:
$$
\gamma_{tk}
= \mathop{\arg\min}\limits_{\gamma} \sum_{x_n~\in~R_{tk}} L\big(y_n,~h_{t-1}(x_n)+\gamma\big)~~\forall~~k=1,~\dots,~K_t
$$
這裡我們並不會「直接」將上述的損失函數在 $\gamma$ 的梯度加總起來並設為 $0$,推導出 $\gamma_{tk}$,如果這麼做,式子將會變得很複雜。
取而代之的是,我們會先將損失函數以二階泰勒公式展開:
:::success
**重點**
$$
L\big(y,~h(x)+\gamma\big) \approx L\big( y,~h(x) \big) + \frac{\partial}{\partial h(x)}L\big( y,~h(x) \big)\gamma + \frac{1}{2}\frac{\partial^2}{\partial h(x)^2}L\big( y,~h(x) \big)\gamma^2
$$
:::
接著,再求展開後的損失函數在 $\gamma$ 的梯度:
:::success
**重點**
$$
\frac{\partial}{\partial \gamma}L\big(y,~h(x)+\gamma\big) \approx \frac{\partial}{\partial h(x)}L\big( y,~h(x) \big) + \frac{\partial^2}{\partial h(x)^2} L\big( y,~h(x) \big)\gamma
$$
:::
再來,才跟過去一樣,將損失函數在 $\gamma_{tk}$ 的梯度加總起來並設為 $0$,推導出 $\gamma_{tk}$:
$$
\begin{align}
& \sum_{x_n~\in~R_{tk}} \frac{\partial}{\partial \gamma_{tk}}L\big(y_n,~h_{t-1}(x_n)+\gamma_{tk}\big)=0 ~~\forall~~ k=1 ,~\dots,~K_t \\
\implies & \cdots\cdots\cdots \\
\implies & \gamma_{tk}=\frac{-\sum_{x_n \in R_{tk}} \Big(\tfrac{\partial}{\partial h_{t-1}(x_n)}L\big(y_n,~h_{t-1}(x_n)\big)\Big)}{\sum_{x_n \in R_{tk}} \Big(\tfrac{\partial^2}{\partial h_{t-1}(x_n)^2} L\big( y_n,~h_{t-1}(x_n) \big)\Big)}~~\forall~~k=1,~\dots,~K_t \\
\implies & \cdots\cdots\cdots
\end{align}
$$
:::success
**重點**
$$
\large
\gamma_{tk}=\frac{\sum_{x_n \in R_{tk}} r_{tn}}{\sum_{x_n \in R_{tk}}\Big[ \sigma(h_{t-1}(x_n)) \cdot \big(1-\sigma(h_{t-1}(x_n))\big) \Big]}~~\forall~~k=1,~\dots,~K_t
$$
:::
將損失函數經由泰勒公式展開後,能簡化 $\gamma_{tk}$ 的計算,結果也相當容易理解,分子是樣本的虛擬殘差相加,而分母則是樣本在前個模型的「預測成功機率值」乘上「預測失敗機率值」,再相加。
<font size='0.8'>**STEP 2.4-更新模型**</font>
:::success
**重點**
$$
\large
h_t(x) = h_{t-1}(x) + \nu\sum_{k=1}^{K_t}\gamma_{tk} I\big[x \in R_{tk}\big]
$$
:::
<font size='2'>**STEP 3-產出最終模型**</font>
:::success
**重點**
$$
\large
H(x)=
\begin{cases}
1 & \text{if}~~\sigma\big(h_T(x)\big) \ge \text{threshold} \\
0 & \text{o.w.}
\end{cases}
$$
:::
# 參考資料
- [Gradient Boosting 簡介, Chih-Wei Chang](https://medium.com/@cwchang/gradient-boosting-%E7%B0%A1%E4%BB%8B-f3a578ae7205)
- [Gradient Boost Part 1: Regression Main Ideas, StatQuest with Josh Starmer](https://www.youtube.com/watch?v=3CC4N4z3GJc)
- [Gradient Boost Part 2: Regression Details, StatQuest with Josh Starmer](https://www.youtube.com/watch?v=2xudPOBz-vs)
- [Gradient Boost Part 3: Classification, StatQuest with Josh Starmer](https://www.youtube.com/watch?v=jxuNLH5dXCs)
- [Gradient Boost Part 4: Classification Details, StatQuest with Josh Starmer](https://www.youtube.com/watch?v=StWY5QWMXCw)
###### tags: `ML`
$$
\DeclareMathOperator{\argmin}{\arg\min}
$$