梯度下降与梯度提升?
相同点:每一轮迭代中,都用负梯度方向信息更新模型。
不同点:
(1)梯度下降:将模型参数化,模型的更新转变为参数的更新。
(2)梯度提升:将模型定义在函数空间内,大大扩展使用的模型类型。
梯度提升类的一般框架
概述
基于boosting集成的加法模型,训练时采用前向分布算法进行贪婪学习,每次迭代学习一棵树来拟合前棵树的预测结果与真值的残差。
目标函数
解决方案
初始化一个预测值,然后每次迭代添加一个函数:
目标函数的泰勒展开及树生成方案
(1)目标函数变换
引入泰勒展开公式:
令,,则
其中,
(2)重新定义树
通过叶子节点的权重及实例映射到叶子节点的索引函数来定义树。
令,
其中,
定义树的复杂程度:
(3)目标函数的二次函数形式优化推导
设叶子节点中的实例集合为
则目标函数可重新写为:
令,则
通过观察,发现其为二次函数
在处取得最优值为。
(4)贪婪算法生成树
何为贪婪算法?通过迭代局部最优实现。
对每个节点枚举所有特性,然后根据该特性对样本排序,通过线性扫描查找该特性下的最佳分裂点,采用所有特征中最好的分裂方案进行分裂。
经典梯度提升方法
梯度提升决策树(Gradient Boosting Decision Tree,GBDT)
特点
损失函数为泰勒一阶展开。
优点
- 可解释性强,并能自动发现特征的高阶关系;
- 预测阶段可并行加速;
缺点
- 训练时不能并行,工程加速只能体现在单棵树的构建上;
- 在高维稀疏数据集上表现效果差;(为什么:高维特征导致运行耗时,稀疏特征导致不能有效地进行特征空间切分,对噪声敏感)
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 | 最大叶子节点数量 |
调参过程
借助网格搜索方法:
- 固定一较大的学习率(如lr=0.1),进行n_estimators调优;
- 固定学习率和n_estimators,对树的参数进行调优:max_depth、min_samples_split->min_samples_leaf->max_features
- 降低学习率,确定理想参数。在该参数下,进行多轮次训练,观察和评估模型的拟合、泛化表现。
极致梯度提升(Extreme Gradient Boosting,XGBoost)
与GBDT的对比
- GBDT的损失函数为一阶泰勒展开,XGBoost的损失函数为二阶泰勒展开+正则化;(二阶泰勒展开可以更加精准地逼近真实损失函数,有利于梯度下降得更快更准)
- GBDT的基分类器为CART树,XGBoost的基分类器为CART树或线性分类器;
- GBDT无缺失值的处理,XGBoost通过稀疏感知的方法来处理缺失值;
- XGBoost在算法基础上进行了工程优化;
特点
- 缺失值处理:分裂节点时,将缺失值视为一个整体,提高运算效率,并考虑两个方向。
- 列采样:构建每棵树时随机选择一部分特征,增加模型多样性,防止过拟合。
- 工程并行优化:将每一列的特征提前进行排序,以块的形式存储在缓存中,每次节点分裂重复调用排好序的块即可。
XGBoost防止过拟合的方式
- 正则化
- 行、列采样
- 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 | 节点分裂所需的损失减小最小值 | |
alpha | l1正则化权重项 | |
lambda | l2正则化权重项 | |
eval_metric | 评估指标:rmse(回归任务)、mlogloss(多分类任务)、error(二分类任务)、auc(二分类任务) |
调参过程
借助网格搜索方法:
- 固定一较大的学习率(如lr=0.1),进行n_estimators调优;
- 固定学习率和n_estimators,对树的参数进行调优:min_child_weight、max_depth->gamma->subsample、colsample_bytree
- 正则化参数alpha、lambda调优
- 降低学习率,确定理想参数。在该参数下,进行多轮次训练,观察和评估模型的拟合、泛化表现。
调参经验总结
- 固定一较大的学习率(如lr=0.1),进行n_estimators调优;
- 固定学习率和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
- (正则化参数alpha、lambda调优)
- 降低学习率,确定理想参数。在该参数下,进行多轮次训练,观察和评估模型的拟合、泛化表现。