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

相关推荐
sp_fyf_202420 分钟前
【大语言模型】ACL2024论文-19 SportsMetrics: 融合文本和数值数据以理解大型语言模型中的信息融合
人工智能·深度学习·神经网络·机器学习·语言模型·自然语言处理
编程修仙31 分钟前
Collections工具类
linux·windows·python
芝麻团坚果1 小时前
对subprocess启动的子进程使用VSCode python debugger
linux·ide·python·subprocess·vscode debugger
EterNity_TiMe_1 小时前
【论文复现】神经网络的公式推导与代码实现
人工智能·python·深度学习·神经网络·数据分析·特征分析
Stara05111 小时前
Git推送+拉去+uwsgi+Nginx服务器部署项目
git·python·mysql·nginx·gitee·github·uwsgi
hence..2 小时前
Vscode写markdown快速插入python代码
ide·vscode·python
DanielYQ2 小时前
LCR 001 两数相除
开发语言·python·算法
sp_fyf_20242 小时前
【大语言模型】ACL2024论文-18 MINPROMPT:基于图的最小提示数据增强用于少样本问答
人工智能·深度学习·神经网络·目标检测·机器学习·语言模型·自然语言处理
爱喝白开水a3 小时前
Sentence-BERT实现文本匹配【分类目标函数】
人工智能·深度学习·机器学习·自然语言处理·分类·bert·大模型微调
vener_3 小时前
LuckySheet协同编辑后端示例(Django+Channel,Websocket通信)
javascript·后端·python·websocket·django·luckysheet