通过Python解释梯度提升分类

2025年1月5日 | 阅读6分钟

集成方法

总的来说,你应该想利用你所有的优秀预测器,而不是痛苦地只选择一个,因为它能带来 0.0001 的准确率提升。这时集成学习就派上用场了。集成学习通过使用多个预测器并在数据上进行训练,而不是只使用一个预测器,通常能产生比单一模型更好的结果。例如,随机森林就是一堆复制粘贴的决策树。

集成方法就像一个管弦乐队,其中有几位音乐家演奏不同的乐器,而不是只有一位,通过结合所有乐器的演奏,整体的音乐效果比由一位独奏者演奏要好。

梯度增强更确切地说是一种增强技术,而不是一种集成学习方法。那么,什么是增强呢?

Boosting

增强是一种特殊的集成学习策略,它通过合并多个弱学习器(准确性差的预测器)来创建一个强学习器(准确性高的模型)。为了实现这一点,每个模型都会从其前一个模型的错误中学习。

增强中最常用的两种技术是

  • 自适应增强(我的论文中已对此主题进行了介绍)
  • 梯度提升

我们将要讨论梯度增强。

梯度提升

在梯度增强中,每个预测器都试图通过减少错误来改进其前驱。但梯度增强背后的有趣想法是,它不是在每次迭代时都对数据进行拟合预测器,而是实际上拟合一个新的预测器来拟合前一个预测器产生的残差错误。让我们通过一个逐步的例子来了解梯度增强分类是如何工作的。

  1. 为了对数据进行早期预测,算法将获取目标特征的几率对数。这通常是通过将总的真值(值为 1)的数量除以总的假值(值为 0)的数量来计算的。
    因此,如果我们有一个包含六个乳腺癌病例的数据集,其中有四个个体患有乳腺癌(四个目标值=1)和两个个体没有乳腺癌(两个目标值=0),那么 log(odds) = log(4/2) ≈ 0.7。这是我们的基本估计器。
  2. 为了进行预测,我们使用逻辑函数将 log(odds) 值转换为概率。按照我们上一个例子中 0.7 的 log(odds) 值,逻辑函数也将约为 0.7。
  3. 鉴于此数字大于 0.5,算法对每个实例的基本猜测将为 0.7。下面的公式可用于将 log(odds) 转换为概率
  • 它计算训练集中每个实例的残差,或者换句话说,观察值减去预测值。
  • 完成此操作后,它会构建一个新的决策树,试图预测先前确定的残差。但在这里,它变得比梯度增强回归复杂一些。

在创建决策树时,最多可以使用一定数量的叶子。用户可以将其指定为参数;它通常在 8 到 32 之间。这会导致两种潜在结果

  • 多个实例合并到一个叶子中
  • 每个实例都有自己的叶子。

与梯度增强回归不同,后者我们可以简单地对实例值进行平均以获得输出值,并让单个实例成为其自身的叶子,我们现在必须使用以下公式来修改这些值

Gradient Boosting Classification Explained Through Python

符号 Σ 表示“总和”,PreviousProb 表示我们之前计算的概率,在本例中为 0.7。此修改应用于树中的每个叶子。我们为什么要这样做?我们不能简单地将它们结合起来,因为它们来自两个不同的源,正如您可能还记得的那样,我们的基本估计器是 log(odds),而我们的树实际上是基于概率构建的。

进行预测

现在,我们进行两步来创建新的预测

  1. 获取训练集中每个实例的 log(odds) 预测。
  2. 将预测转换为概率。

以下是预测训练集中每个实例的公式

一个称为 learning_rate 的超参数用于缩放每个树的贡献,从而以增加方差为代价放弃偏差。为了防止数据过拟合,我们用这个数字乘以预期值。

使用将 log(odds) 值转换为概率的先前过程,一旦我们计算出 log(odds) 预测,我们就必须将其转换为概率。

重复并猜测未见过的信息

遵循此过程,我们计算树的更新残差并构建一棵新树来拟合更新后的残差。然后一遍又一遍地重复该过程,直到残差最小或达到某个阈值。

使用我们由六棵树组成的训练集对新情况进行预测的伪代码如下

现在您对梯度增强分类的原理有了基本了解,让我们开始学习一些代码来巩固我们的理解!

使用 Scikit-Learn 进行梯度增强分类

我们将使用的数据集是 scikit-learn 预置的乳腺癌数据集。首先,让我们先弄清楚一些导入

说明

该代码导入了机器学习和数据分析所需的库和模块。它使用 Pandas 和 NumPy 来处理数据,并加载数据集、运行交叉验证以及评估分类模型。使用 load_breast_cancer 函数加载乳腺癌数据集,并使用 GradientBoostingClassifier 构建分类模型。使用 KFold 进行交叉验证,并使用 classification_report 生成全面的分类性能报告。

为了评估模型的性能,我们只导入了 pandas、numpy、我们的模型和一个度量指标。

说明

这行代码加载了 sklearn 库中的乳腺癌数据集,并构建了一个以特征名称作为列的 DataFrame。然后显示 DataFrame 的前五行,并添加一个名为“y”的新列,其中包含目标标签——乳腺癌诊断。

由于处理 DataFrame 更方便,我们将数据转换为该格式。您可以随意省略此步骤。

在这里,我们指定我们的特征和标签,并使用 5 折交叉验证将您的数据分成训练集和验证集。

说明

通过将 DataFrame (df) 中的目标变量 (y) 与特征集 (X) 分离,此代码中指定了 X 和 y。为了可重复性,使用随机状态和打乱构建了一个 5 折交叉验证对象 kf。在 for 循环遍历 kf 生成的分割时,将训练和验证索引分配给 train_index 和 val_index。对于每一折,然后使用这些索引将 X 和 Y 分成训练集和验证集。使用 0.1 的学习率,构建了一个 GradientBoostingClassifier,并使用 get_params() 获取其参数。

输出

 
{'ccp_alpha': 0.0,
 'criterion': 'friedman_mse',
 'init': None,
 'learning_rate': 0.1,
 'loss': 'deviance',
 'max_depth': 3,
 'max_features': None,
 'max_leaf_nodes': None,
 'min_impurity_decrease': 0.0,
 'min_impurity_split': None,
 'min_samples_leaf': 1,
 'min_samples_split': 2,
 'min_weight_fraction_leaf': 0.0,
 'n_estimators': 100,
 'n_iter_no_change': None,
 'presort': 'deprecated',
 'random_state': None,
 'subsample': 1.0,
 'tol': 0.0001,
 'validation_fraction': 0.1,
 'verbose': 0,
 'warm_start': False}   

有几个方面需要考虑,所以我将在这里重点介绍最关键的方面

  • 准则: 确定数据分割的最佳特征和阈值的损失函数
  • learning_rate: 此选项为每个树的贡献设定了一个尺度
  • max_depth: 此参数为每棵树设定了最大深度。
  • n_estimators: 要构建的树的数量
  • Init: 初始估计器。默认情况下,它是转换为概率的 log(odds)(正如我们之前解释的)。

说明

在训练集数据 (X_train, y_train) 上的梯度增强模型后,该代码通过打印分类报告来评估模型在验证集数据 (X_val, y_val) 上的性能。对于每个类别,报告提供了 F1 分数、召回率和准确率等数据。

输出

 
precision    recall   f1-score   support
0       0.98      0.93      0.96        46
1       0.96      0.99      0.97        67
    accuracy                           0.96       113
   macro avg       0.97      0.96      0.96       113
weighted avg       0.96      0.96      0.96       113   

好的,准确率为 96%!