# GBDT

​ GBDT也是迭代型的，可以用于分类和回归，**弱学习器限定只能使用CART回归树模型**，GBDT中的决策树是个弱模型，深度较小一般不会超过5，叶子节点的数量也不会超过10.

## 回归

输入训练集样本：$$T={(x\_1,y\_1),(x\_2,y\_2),...,(x\_m,y\_m) }$$，最大迭代次数T, 损失函数L。

输出强学习器f(x)

### 1）假设前一轮学到的强学习器

$$f\_{t-1}(x)$$

如果是初始轮，就按照正常[CART](https://blog.csdn.net/jiang425776024/article/details/87644983#4.CART算法)那样构建出来一个CART回归

### 2）定义前一轮的损失函数

$$L(y,f\_{t-1}(x))$$

那么当前迭代学习，希望学到的弱学习器，目的是希望找到一个CART回归树模型的弱学习器：$$h\_t(x)$$让接下来t轮的强学习器的损失：$$L(y,f\_t(x))=L(y,f\_{t-1}(x)+h\_t(x))$$降到最低。

也就是希望找到这样一个新的CART回归决策树，让损失进一步下降，一步步逼近真实值：

![](/files/-Lq7QTFRWcoSH45FMzys)

显然负梯度方向是函数下降方向，记 t 轮的第 i 个样本的损失函数的负梯度为：

$$
r\_{ti} = - \[\frac{\partial L(y\_i, f(x\_i))}{\partial f(x\_i)}]*{f(x)=f*{t-1}(x)}
$$

L可以这么选，GBDT通常是平方损失，也就是下1，因此对于$$x\_i$$，其负梯度损失可以看作是$$y\_i-f(x\_i)$$：

![](/files/-Lq7QTFW9oUq-YFZxPlE)

### 3）构造出CART树

* a）计算出每个样本的损失负梯度值（是个值），得到新的数据集（自变量及对应损失梯度值构成的集合）：

$$(x\_i,r\_{ti});; (i=1,2,..m)$$，就可以可以开始构造CART回归树了。

* b）记叶子节点为：$$R\_{tj}, j =1,2,..., J$$，J为叶子节点个数。

  假设叶子节点$$R\_{tj}$$包含k个样本，我们希望这个叶子节点的输出能让节点内k个样的累积损失最小

  （因为每个节点都这样计算最佳c，整个树的最佳输出就找到了）：$$\large c\_{tj} = \underbrace{arg; min}*{c}\sum\limits*{x\_i \in R\_{tj}} L(y\_i,f\_{t-1}(x\_i) +c)$$
* c）根据CART构造规则，**叶子节点的值为节点内数据的平均或中位数**。但是现在叶子节点内部k个样本负梯度的均值记$$avg\_{rtj}$$是梯度均值。

  （问题是梯度只是个方向，梯度=0.1=100=无穷 >0，仅仅表示下一轮弱学习器应该往增大预测输出这个方向上去）（有些资料直接拿这个做输出也是可以的，就是学习率是1，然后执行了一次梯度下降嘛。

  但是不一定就是最佳输出，可以用一维线性搜索：<https://blog.csdn.net/jiang425776024/article/details/87600422>
* d）因此，**划分CART树就是正常那样方差最小划分，节点输出为基于节点负梯度均值为梯度下降方向乘以步长，尽量找到的最佳c为此节点的输出**，这样，就能构造出新的CART树让损失下降了。

### 4）得到新论CART决策树函数

$$\large h\_t(x) = \sum\limits\_{j=1}^{J}c\_{tj}I(x \in R\_{tj})$$

既，对于x做预测，其输出为x一路判断到叶子节点的那个区域的$$c\_{tj}$$。

### 5）得到新的强学习器

$$\large f\_{t}(x) = f\_{t-1}(x) + \sum\limits\_{j=1}^{J}c\_{tj}I(x \in R\_{tj})$$

### 6）得到最终集成器

上面那样计算**T次负梯度误差（残差），构造T个CART树，叠加起来**就得到了最终的集成学习器：

$$f(x) = f\_T(x) =f\_0(x) + \sum\limits\_{t=1}^{T}\sum\limits\_{j=1}^{J}c\_{tj}I(x \in R\_{tj})$$

## 分类

### 二分类

输入训练集样本：$$\large T={(x\_,y\_1),(x\_2,y\_2), ...(x\_m,y\_m)}$$，最大迭代次数T, 损失函数L。

输出是强学习器f(x)

GBDT的分类算法从思想上和GBDT的回归算法没有区别，但是由于样本输出不是连续的值，而是离散的类别，导致无法直接从输出类别去拟合类别输出的误差。

解决这个问题，主要有两个方法，一个是**用指数损失函数**，此时GBDT退化为Adaboost算法。另一种方法是用类似于**逻辑回归的对数似然损失函数**的方法。也就是说，我们**用类别的预测概率值和真实概率值的差**来拟合损失。

### 1）定义损失形式为

（这里记分类标签为-1,1）

（负二项对数似然）

$$\large L(y,f\_t(x)))=log(1+exp(-2yf\_t(x))),y \in -1,1$$

其中**初始时每个样本的预测输出为样本集中正负样本概率和的比**：

$$
f\_0(x)=log \frac{\sum\_{i=1}^m y\_i}{\sum\_{i=1}^m(1-y\_i)}=log \frac{num(p\_1)}{num(p\_{-1})}
$$

$$\large f\_t(x)$$由后面累加CART树得到。

### 2）然后就能计算负梯度函数了

$$
\large r\_{ti}=-\[\frac{\partial L(y,f(x\_{i}))}{\partial f(x\_{i})}]*{f(x)=f*{t-1}(x)}=\frac{2y\_{i}}{1+exp(2y\_{i}f\_{t-1}(x\_{i}))}
$$

### 3）叶子节点估计值：

$$
\large c\_{tj} = argmin\_{c}\sum\_{x\_{i}\epsilon R\_{tj}} log(1+exp(-2y\_{i}(f\_{t-1}(x\_{i})+c)))
$$

分类问题没有绝对意义上的步长和距离的概念，因此难以求解最佳值，所以**改为近似求解**：

$$
\large c\_{tj} = \sum\limits\_{x\_i \in R\_{tj}}r\_{ti}\bigg / \sum\limits\_{x\_i \in R\_{tj}}|r\_{ti}|(2 -|r\_{ti}|)
$$

4）这样，基于CART划分节点规则，基于上面对节点的输出，可以构造出CART回归树。

5）其它步骤与上面的回归一致。

$$
\large f\_{t}(x) = f\_{t-1}(x) + \sum\limits\_{j=1}^{J}c\_{tj}I(x \in R\_{tj})
$$

$$
\large f(x) = f\_T(x) =f\_0(x) + \sum\limits\_{t=1}^{T}\sum\limits\_{j=1}^{J}c\_{tj}I(x \in R\_{tj})
$$

6）最后预测形式

把上面得到的f(x)，可以传入计算出概率：

$$
\large P(y=1|x)=p= \frac{1}{1+e^{-2f(x)}},\large P(y=-1|x)=1-p= \frac{1}{1+e^{2f(x)}}
$$

可以计算正负类的概率。

## 代码跑起来

在sacikit-learn中，GradientBoostingClassifier为GBDT的分类类， 而GradientBoostingRegressor为GBDT的回归类

使用方法：<https://www.cnblogs.com/pinard/p/6143927.html>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://im-qianuxn.gitbook.io/pytorch/ji-suan-ji/ml/ji-cheng/gbdt.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
