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

XGBoost算法Python代码实现

### XGBoost定义
class XGBoost:
    def __init__(self, n_estimators=300, learning_rate=0.001, 
                 min_samples_split=2,
                 min_gini_impurity=999, 
                 max_depth=2):
        # 树的棵数
        self.n_estimators = n_estimators
        # 学习率
        self.learning_rate = learning_rate 
        # 结点分裂最小样本数
        self.min_samples_split = min_samples_split 
        # 结点最小基尼不纯度
        self.min_gini_impurity = min_gini_impurity  
        # 树最大深度
        self.max_depth = max_depth                  
        # 用于分类的对数损失
        # 回归任务可定义平方损失 
        # self.loss = SquaresLoss()
        self.loss = LogisticLoss()
        # 初始化分类树列表
        self.trees = []
        # 遍历构造每一棵决策树
        for _ in range(n_estimators):
            tree = XGBoost_Single_Tree(
                    min_samples_split=self.min_samples_split,
                    min_gini_impurity=self.min_gini_impurity,
                    max_depth=self.max_depth,
                    loss=self.loss)
            self.trees.append(tree)
    
    # xgboost拟合方法
    def fit(self, X, y):
        y = cat_label_convert(y)
        y_pred = np.zeros(np.shape(y))
        # 拟合每一棵树后进行结果累加
        for i in range(self.n_estimators):
            tree = self.trees[i]
            y_true_pred = np.concatenate((y, y_pred), axis=1)
            tree.fit(X, y_true_pred)
            iter_pred = tree.predict(X)
            y_pred -= np.multiply(self.learning_rate, iter_pred)

    # xgboost预测方法
    def predict(self, X):
        y_pred = None
        # 遍历预测
        for tree in self.trees:
            iter_pred = tree.predict(X)
            if y_pred is None:
                y_pred = np.zeros_like(iter_pred)
            y_pred -= np.multiply(self.learning_rate, iter_pred)
        y_pred = np.exp(y_pred) / np.sum(np.exp(y_pred), axis=1, keepdims=True)
        # 将概率预测转换为标签
        y_pred = np.argmax(y_pred, axis=1)
        return y_pred

这段代码定义了一个名为 XGBoost 的类,旨在实现 XGBoost 的基础功能,包括梯度提升树的训练和预测。以下是对代码的详细解读:


代码功能和实现逻辑

1. __init__ 方法:初始化模型

功能:

  • 初始化 XGBoost 模型的超参数,包括树的数量、学习率、节点分裂条件、树的最大深度等。
  • 定义损失函数(这里为逻辑回归损失 LogisticLoss),并初始化分类树列表 self.trees

核心代码:

self.n_estimators = n_estimators         # 树的数量
self.learning_rate = learning_rate       # 学习率,用于控制每棵树的贡献
self.min_samples_split = min_samples_split  # 节点最小分裂样本数
self.min_gini_impurity = min_gini_impurity  # 节点最小基尼不纯度
self.max_depth = max_depth               # 树的最大深度
self.loss = LogisticLoss()               # 损失函数
self.trees = []                          # 初始化决策树列表

说明:

  • 每棵树由 XGBoost_Single_Tree 类定义,参数与整体模型的超参数保持一致。
  • 逐一初始化树对象并存储在 self.trees 列表中。

2. fit 方法:训练模型

功能:

  • 拟合训练数据集 ( X , y ) (X, y) (X,y)
  • 对每棵树,基于当前的残差拟合新的决策树,逐步逼近目标函数。

实现步骤:

  1. 初始化预测值
    使用 y_pred = np.zeros(np.shape(y)) 初始化所有样本的预测值为零。

  2. 训练每一棵树

    • 计算当前的真实值和预测值组合 ( y , y pred ) (y, y_{\text{pred}}) (y,ypred),作为树的输入。
    • 调用 tree.fit(X, y_true_pred) 训练当前树。
    • 使用当前树对样本进行预测,并更新累积预测值 y_pred
  3. 更新规则

    • 累积预测值更新规则:
      y pred ( i + 1 ) = y pred ( i ) − η ⋅ tree.predict ( X ) y_{\text{pred}}^{(i+1)} = y_{\text{pred}}^{(i)} - \eta \cdot \text{tree.predict}(X) ypred(i+1)=ypred(i)ηtree.predict(X)
      其中, η \eta η 是学习率, tree.predict ( X ) \text{tree.predict}(X) tree.predict(X) 是当前树对样本的预测。

核心代码:

y_pred = np.zeros(np.shape(y))  # 初始化预测值
for i in range(self.n_estimators):
    tree = self.trees[i]
    y_true_pred = np.concatenate((y, y_pred), axis=1)  # 组合真实值和预测值
    tree.fit(X, y_true_pred)                           # 训练当前树
    iter_pred = tree.predict(X)                        # 当前树的预测值
    y_pred -= np.multiply(self.learning_rate, iter_pred)  # 累加预测值

3. predict 方法:模型预测

功能:

  • 使用训练好的树集对测试数据 X X X 进行预测。
  • 基于累积预测值,通过 softmax 转换为概率分布,再将概率转换为分类标签。

实现步骤:

  1. 初始化预测值
    使用 y_pred = None 初始化预测值。

  2. 累积预测值

    • 遍历每棵树,逐一计算预测值。
    • 累积预测值更新规则与训练一致:
      y pred = y pred − η ⋅ tree.predict ( X ) y_{\text{pred}} = y_{\text{pred}} - \eta \cdot \text{tree.predict}(X) ypred=ypredηtree.predict(X)
  3. 概率转换

    • 使用 softmax 函数将累积预测值转换为概率分布:
      p ( y ) = exp ⁡ ( y pred ) ∑ exp ⁡ ( y pred ) p(y) = \frac{\exp(y_{\text{pred}})}{\sum \exp(y_{\text{pred}})} p(y)=exp(ypred)exp(ypred)
  4. 分类标签转换

    • 对 softmax 的概率结果,取最大值的索引作为最终分类结果。

核心代码:

for tree in self.trees:
    iter_pred = tree.predict(X)
    if y_pred is None:
        y_pred = np.zeros_like(iter_pred)
    y_pred -= np.multiply(self.learning_rate, iter_pred)  # 累积预测值

y_pred = np.exp(y_pred) / np.sum(np.exp(y_pred), axis=1, keepdims=True)  # 转换为概率
y_pred = np.argmax(y_pred, axis=1)  # 转换为分类标签
return y_pred

核心公式总结

  1. 训练时更新规则
    y pred ( i + 1 ) = y pred ( i ) − η ⋅ tree.predict ( X ) y_{\text{pred}}^{(i+1)} = y_{\text{pred}}^{(i)} - \eta \cdot \text{tree.predict}(X) ypred(i+1)=ypred(i)ηtree.predict(X)

  2. 预测时 softmax 转换
    p ( y ) = exp ⁡ ( y pred ) ∑ exp ⁡ ( y pred ) p(y) = \frac{\exp(y_{\text{pred}})}{\sum \exp(y_{\text{pred}})} p(y)=exp(ypred)exp(ypred)


总结

这段代码实现了一个基础的 XGBoost 算法,涵盖了梯度提升的核心逻辑和分类预测流程。尽管与正式的 XGBoost 实现相比有所简化,但它提供了一个清晰的框架,适合用于理解 XGBoost 的原理和实现方式。在实际应用中,可以根据需求扩展功能,提升模型性能和效率。


http://www.kler.cn/a/389325.html

相关文章:

  • 学术论文写作丨机器学习与深度学习
  • C# 委托与匿名方法
  • react 中 FC 模块作用
  • 红帽认证和华为认证哪个好?看完这4点你就明白了
  • GitHub Org
  • 力扣 LeetCode 142. 环形链表II(Day2:链表)
  • Iceberg 写入和更新模式,COW,MOR(Copy-on-Write,Merge-on-Read)
  • sqli-labs(第二关)
  • ThinkBook 14+ 2024 Ubuntu 触控板失效 驱动缺失问题解决
  • 腾讯自研的 Git 客户端!!【送源码】
  • vue3中使用输入框按回车键刷新页面问题
  • 零拷贝Zero Copy
  • RabbitMQ的应用
  • 【STK学习】part1-卫星轨道与Walker星座基础知识
  • 《TCP/IP网络编程》学习笔记 | Chapter 4:基于TCP的服务器端/客户端(1)
  • 信息泄露漏洞一文速通
  • Facebook vs. Google:哪个更适合你的品牌
  • rabbitMq怎么保证消息不丢失?消费者没有接收到消息怎么处理
  • MySQL_聚合函数分组查询
  • 【神经科学学习笔记】基于分层嵌套谱分割(Nested Spectral Partition)模型分析大脑网络整合与分离的学习总结
  • 无人机手势控制工作原理和算法!
  • 【笔记】开关电源变压器设计 - 工作磁通的选择原则
  • 机器学习中的两种主要思路:数据驱动与模型驱动
  • Stable Diffusion WebUI或ComfyUI下载不了huggingface?修改huggingface为国内镜像地址方法在这里
  • 计算用户订购率梧桐数据库和oracle数据库sql分析
  • 关于elementui el-radio 赋值问题