梯度提升类(Gradient Boosting)方法的总结

梯度下降与梯度提升?

相同点:每一轮迭代中,都用负梯度方向信息更新模型。

不同点:

    (1)梯度下降:将模型参数化,模型的更新转变为参数的更新。

w_t=w_{t-1}-\rho_t\bigtriangledown_wL|_{w=w_{t-1}}

L=\sum_{i}^{}loss(y_i,f_w(w_i))

    (2)梯度提升:将模型定义在函数空间内,大大扩展使用的模型类型。

F_t=F_{t-1}-\rho_t\bigtriangledown_FL|_{F=F_{t-1}}

L=\sum_{i}^{}loss(y_i,F(x_i))

梯度提升类的一般框架

概述

基于boosting集成的加法模型,训练时采用前向分布算法进行贪婪学习,每次迭代学习一棵树来拟合前t-1棵树的预测结果与真值的残差。

目标函数

Obj=\sum_{i}^{}L(y_i,\hat{y_i})+\sum_{k}^{}\Omega (f_k)

解决方案

初始化一个预测值,然后每次迭代添加一个函数:

\hat{y_i}^{(0)}=0

\hat{y_i}^{(1)}=\hat{y_i}^{(0)}+f_1(x_i))     

\hat{y_i}^{(2)}=\hat{y_i}^{(1)}+f_2(x_i))

...

\hat{y_i}^{(t)}=\hat{y_i}^{(t-1)}+f_t(x_i))=\sum_{k=1}^{t}f_k(x_i)

目标函数的泰勒展开及树生成方案

(1)目标函数变换

Obj=\sum_{i}^{}L(y_i,\hat{y_i})+\sum_{k}^{}\Omega (f_k) =\sum_{i}^{}L(y_i,\hat{y_i}^{t-1}+f_t(x_i))+\sum_{k}^{}\Omega (f_k)

引入泰勒展开公式:

f(x+\Delta x)=f(x)+f^{'}(x)\Delta x+\frac{1}{2}f^{''}(x)\Delta x^{2}

f(x)=L(y_i,\hat{y_i}^{t-1}),\Delta x=f_t(x_i),则

Obj\approx \sum_{i}^{}[L(y_i,\hat{y_i}^{t-1})+g_if_t(x_i)+\frac{1}{2}h_if_t^{2}(x_i))]+\sum_{k}^{}\Omega (f_k)

=\sum_{i}^{}[g_if_t(x_i)+\frac{1}{2}h_if_t^{2}(x_i))]+\sum_{k}^{}\Omega (f_k)+constant

其中,g_i= \partial_{\hat{y}_i^{(t-1)}}L(y_i,\hat{y}_i^{(t-1)}),h_i= \partial^{2}_{\hat{y}_i^{(t-1)}}L(y_i,\hat{y}_i^{(t-1)})

(2)重新定义树

通过叶子节点的权重w及实例映射到叶子节点的索引函数q来定义树。

f_t(x_i)=w_q(x_i),

其中,w\in R^{T},q:R^{d}\rightarrow {[1,2,...,T]}

定义树的复杂程度:

\Omega (f_k)=\gamma T+\frac{1}{2}\lambda \sum_{j=1}^{T}w_{j}^{2}

(3)目标函数的二次函数形式优化推导

设叶子节点j中的实例集合为I_j=\begin{Bmatrix} i|q(x_i)=j \end{Bmatrix}

则目标函数可重新写为:

Obj=\sum_{j}^{}[\sum_{i\in I_j}^{}g_iw_j+\frac{1}{2}\sum_{i\in I_j}^{}h_iw_j^{2}(x_i)]+\gamma T+\frac{1}{2}\lambda \sum_{j=1}^{T}w_{j}^{2}+constant

=\sum_{j}^{}[\sum_{i\in I_j}^{}g_iw_j+\frac{1}{2}(\sum_{i\in I_j}^{}h_i+\lambda )w_j^{2}(x_i)]+\gamma T+constant

G_i=\sum_{i\in I_j}^{}g_i,H_i=\sum_{i\in I_j}^{}h_i,则

Obj=\sum_{j}^{}[G_iw_j+\frac{1}{2}(H_i+\lambda )w_j^{2}(x_i)]+\gamma T+constant

通过观察,发现其为二次函数

w_{j}^{*}=-\frac{G_j}{H_j+\lambda }处取得最优值为Obj^{*}=-\frac{1}{2}\sum_{j}\frac{G_j^2}{H_j+\lambda }+\gamma T

(4)贪婪算法生成树

何为贪婪算法?通过迭代局部最优实现。

对每个节点枚举所有特性,然后根据该特性对样本排序,通过线性扫描查找该特性下的最佳分裂点,采用所有特征中最好的分裂方案进行分裂。

Gain=\frac{1}{2}(\frac{G_L^2}{H_l+\lambda }+\frac{G_R^2}{H_R+\lambda }-\frac{(G_L+G_R)^2}{H_l+H_R+\lambda })-\gamma

经典梯度提升方法

梯度提升决策树(Gradient Boosting Decision Tree,GBDT)

特点

损失函数为泰勒一阶展开。

优点

  1. 可解释性强,并能自动发现特征的高阶关系;
  2. 预测阶段可并行加速;

缺点

  1. 训练时不能并行,工程加速只能体现在单棵树的构建上;
  2. 在高维稀疏数据集上表现效果差;(为什么:高维特征导致运行耗时,稀疏特征导致不能有效地进行特征空间切分,对噪声敏感)

Python调用方式

from sklearn.ensemble import GradientBoostingRegressor
'''
GradientBoostingRegressor(*, loss='squared_error', learning_rate=0.1, n_estimators=100, subsample=1.0, criterion='friedman_mse', min_samples_split=2, min_samples_leaf=1, min_weight_fraction_leaf=0.0, max_depth=3, min_impurity_decrease=0.0, init=None, random_state=None, max_features=None, alpha=0.9, verbose=0, max_leaf_nodes=None, warm_start=False, validation_fraction=0.1, n_iter_no_change=None, tol=0.0001, ccp_alpha=0.0)
'''

主要参数

分类参数名称参数含义
boosting框架参数loss损失函数
n_estimatos树的个数
learning_rate学习率
subsample样本采样比例
弱学习器参数min_samples_split节点分裂所需的最小样本数
min_samples_leaf叶子节点最小的样本数
max_depth最大深度
min_weight_fraction_leaf叶子节点所有样本权重和的最小值
min_impurity_decrease节点划分最小不纯度
max_features考虑的最大特征数目,auto、sqrt、log2
max_leaf_nodes最大叶子节点数量

调参过程

借助网格搜索方法:

  1. 固定一较大的学习率(如lr=0.1),进行n_estimators调优;
  2. 固定学习率和n_estimators,对树的参数进行调优:max_depth、min_samples_split->min_samples_leaf->max_features
  3. 降低学习率,确定理想参数。在该参数下,进行多轮次训练,观察和评估模型的拟合、泛化表现。

极致梯度提升(Extreme Gradient Boosting,XGBoost)

与GBDT的对比

  1. GBDT的损失函数为一阶泰勒展开,XGBoost的损失函数为二阶泰勒展开+正则化;(二阶泰勒展开可以更加精准地逼近真实损失函数,有利于梯度下降得更快更准)
  2. GBDT的基分类器为CART树,XGBoost的基分类器为CART树或线性分类器;
  3. GBDT无缺失值的处理,XGBoost通过稀疏感知的方法来处理缺失值;
  4. XGBoost在算法基础上进行了工程优化;

特点

  1. 缺失值处理:分裂节点时,将缺失值视为一个整体,提高运算效率,并考虑两个方向。
  2. 列采样:构建每棵树时随机选择一部分特征,增加模型多样性,防止过拟合。
  3. 工程并行优化:将每一列的特征提前进行排序,以块的形式存储在缓存中,每次节点分裂重复调用排好序的块即可。

XGBoost防止过拟合的方式

  1. 正则化
  2. 行、列采样
  3. Shrinkage:不完全信任每个弱学习器学到的残差值,对其进行衰减,从而为后边的树留下学习空间。

Python调用方式

import xgboost as xgb
model = xgb.XGBRegressor(max_depth=3,
                        learning_rate=0.1,
                        n_estimators=100,
                        objective='reg:linear', # 此默认参数
                        booster='gbtree',
                        gamma=0,
                        min_child_weight=1,
                        subsample=1,
                        colsample_bytree=1,)

主要参数

分类参数名称参数含义
boosting参数booster弱学习器的种类:gbtree、gblinear
n_estimatos树的个数
learning_rate学习率
objective学习目标reg:linear、reg:logstic、binary:logstic、multi:softmax
subsample样本采样比例
弱学习器参数max_depth最大深度
colsample_bytree特征随机采样的比例
min_child_weight孩子节点最小的样本权重和
gamma节点分裂所需的损失减小最小值
alphal1正则化权重项
lambdal2正则化权重项
eval_metric评估指标:rmse(回归任务)、mlogloss(多分类任务)、error(二分类任务)、auc(二分类任务)

调参过程

借助网格搜索方法:

  1. 固定一较大的学习率(如lr=0.1),进行n_estimators调优;
  2. 固定学习率和n_estimators,对树的参数进行调优:min_child_weight、max_depth->gamma->subsample、colsample_bytree
  3. 正则化参数alpha、lambda调优
  4. 降低学习率,确定理想参数。在该参数下,进行多轮次训练,观察和评估模型的拟合、泛化表现。

调参经验总结

  1. 固定一较大的学习率(如lr=0.1),进行n_estimators调优;
  2. 固定学习率和n_estimators,对树的参数进行调优:
    步骤类型参数名称
    1树的深度、节点分裂的限制

    GradientBoostingRegressor:max_depth、min_samples_split

    XGBRegressor:max_depth、min_child_weight

    2叶子节点限制

    GradientBoostingRegressor:min_samples_leaf

    XGBRegressor:gamma

    3行/列采样

    GradientBoostingRegressor:max_features

    XGBRegressor:colsample_bytree、subsample

  3. (正则化参数alpha、lambda调优)
  4. 降低学习率,确定理想参数。在该参数下,进行多轮次训练,观察和评估模型的拟合、泛化表现。
梯度提升Gradient Boosting)是一种集成学习方法,它通过将多个弱学习器(通常是决策树)组合成一个强学习器来提高预测性能。梯度提升的核心思想是通过迭代的方式,每次迭代都训练一个新的弱学习器来纠正前一轮迭代的错误。 在Python中,有多个库可以用于实现梯度提升算法,其中最常用的是scikit-learn库中的GradientBoostingRegressor和GradientBoostingClassifier。这两个分别用于回归和分问题。 下面是一个使用scikit-learn库中的GradientBoostingRegressor进行回归问题的示例代码: ```python from sklearn.ensemble import GradientBoostingRegressor from sklearn.datasets import make_regression from sklearn.model_selection import train_test_split from sklearn.metrics import mean_squared_error # 生成示例数据 X, y = make_regression(n_samples=100, n_features=1, noise=0.1, random_state=42) # 划分训练集和测试集 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) # 创建梯度提升回归器 model = GradientBoostingRegressor() # 训练模型 model.fit(X_train, y_train) # 在测试集上进行预测 y_pred = model.predict(X_test) # 计算均方误差 mse = mean_squared_error(y_test, y_pred) print("均方误差:", mse) ``` 对于分问题,可以使用scikit-learn库中的GradientBoostingClassifier。使用方法与上述示例似,只需要将名替换为GradientBoostingClassifier即可。 梯度提升算法还有很多参数可以调整,例如学习率、树的数量、树的深度等。你可以根据具体问题和数据集的特点来调整这些参数以获得更好的性能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值