XGBoost算法Python代码实现

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

核心代码:

python 复制代码
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) 是当前树对样本的预测。

核心代码:

python 复制代码
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 的概率结果,取最大值的索引作为最终分类结果。

核心代码:

python 复制代码
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 的原理和实现方式。在实际应用中,可以根据需求扩展功能,提升模型性能和效率。

相关推荐
计算机学姐12 分钟前
基于Python的高校成绩分析管理系统
开发语言·vue.js·后端·python·mysql·pycharm·django
北京_宏哥16 分钟前
《最新出炉》系列入门篇-Python+Playwright自动化测试-50-滚动条操作
python·前端框架·测试
九年义务漏网鲨鱼19 分钟前
【人脸伪造检测后门攻击】 Exploring Frequency Adversarial Attacks for Face Forgery Detection
论文阅读·python·算法·aigc
天冬忘忧33 分钟前
Spark 共享变量:广播变量与累加器解析
大数据·python·spark
NK.MainJay1 小时前
Go语言 HTTP 服务模糊测试教程
python·http·golang
南宫理的日知录1 小时前
106、Python并发编程:深入浅出理解线程池的内部实现原理
开发语言·python·学习·编程学习
萧鼎1 小时前
Python中的随机数生成与控制:random库实战解析
python·random·随机数
三维重建--小博主2 小时前
人群计数制作私有数据集教程-----自用
python·opencv·计算机视觉
sagima_sdu2 小时前
Python 操作 Neo4J,Python 库 Py2Neo
python·oracle·neo4j
B站计算机毕业设计超人2 小时前
计算机毕业设计Python+Neo4j中华古诗词可视化 古诗词智能问答系统 古诗词数据分析 古诗词情感分析 PyTorch Tensorflow LSTM
pytorch·python·深度学习·机器学习·知识图谱·neo4j·数据可视化