当前位置: 首页 > news >正文

分类算法——XGBoost 详解

XGBoost 的底层原理与实现

        XGBoost(eXtreme Gradient Boosting)是一种高效的梯度提升算法(Gradient Boosting),它通过组合多个弱学习器(通常是决策树)来构建强大的模型。XGBoost 在算法层面上优化了传统的梯度提升树(GBT),在速度和准确性上都有显著的提升。

以下是对 XGBoost 的底层原理和实现细节的详细解析:


1. XGBoost 的基本概念

  • 梯度提升:一种通过构建多个弱学习器(如决策树)逐步提升模型性能的算法。每一步的目标是根据前一步的误差来构建新的模型,使模型误差逐渐减少。
  • 弱学习器:通常是决策树,XGBoost 使用 CART(Classification And Regression Tree)作为基本单元,每棵树试图拟合之前模型的误差(残差)。
  • 目标函数:在 XGBoost 中定义为损失函数与正则化项的和,正则化项通过控制树的复杂度来防止过拟合。

2. XGBoost 的目标函数

        XGBoost 的目标函数可以分为两部分:损失函数和正则化项。具体表示为:

  • L\left ( y_{i},\hat{y_{i}} \right )表示损失函数,用于衡量模型预测值 \hat{y_{i}}​ 和真实值 y_{i}​ 的差距。
  • \Omega (f_{k}) 表示正则化项,用于控制每棵树的复杂度。XGBoost 使用 L_{2} 正则化来限制树的叶节点数和节点权重,从而防止过拟合。

        对于第 t 轮迭代,假设我们有 t−1 颗树,第 t 颗树的增量预测值为 f_{t}(x),于是可以写出第 t 轮的预测值:

\hat{y}_{i}^{(t-1)} +f_{t}(xi)

目标函数的二次近似展开

为了便于求解,将目标函数通过泰勒展开式近似为二次形式:

其中:

  • g_{i}=\partial _{\hat{y}_{i}^{(t-1)}}L(y_{i},\hat{y}_{i}^{(t-1)}) 是一阶导数,代表当前预测值的梯度。
  • hi= \partial _{\hat{y}^{(t-1)}}^{2} *L(y_{i},\hat{y}_{i}^{(t-1)}) 是二阶导数,代表当前预测值的曲率(即 Hessian)。

XGBoost 利用一阶和二阶信息来构建树,提高了模型对损失的精确逼近。

3. 树的构建与叶节点分裂

在每轮迭代中,XGBoost 通过最小化目标函数来构建新的树。主要包括以下步骤:

  1. 叶节点的增益计算

    • 在每个分裂点,计算该分裂点的增益。增益表示分裂后误差的减少量。对于一个分裂点,增益可以表示为:

      其中:

      • G_{L}G_{R}​ 为左子节点和右子节点的梯度和,H_{L}H_{R}​​ 为左子节点和右子节点的 Hessian 和。
      • λ 为正则化参数,用于控制叶节点权重的大小。
      • \gamma 为惩罚项,限制树的叶节点数,防止树过于复杂。
  2. 选择最佳分裂点

           计算每个特征的所有可能分裂点的增益,选择增益最大的分裂点作为当前节点的最优分裂。
  3. 叶节点权重的确定

    • 对于每个叶节点,XGBoost 会基于损失函数的二阶信息来优化其权重 wjwj​,权重的最优值可表示为:

      wj∗=−∑i∈Ijgi∑i∈Ijhi+λwj∗​=−∑i∈Ij​​hi​+λ∑i∈Ij​​gi​​

    其中 I_{j} 为叶节点 j 包含的样本集合。

4. XGBoost 的正则化

        正则化项是 XGBoost 的核心改进之一,通过控制树的结构复杂度来减少过拟合。正则化项包括两个部分:

  • 叶节点权重的 L_{2} 正则化:通过对每个叶节点的权重施加 L_{2} 正则化,使得权重不会过大,防止模型对特定样本过度拟合。
  • 叶节点数的惩罚项:通过对树的叶节点数量进行惩罚,防止生成过深的树。

5. XGBoost 的特性优化

  • 列抽样(Column Subsampling):每棵树训练时随机选择部分特征,增加模型的多样性,减少过拟合。
  • 并行化计算:对每个特征的分裂增益进行并行计算,加速树的构建。
  • Shrinkage(缩减):类似于学习率,在每棵树的预测上乘以一个缩减系数,防止步长过大导致的模型震荡。
  • 缺失值处理:XGBoost 能够自动处理缺失值,通过最优分裂自动调整数据分布。

XGBoost 的源代码实现

以下是使用 Python 和 xgboost 库实现 XGBoost 分类算法的源代码示例。

# 导入相关库
import xgboost as xgb
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score# 加载数据
data = load_iris()
X, y = data.data, data.target# 将数据分成训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)# 创建 DMatrix 数据结构,这是 XGBoost 特有的数据格式,优化存储和计算速度
dtrain = xgb.DMatrix(X_train, label=y_train)
dtest = xgb.DMatrix(X_test, label=y_test)# 设置参数
params = {'objective': 'multi:softmax',  # 多分类问题'num_class': 3,                # 类别数'max_depth': 3,                # 树的深度'eta': 0.1,                    # 学习率'subsample': 0.8,              # 采样率'colsample_bytree': 0.8        # 列采样
}# 训练模型
num_round = 50  # 训练轮数
bst = xgb.train(params, dtrain, num_round)# 预测
y_pred = bst.predict(dtest)
accuracy = accuracy_score(y_test, y_pred)
print("Accuracy:", accuracy)

源码解读
  1. DMatrix 数据结构:XGBoost 使用 DMatrix 数据结构来存储数据,这种结构在内存使用和计算速度上进行了优化。通过 xgb.DMatrix() 转换原始数据,可以有效地管理数据和标签。

  2. 模型参数

    • objective: 定义任务类型,multi:softmax 表示多分类任务。
    • max_depth: 树的最大深度,控制模型复杂度。
    • eta(学习率):防止每棵树对目标的影响过大,有助于提高模型的泛化能力。
    • subsample 和 colsample_bytree: 控制每棵树构建过程中所使用的样本比例和特征比例,防止过拟合。
  3. 训练过程:使用 xgb.train() 函数进行模型训练,设置了迭代次数 num_round,表示模型构建的弱学习器数量(即树的数量)。

  4. 预测与评估:调用 bst.predict() 进行预测,并使用准确率指标评估模型效果。

XGBoost 的优缺点

优点
  1. 高性能:XGBoost 在梯度提升树算法的基础上进行了优化,速度更快,适用于大规模数据。
  2. 正则化处理:加入了正则化项,有效防止过拟合。
  3. 灵活性:支持多种目标函数和自定义损失函数,可以处理分类和回归等多种任务。
  4. 自动化处理缺失值:在树构建过程中自动处理缺失值,提高了数据处理的灵活性。
缺点
  1. 参数较多:XGBoost 有许多可调参数,参数调整可能较为复杂。
  2. 高内存消耗:由于需要存储大量的中间计算结果,在处理超大数据集时可能面临内存限制。
  3. 不擅长稀疏数据:尽管 XGBoost 能够处理缺失值,但对于稀疏特征表现不如专门的线性模型。

XGBoost 的应用

XGBoost 因其高效性和良好的泛化性能,广泛应用于各类竞赛和实际应用场景中,例如:

  • 金融风控:在信用评分、违约预测等任务中。
  • 推荐系统:用于用户评分、偏好预测等。
  • 医学诊断:在疾病预测、医学图像分类等任务中。

总结

        XGBoost 是一种高效的梯度提升算法,结合了多种优化策略来提高计算速度和模型性能。在底层实现上,XGBoost 通过二阶近似、正则化、并行化等技术来提升模型效果,同时具有灵活的参数和支持多种任务的能力。


http://www.mrgr.cn/news/62575.html

相关文章:

  • 安全运营 -- 监控linux命令history
  • Pycharm,2024最新版Pycharm现在安装环境配置汉化详细教程!
  • 【热门主题】000018 人工智能深度学习模型:探索与应用
  • Linux系统编程——信号量
  • 连续访问内存
  • 江协科技STM32学习- P24 DMA数据转运DMA+AD多通道
  • JAVA开源项目 学生宿舍管理系统 计算机毕业设计
  • AFSim 基础总结一 代码总结(1)
  • TVB被嘲讽工资低,张兆辉得体且高情商的回应,赢得网友赞赏
  • 新能源行业必会基础知识---电力现货问答---第11问---什么是实物合约和金融合约?什么是差价合约?
  • o1背后的秘密:6种推理模式解析!
  • SL3038 降压恒压150V恒压芯片 60V 72V 90V降压IC 电动车控制器芯片
  • Kubernetes(K8s)相关漏洞介绍
  • Java常用设计模式
  • 01背包模板 | 学习总结
  • “无法定位程序输入点kernel32.dll”的错误要怎么处理?一键修复kernel32.dll
  • 算法2(C++实现)
  • React + SpreadJS 开发时常见问题
  • GNN
  • sed awk 第二版学习(八)—— awk 函数
  • socket
  • 代码随想录算法训练营第十九天 | LeetCode77.组合、LeetCode216.组合总和III、LeetCode17.电话号码的字母组合
  • js实现blob类型转化为excel文件
  • 江协科技STM32学习- P27 实验-串口发送/串口接收
  • .NET Core WebApi第4讲:控制器、路由
  • SSM(加载策略、Mybatis缓存)