python_梯度提升决策树(GBDT)

前言

提醒:
文章内容为方便作者自己后日复习与查阅而进行的书写与发布,其中引用内容都会使用链接表明出处(如有侵权问题,请及时联系)。
其中内容多为一次书写,缺少检查与订正,如有问题或其他拓展及意见建议,欢迎评论区讨论交流。


分类与回归算法

机器学习中的分类与回归算法是两种主要的监督学习任务,它们分别用于解决不同类型的问题。以下是这两种算法的总结:

  1. 分类算法
    分类算法用于将数据分成不同的类别,适用于输出为离散标签的问题。常见的分类算法包括:

    1. 逻辑回归:使用逻辑函数来估计概率,用于二分类问题,也可以扩展到多分类问题。
    2. 支持向量机(SVM):通过找到最优的决策边界来最大化样本的分类准确率,适用于高维数据。
    3. 决策树:通过树结构来进行决策,每个节点代表一个特征的选择,叶子节点代表分类结果。
    4. 随机森林:由多个决策树组成的集成学习方法,通过投票来决定最终分类结果。
    5. 梯度提升决策树(GBDT):通过构建和结合多个弱学习器来形成强学习器,适用于分类和回归问题。
    6. 朴素贝叶斯:基于贝叶斯定理,假设特征之间相互独立,适用于文本分类等场景。
    7. K近邻(KNN):根据样本之间的距离进行分类,适用于小规模数据集。
    8. 神经网络:通过多层感知机学习数据的复杂模式,适用于图像、语音等复杂分类问题。
  2. 回归算法
    回归算法用于预测连续数值输出,适用于输出为连续变量的问题。常见的回归算法包括:

    1. 线性回归:通过拟合一条直线来预测目标变量的值,是最简单的回归方法。
    2. 岭回归:线性回归的扩展,通过引入L2正则化项来防止过拟合。
    3. Lasso回归:线性回归的另一种扩展,通过引入L1正则化项来进行特征选择。
    4. 弹性网回归:结合了岭回归和Lasso回归,同时引入L1和L2正则化项。
    5. 决策树回归:使用决策树结构来进行回归预测,适用于非线性关系。
    6. 随机森林回归:由多个决策树组成的集成学习方法,通过平均来决定最终回归结果。
    7. 梯度提升决策树回归(GBDT回归):通过构建和结合多个弱学习器来形成强学习器,适用于回归问题。
    8. 支持向量回归(SVR):支持向量机在回归问题上的应用,通过找到最优的决策边界来最大化样本的回归准确率。
    9. 神经网络回归:通过多层感知机学习数据的复杂模式,适用于复杂的回归问题。
  3. 分类与回归算法的比较

    • 输出类型:分类算法输出离散标签,回归算法输出连续数值。
    • 评估指标:分类算法常用准确率、召回率、F1分数等指标,回归算法常用均方误差(MSE)、均方根误差(RMSE)等指标。
    • 问题类型:分类算法适用于类别预测问题,如垃圾邮件检测;回归算法适用于数值预测问题,如房价预测。 在实际应用中,选择分类还是回归算法取决于问题的性质和需求。有时,可以将回归问题转化为分类问题,或者将分类问题转化为回归问题,具体取决于问题的特点和目标。

梯度提升决策树

数学原理

以下是分类算法梯度提升决策树的原理及其数学公式的详细介绍:


  1. 初始化模型

    • 用一个常数模型进行初始化,通常是最小化损失函数的值。例如,对于平方损失,这通常是目标变量的均值。
      F 0 ( x ) = arg ⁡ min ⁡ c ∑ i = 1 n L ( y i , c ) F_0(x) = \arg\min_{c} \sum_{i=1}^{n} L(y_i, c) F0(x)=argcmini=1nL(yi,c)
      这里, F 0 ( x ) = c F_0(x) = c F0(x)=c,其中 c c c 是使损失最小的常数值。
  2. 迭代过程

    • 对于每次迭代 m = 1 m = 1 m=1 M M M
      • 计算残差:损失函数 L L L 关于 F m − 1 ( x ) F_{m-1}(x) Fm1(x) 的负梯度给出了最陡峭的下降方向。
        r i m = − ∂ L ( y i , F m − 1 ( x i ) ) ∂ F m − 1 ( x i ) r_{im} = -\frac{\partial L(y_i, F_{m-1}(x_i))}{\partial F_{m-1}(x_i)} rim=Fm1(xi)L(yi,Fm1(xi))
        这里, r i m r_{im} rim 表示第 i i i 个样本在第 m m m 次迭代时的残差。
      • 训练决策树:训练一个新的树 h m ( x ) h_m(x) hm(x) 来拟合这些残差。
        h m ( x ) = arg ⁡ min ⁡ h ∑ i = 1 n ( r i m − h ( x i ) ) 2 h_m(x) = \arg\min_{h} \sum_{i=1}^{n} (r_{im} - h(x_i))^2 hm(x)=arghmini=1n(rimh(xi))2
        这意味着我们正在寻找一个树 h h h,使其预测值 h ( x i ) h(x_i) h(xi) 尽可能接近残差 r i m r_{im} rim
      • 确定最优步长:通过一个线性搜索来确定一个最优步长 γ m \gamma_m γm,以最小化损失函数。
        γ m = arg ⁡ min ⁡ γ ∑ i = 1 n L ( y i , F m − 1 ( x i ) + γ h m ( x i ) ) \gamma_m = \arg\min_{\gamma} \sum_{i=1}^{n} L\left(y_i, F_{m-1}(x_i) + \gamma h_m(x_i)\right) γm=argγmini=1nL(yi,Fm1(xi)+γhm(xi))
        这个步骤确保我们朝损失函数梯度的反方向移动,同时控制步长以避免过拟合。
      • 更新模型
        F m ( x ) = F m − 1 ( x ) + γ m h m ( x ) F_m(x) = F_{m-1}(x) + \gamma_m h_m(x) Fm(x)=Fm1(x)+γmhm(x)
        这个迭代更新逐步改进模型,使其更准确地拟合数据。
  3. 最终模型

    • M M M 次迭代后,组合所有树来形成最终的预测模型。
      F M ( x ) = F 0 ( x ) + ∑ m = 1 M γ m h m ( x ) F_M(x) =F_0(x)+ \sum_{m=1}^{M} \gamma_m h_m(x) FM(x)=F0(x)+m=1Mγmhm(x)
      这个最终模型是所有单个决策树的加权组合,每个树都针对前一个模型的残差进行优化。

具体损失函数

  • 平方损失(回归)
    L ( y , F ( x ) ) = ( y − F ( x ) ) 2 L(y, F(x)) = (y - F(x))^2 L(y,F(x))=(yF(x))2
    这里的负梯度是:
    r i m = y i − F m − 1 ( x i ) r_{im} = y_i - F_{m-1}(x_i) rim=yiFm1(xi)
  • 对数损失(二元分类)
    L ( y , F ( x ) ) = log ⁡ ( 1 + e − y F ( x ) ) L(y, F(x)) = \log(1 + e^{-y F(x)}) L(y,F(x))=log(1+eyF(x))
    这里的负梯度是:
    r i m = − y i 1 + e y i F m − 1 ( x i ) r_{im} = \frac{-y_i}{1 + e^{y_i F_{m-1}(x_i)}} rim=1+eyiFm1(xi)yi

通过这种方式,GBDT 通过逐步添加针对残差的树来最小化损失函数,构建了一个强大的分类或回归模型。

总结:
GBDT通过迭代优化模型,最小化损失函数  L ( y , F ( x ) ) 。 初始化  F 0 ( x )  为最小化  ∑ i = 1 n L ( y i , c )  的常数值  c 。 对于每次迭代  m = 1  到  M : 1.  计算残差  r i m = − ∂ L ( y i , F m − 1 ( x i ) ) ∂ F m − 1 ( x i ) 。 2.  训练一个决策树  h m ( x )  来拟合  r i m ,最小化  ∑ i = 1 n ( r i m − h ( x i ) ) 2 。 3.  确定最优步长  γ m = arg ⁡ min ⁡ γ ∑ i = 1 n L ( y i , F m − 1 ( x i ) + γ h m ( x i ) ) 。 4.  更新模型  F m ( x ) = F m − 1 ( x ) + γ m h m ( x ) 。 经过  M  次迭代后,最终模型为  F M ( x ) = F 0 ( x ) + ∑ m = 1 M γ m h m ( x ) 。 \mathbf{ \begin{aligned} &\text{GBDT通过迭代优化模型,最小化损失函数 } L(y, F(x)) \text{。} \\ &\text{初始化 } F_0(x) \text{ 为最小化 } \sum_{i=1}^{n} L(y_i, c) \text{ 的常数值 } c \text{。} \\ &\text{对于每次迭代 } m = 1 \text{ 到 } M\text{:} \\ &\quad 1.\ \text{计算残差 } r_{im} = -\frac{\partial L(y_i, F_{m-1}(x_i))}{\partial F_{m-1}(x_i)} \text{。} \\ &\quad 2.\ \text{训练一个决策树 } h_m(x) \text{ 来拟合 } r_{im} \text{,最小化 } \sum_{i=1}^{n} (r_{im} - h(x_i))^2 \text{。} \\ &\quad 3.\ \text{确定最优步长 } \gamma_m = \arg\min_{\gamma} \sum_{i=1}^{n} L\left(y_i, F_{m-1}(x_i) + \gamma h_m(x_i)\right) \text{。} \\ &\quad 4.\ \text{更新模型 } F_m(x) = F_{m-1}(x) + \gamma_m h_m(x) \text{。} \\ &\text{经过 } M \text{ 次迭代后,最终模型为 } F_M(x) =F_0(x)+ \sum_{m=1}^{M} \gamma_m h_m(x) \text{。} \end{aligned} } GBDT通过迭代优化模型,最小化损失函数 L(y,F(x))初始化 F0(x) 为最小化 i=1nL(yi,c) 的常数值 c对于每次迭代 m=1  M1. 计算残差 rim=Fm1(xi)L(yi,Fm1(xi))2. 训练一个决策树 hm(x) 来拟合 rim,最小化 i=1n(rimh(xi))23. 确定最优步长 γm=argγmini=1nL(yi,Fm1(xi)+γhm(xi))4. 更新模型 Fm(x)=Fm1(x)+γmhm(x)经过 M 次迭代后,最终模型为 FM(x)=F0(x)+m=1Mγmhm(x)

手动实现

import numpy as np
from sklearn.tree import DecisionTreeRegressor
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score


class GBDTClassifier:
    def __init__(self, n_estimators=100, learning_rate=0.1, max_depth=3):
        self.n_estimators = n_estimators
        self.learning_rate = learning_rate
        self.max_depth = max_depth
        self.trees = []

    def sigmoid(self, x):
        return 1 / (1 + np.exp(-x))

    def fit(self, X, y):
        # 初始化预测值为 0
        f0 = np.zeros(len(y))
        self.f0 = f0

        for _ in range(self.n_estimators):
            # 计算负梯度(残差)
            y_pred = self.sigmoid(f0)
            residuals = y - y_pred

            # 训练一棵决策树来拟合残差
            tree = DecisionTreeRegressor(max_depth=self.max_depth)
            tree.fit(X, residuals)

            # 更新预测值
            f0 += self.learning_rate * tree.predict(X)

            # 保存决策树
            self.trees.append(tree)

    def predict_proba(self, X):
        # 初始预测值
        f = np.zeros(len(X)) + self.f0[0]

        for tree in self.trees:
            f += self.learning_rate * tree.predict(X)

        return self.sigmoid(f)

    def predict(self, X):
        y_pred_proba = self.predict_proba(X)
        return (y_pred_proba > 0.5).astype(int)


# 示例
if __name__ == "__main__":
    # 生成一个二分类数据集
    X, y = make_classification(n_samples=1000, n_features=10, n_informative=5, n_redundant=0, random_state=42)

    # 划分训练集和测试集
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

    # 创建并训练 GBDT 分类器
    gbdt = GBDTClassifier(n_estimators=100, learning_rate=0.1, max_depth=3)
    gbdt.fit(X_train, y_train)

    # 进行预测
    y_pred = gbdt.predict(X_test)

    # 计算准确率
    accuracy = accuracy_score(y_test, y_pred)
    print(f"Accuracy: {accuracy:.2f}")

运行结果:

在这里插入图片描述

python函数库实现

from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.metrics import accuracy_score

# 创建一个二分类数据集
X, y = make_classification(n_samples=1000, n_features=20, n_informative=2, n_redundant=10, random_state=42)

# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 初始化GBDT分类器
gbdt = GradientBoostingClassifier(n_estimators=100, learning_rate=0.1, max_depth=3, random_state=42)

# 训练模型
gbdt.fit(X_train, y_train)

# 预测测试集
y_pred = gbdt.predict(X_test)

# 计算准确率
accuracy = accuracy_score(y_test, y_pred)
print(f"Accuracy: {accuracy}")

# 输出预测概率
print("Predicted probabilities:", gbdt.predict_proba(X_test)[:5])  # 只展示前5个样本的概率

运行结果:
在这里插入图片描述

GBDT实现多元分类

1. One-vs-All(OvA)策略

在 One-vs-All 策略中,对于每个类别,训练一个二分类模型,将该类别与其他所有类别区分开来。具体步骤如下:

  1. 数据预处理

    • 对输入数据进行标准化处理,确保数据在相同的尺度上。
  2. 模型训练

    • 对于每个类别 k k k,训练一个二分类模型,将类别 k k k 标记为正类,其他类别标记为负类。
    • 使用 GBDT 训练每个二分类模型。
  3. 预测

    • 对新的输入数据,计算每个二分类模型的预测概率。
    • 选择概率最高的类别作为最终预测结果。

2. Softmax 多分类策略

在 Softmax 多分类策略中,直接将 GBDT 扩展为多分类模型,通过 Softmax 函数计算每个类别的概率。具体步骤如下:

  1. 数据预处理

    • 对输入数据进行标准化处理,确保数据在相同的尺度上。
  2. 模型训练

    • 使用 GBDT 训练一个多分类模型,损失函数采用 Softmax 损失(交叉熵损失)。
    • 每次迭代中,计算每个类别的残差,并训练一个决策树来拟合这些残差。
  3. 预测

    • 对新的输入数据,计算每个类别的预测值。
    • 使用 Softmax 函数将预测值转换为概率,选择概率最高的类别作为最终预测结果。

python函数库实现

以下是一个基于 sklearn 的 GBDT 多分类实现示例,使用 One-vs-All 策略:

from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.preprocessing import LabelBinarizer
from sklearn.metrics import accuracy_score

# 加载数据集
data = load_iris()
X = data.data
y = data.target

# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)

# 初始化 GBDT 分类器
gbdt = GradientBoostingClassifier(n_estimators=100, learning_rate=0.1, max_depth=3)

# 训练模型
gbdt.fit(X_train, y_train)

# 预测测试集
y_pred = gbdt.predict(X_test)

# 评估模型
print("Accuracy:", accuracy_score(y_test, y_pred))

运行结果:

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值