{r setup, include=FALSE} knitr::opts_chunk$set(eval = FALSE) * Extreme Gradient Boosting with XGBoost 学习笔记 - A Hugo website 这里是Python的Code和例子,以及超参数的调整。
这里主要讲的是理论部分,反正我在网上很少看到讲的清楚的文章,这篇写的比较好,是卡狗,Kaggle比较厉害的一个人写的,Ben Gorman | Kaggle。 这里主要参考他的一个博客,A Kaggle Master Explains Gradient Boosting | No Free Hunch。
简单来说,XGBoost的形成,是通过决策树$\to$ Boosting $\to$ XGBoost完成的。
因此先将决策树。 具体决策树递归的逻辑见 ( 决策树理论部分 学习笔记 - A Hugo website ) 。
{r message=FALSE, warning=FALSE, include=FALSE} library(knitr) library(tidyverse)
{r echo=FALSE, message=FALSE, warning=FALSE} tibble::tribble( ~PersonID, ~Age, ~LikesGardening, ~PlaysVideoGames, ~LikesHats, 1L, 13L, FALSE, TRUE, TRUE, 2L, 14L, FALSE, TRUE, FALSE, 3L, 15L, FALSE, TRUE, FALSE, 4L, 25L, TRUE, TRUE, TRUE, 5L, 35L, FALSE, TRUE, TRUE, 6L, 49L, TRUE, FALSE, FALSE, 7L, 68L, TRUE, TRUE, TRUE, 8L, 71L, TRUE, FALSE, FALSE, 9L, 73L, TRUE, FALSE, TRUE ) %>% kable()
其中列标签分别表示,
PersonID表示数据表的index,Age是$Y$变量,- 其余是$X$变量,且都是dummy的。
对于三个自变量,有如下的猜想,
– The people who like gardening are probably older,喜欢花花草草的,可能更年长 – The people who like video games are probably younger,喜欢打游戏的,可能更年轻 – LikesHats is probably just random noise,喜欢帽子与否是噪音,这里的引入主要是为说明决策树的一个超参数。
{r echo=FALSE, message=FALSE, warning=FALSE} tibble::tribble( ~Feature, ~FALSE., ~TRUE., "LikesGardening", "{13, 14, 15, 35}", "{25, 49, 68, 71, 73}", "PlaysVideoGames", "{49, 71, 73}", "{13, 14, 15, 25, 35, 68}", "LikesHats", "{14, 15, 49, 71}", "{13, 25, 35, 68, 73} ) %>% kable()
<!--  -->
假设每个叶子最少三个样本得到的例子。 这个通过信息熵控制,暂时不讨论这个问题。
<!--  -->
假设每个叶子最少两个样本得到的例子,发现噪音-帽子进入了决策树,因为模型抓取了噪音,因此过拟合了。
这里可以通过正则化等方法控制,但是Boosting也可以解决这个问题。
{r echo=FALSE, message=FALSE, warning=FALSE} tibble::tribble( ~PersonID, ~Age, ~Tree1.Prediction, ~Tree1.Residual, 1L, 13L, 19.25, -6.25, 2L, 14L, 19.25, -5.25, 3L, 15L, 19.25, -4.25, 4L, 25L, 57.2, -32.2, 5L, 35L, 19.25, 15.75, 6L, 49L, 57.2, -8.2, 7L, 68L, 57.2, 10.8, 8L, 71L, 57.2, 13.8, 9L, 73L, 57.2, 15.8 ) %>% kable()
公式满足
$$Age-Tree1.Prediction = Tree1.Residual$$
Boosting的关键出现了,
<!--  -->
对Tree1.Residual也就是$\hat \mu$进行学习,这就是知道了,为什么线性回归搞Boosting存在bug,因为$\rho(\hat \mu, X) = 0$。
这个树相比较于Tree1的关键之处是,没有用帽子变量,因此剔除了噪音,这就是Boosting的价值之处,并且这里的$\hat y$是Tree1里面的$\hat \mu$,是一个过拟合的决策树的东西。 因此Boosting相当于对错题集重复的学习。
{r echo=FALSE, message=FALSE, warning=FALSE} tibble::tribble( ~PersonID, ~Age, ~Tree1.Prediction, ~Tree1.Residual, ~Tree2.Prediction, ~Combined.Prediction, ~Final.Residual, 1L, 13L, 19.25, -6.25, -3.567, 15.68, 2.683, 2L, 14L, 19.25, -5.25, -3.567, 15.68, 1.683, 3L, 15L, 19.25, -4.25, -3.567, 15.68, 0.6833, 4L, 25L, 57.2, -32.2, -3.567, 53.63, 28.63, 5L, 35L, 19.25, 15.75, -3.567, 15.68, -19.32, 6L, 49L, 57.2, -8.2, 7.133, 64.33, 15.33, 7L, 68L, 57.2, 10.8, -3.567, 53.63, -14.37, 8L, 71L, 57.2, 13.8, 7.133, 64.33, -6.667, 9L, 73L, 57.2, 15.8, 7.133, 64.33, -8.667 ) %>% kable()
这里满足,以PersonID = 1为例。
Age = 13、 Tree1 Prediction = 19.25, 所以,Tree1 Residual = 13 - 19.25 = -6.25。
Tree2 Prediction = -3.567 所以,Tree2 Residual = -6.25 - (-3.567) = -2.683,也就是Final Residual。
所以,Combined.Prediction = Age - Final Residual = 13 - (-2.683) = 15.83。
用公式推导就是,
$$y = F_{1}(X) \to y = \hat F_{1}(X) + \hat \mu_{1}$$
$$\hat \mu_1 = F_{2}(X) \to \hat \mu_1 = \hat F_{2}(X) + \hat \mu_{2}$$
因此,
$$\begin{alignat}{2} y & = \hat F_{1}(X) + \hat \mu_{1} \ & = \hat F_{1}(X) + \hat F_{2}(X) + \hat \mu_{2} \ & = \sum_{i}^m \hat F_{i}(X) + \hat \mu_{m} \ \end{alignat}$$
$\hat \mu_{m}$理论上比之前都要好,因此这就是Boosting的价值。