1. 基本概念
- GBDT也是Boosting算法的一种,但是和Adaboost算法不同;如别如下:
- Adaboost算法是利用前一轮的弱学习器的预测误差率来更新样本权重,然后一轮一轮的迭代;
- GBDT也是迭代,但是GBDT要求的弱学习器必须是CART模型,而且GBDT在模型训练的时候,模型预测的样本损失尽可能小;
- GBDT底层只支持决策树,并且是回归决策树;
- 别名:GBT(Gradient Boosting Tree),GTB(Gradient Tree Boosting)、GBRT(Gradient Boosting Regression Tree), GBDT(Gradient Boosting Decision Tree),
MART(mutiple Additive Regression Tree) - 迭代过程:
- f t − 1 ( x ) − > 训 练 弱 学 习 器 h t ( x ) − > f t ( x ) f_{t-1}(x)->训练弱学习器h_t(x)->f_t(x) ft−1(x)−>训练弱学习器ht(x)−>ft(x)
- L ( Y , f t − 1 ) − > 训 练 弱 学 习 器 h t ( x ) − > L ( y , f t − 1 ( x ) + h t ( x ) ) L(Y, f_{t-1})->训练弱学习器h_t(x)->L(y,f_{t-1}(x)+h_t(x)) L(Y,ft−1)−>训练弱学习器ht(x)−>L(y,ft−1(x)+ht(x))
- 在工作中用的比较少,实际在工作中用的比较多的是Xgboost和LightGBM
- 思想理解
其实,就是每迭代一轮,减少误差。选择本轮迭代器的标准就是:使得本轮得到的误差比上一轮得到的误差最小;
- 举例
- 例一
- 例二
- 例一
- 将每一轮的弱学习器在训练集上的残差作为下一轮学习的输入。
- 当给定步长step0的时候,在构建下一棵树的时候使用step0*残差值作为输出值,这种情况可以减少过拟合的发生
2. 组成要素
- GBDT由三部分组成:DT(Regression Decision Tree)、GB(Gradient Boosting)和shrink(衰减);
- 由多棵决策树组成,所有树的结果累加起来就是最终结果;
- 迭代决策树和随机森林的区别:
- 随机森林抽取不同的样本,构建不同的子树;也就是说第m棵树和第m-1棵树之间没有必然的关系;
- 迭代决策树在构建子树的时候,使用之前的子树构建结果后形成的残差作为输入数据来构建下一个子树;然后最终预测的时候按照子树构建的顺序进行预测,并将模型结果相加;
3. GBDT算法原理
- 给定输入向量X和输出变量Y组成若干训练样本 ( X 1 , Y 1 ) , ( X 2 , Y 2 ) . . . . ( X n , Y n ) (X_1, Y_1),(X_2, Y_2)....(X_n, Y_n) (X1,Y1),(X2,Y2)....(Xn,Yn),目标是找到近似函数(弱学习器),是的损失函数 ( L ( Y , F ( X ) ) ) (L(Y, F(X))) (L(Y,F(X)))尽可能小。
- L损失函数一般采用最小二乘损失函数或者绝对值损失函数:[主要原因是构造回归树]
- L ( X , F ( X ) ) = 1 2 ( y − f ( x ) ) 2 L(X, F(X))=\frac{1}{2}(y-f(x))^2 L(X,F(X))=21(y−f(x))2
- L ( X , F ( X ) ) = ∣ y − F ( X ) ∣ L(X, F(X))=|y-F(X)| L(X,F(X))=∣y−F(X)∣
- 需要寻找的最优弱学习器为: F ∗ ( X ) = a r g m i n F L ( y , F ( x ) ) F^*(X)=argmin_FL(y,F(x)) F∗(X)=argminFL(y,F(x))
- 假设F(x)是一族最优基函数
f
i
(
x
)
f_i(x)
fi(x)的加权和:
- F ( X ) = ∑ i = 0 M f i ( x ) F(X)=\sum_{i=0}^Mf_i(x) F(X)=∑i=0Mfi(x)
- 为了防止每一个基学习器学习能力过强,而导致过拟合,需要给定一个缩放系数: F ( X ) = v ∑ i = 0 M f i ( x ) F(X)=v\sum_{i=0}^Mf_i(x) F(X)=v∑i=0Mfi(x)
- 按照贪心算法的思想得到
F
M
(
x
)
F_M(x)
FM(x),求解最优的f
- F M ( x ) = F M − 1 ( x ) + a r g m i n f ∑ i = 1 n L ( y i , F M − 1 ( X i ) + f m ( X i ) ) F_M(x)=F_{M-1}(x)+argmin_f \sum_{i=1}^n L(y_i,F_{M-1}(X_i)+fm(X_i)) FM(x)=FM−1(x)+argminf∑i=1nL(yi,FM−1(Xi)+fm(Xi))
- 按照贪心算法每次选择最优基函数时,仍然存在困难,使用梯度下降法近似计算[因为涉及到所有的样本]
- 给定常数函数 F 0 ( X ) F_0(X) F0(X),使得 F 0 ( X ) = a r g m i n c ∑ i = 1 n L ( y i , c ) F_0(X)=argmin_c\sum_{i=1}^nL(y_i, c) F0(X)=argminc∑i=1nL(yi,c)
- 根据梯度下降计算学习率:
- α i m = [ ∂ L ( y i , F ( x i ) ) ∂ F ( x i ) ] F ( x ) = F m − 1 ( x ) \alpha_{im}=[\frac{\partial L(y_i, F(x_i))}{\partial F(x_i)}]_{F(x)=F_{m-1}(x)} αim=[∂F(xi)∂L(yi,F(xi))]F(x)=Fm−1(x)
- 使用数据
(
x
i
,
α
i
m
)
(
i
=
1
,
2...
n
)
(x_i, \alpha_{im})(i=1,2...n)
(xi,αim)(i=1,2...n)计算拟合残差,得到一个CART回归树,得到第m棵树:注意每次将
y
i
变
为
α
i
m
y_i变为\alpha_{im}
yi变为αim,
α
i
m
\alpha_{im}
αim的变化就是梯度方向变化
- c m j = a r g m i n x ∑ x ∈ l e a f L ( y i , f m − 1 ( x i ) + c ) c_{mj}=argmin_x \sum_{x\in leaf} L(y_i, f_{m-1}(x_i)+c) cmj=argminx∑x∈leafL(yi,fm−1(xi)+c)
- h m ( x ) = ∑ j = 1 ∣ l e a f ∣ m c m j I ( x ∈ l e a f m j ) h_m(x)=\sum_{j=1}^{|leaf|_m} c_{mj} I(x \in leaf_{mj}) hm(x)=∑j=1∣leaf∣mcmjI(x∈leafmj)
- 更新模型
- f m ( x ) = f m − 1 ( x ) + ∑ j = 1 ∣ l e a f ∣ m c m j I ( x ∈ l e a f m j ) f_m(x)=f_{m-1}(x)+\sum_{j=1}^{|leaf|_m} c_{mj} I(x \in leaf_{mj}) fm(x)=fm−1(x)+∑j=1∣leaf∣mcmjI(x∈leafmj)
- f ( x ) = f 0 ( x ) + ∑ m = 1 M ∑ j = 1 ∣ l e a f ∣ m c m j I ( x ∈ l e a f m j f(x)=f_0(x) + \sum_{m=1}^M \sum_{j=1}^{|leaf|_m}c_{mj} I(x \in leaf_{mj} f(x)=f0(x)+∑m=1M∑j=1∣leaf∣mcmjI(x∈leafmj
4. GBDT回归算法和分类算法的区别
- 两者唯一的区别就是选择不同的损失函数;
- 回归算法选择的损失函数一般为:均方差(最小二乘)或者绝对值误差;而在分类算法中一般的损失函数选择对数函数来表示:
- L ( y , f ( x ) ) = 1 2 ( y − f ( x ) ) 2 L(y, f(x))=\frac{1}{2}(y-f(x))^2 L(y,f(x))=21(y−f(x))2
- L ( y , f ( x ) ) = l n ( 1 + e − y ∗ f ( x ) ) ; y ∈ ( − 1 , + 1 ) L(y, f(x))=ln(1+e^{-y*f(x)}); y\in(-1, +1) L(y,f(x))=ln(1+e−y∗f(x));y∈(−1,+1)
- L ( y , f ( x ) ) = − ∑ k = 1 K y k l o g ( p k ( x ) ) L(y, f(x))=-\sum_{k=1}^K y_k log(p_k(x)) L(y,f(x))=−∑k=1Kyklog(pk(x)); K分类中
5. GBDT API相关参数
参数 | GradientBoostingClassifier | GradientBoostingRegressor |
---|---|---|
alpha | 不支持 | 当使用huber或者quantile损失函数时,需要给定分位数的值,默认为0.9;如果噪音数据比较多,可以适当地降低改参数 |
loss | 给定损失函数,可以选择对数似然函数diviance和指数损失函数exponential;默认为deviance,不建议修改 | 给定损失函数,可选均方差损失函数ls、绝对损失lad、Huber损失huber、分位数损失函数quantile;默认选择ls,如果噪音数据比较多,采用huber;如果是分段预测,推荐qutantile |
n_estimators | 最大迭代次数,值过小可能会导致欠拟合,值过大可能会导致过拟合,一般50~100比较合适,默认50 | |
learning_rate | 指定每个弱分类器的权重缩减系数v,默认为1;一般从一个较小的值进行调参;该值越小表示需要更多的弱分类器; | |
subsample | 给定训练模型的时候,进行子采样的比例值,取值范围(0,1],默认为1,表示不采用子采样;给定小于1的值表示采用部分数据进行模型训练,可以降低模型的过拟合情况;推荐[0.5, 0.8];采样的方式是不放回采用 | |
init | 给定初始化的模型,可以不给定 |
6. GBDT总结
- GBDT的优点如下:
- 可以处理连续值和离散值;
- 在相对少的调参情况下,模型的预测效果也会不错;
- 模型的鲁棒性较强
- GBDT的缺点
- 由于弱学习器之间存在关联关系,难以并行训练模型,也就是模型的训练速度很慢。
Bagging和Boosting的区别
- 样本选择:Bagging算法是又放回的随机抽样(Bootstrap);Boosting算法是每一轮的训练集不变,只是训练集中的每个样例在分类器中的权重发生变化(adaboost)或者目标属性发生变化(gbdt),而权重根据上一轮的分类结果进行调整;
- 样例权重:Bagging使用随机抽样,样例等权重;Boosting根据基分类器的错误率不断地调整样本的权重,错误率越大,权重越大;
- 预测函数:Bagging所有预测模型的权重相等;Boosting算法对于误差小的分类器具有更大的权重;
- 并行计算:Bagging算法可以并行生成各个模型;Boosting理论上只能顺序产生,因为后一个模型需要前一个模型的预测结果;
- Bagging是减小模型的variance(方差);Boosting时间小模型的Bias(偏差)。
- Bagging里面每个分类模型都是强分类器,因为降低的是方差,方差过高需要降低的是过拟合;
Boosting里面每个分类器模型是弱分类器,因为降低的是偏度,偏度过高时欠拟合;
方差和偏差
- e r r o r = B i a s + V a r i a n c e error=Bias+Variance error=Bias+Variance
- 图示
# demo
import numpy as np
from matplotlib import pyplot as plt
from sklearn.preprocessing import PolynomialFeatures
from sklearn.linear_model import Ridge
x = np.arange(0, 5, 0.5)
fun_c = lambda x: -1 * np.square(x) + 6 * x
y_ = [fun_c(_) for _ in x]
noise = [0, 0.1, 0.1, 1, 0.2, 0, -1, 0.1, 0, -0.2]
y = []
for i, j in zip(y_, noise):
y.append(i + j)
pf = PolynomialFeatures(degree=11)
p_x = pf.fit_transform(x.reshape(-1, 1))
lin1 = Ridge()
lin1.fit(p_x, y)
y_pred1 = lin1.predict(p_x)
# -- 直接线性回归
lin2 = Ridge()
lin2.fit(x.reshape(-1, 1), y)
y_pred2 = lin2.predict(x.reshape(-1, 1))
fig = plt.figure(figsize=(8, 6))
plt.scatter(x, y, Zorder=10, s=75, label='real points')
plt.plot(x, y_, color='r', label='Just Right')
plt.plot(x, y_pred1, color='g', label='overfit')
plt.plot(x, y_pred2, color='black', label='underfit')
plt.grid(True)
plt.xlabel('x')
plt.ylabel('y')
plt.legend()
plt.show()
3. Stacking
- Stacking是指训练一个模型用于组合(combine)其他模型(基模型和基学习器)的技术。即首先训练处多个不同的模型,然后以之前训练的各个模型的输出作为输入来训练一个新的模型,从而得到一个最终模型,一般情况下,使用单层的Logistic回归作为组合模型;
- 图例: