Python 中的极端梯度提升(XGBoost)集成

极限梯度提升 (XGBoost) 是一个开源库,它提供了梯度提升算法的高效实现。

尽管在 XGBoost 之前就存在其他开源实现,但 XGBoost 的发布似乎释放了该技术的强大功能,并使应用机器学习社区更普遍地关注梯度提升。

在开发和首次发布后不久,XGBoost 成为机器学习竞赛中分类和回归问题获胜解决方案的首选方法,并且通常是其中的关键组件。

在本教程中,您将学习如何开发用于分类和回归的极限梯度提升集成。

完成本教程后,您将了解:

  • 极限梯度提升是随机梯度提升集成算法的高效开源实现。
  • 如何使用 scikit-learn API 开发用于分类和回归的 XGBoost 集成。
  • 如何探究 XGBoost 模型超参数对模型性能的影响。

使用我的新书《Python 集成学习算法启动您的项目,其中包括逐步教程和所有示例的Python 源代码文件

让我们开始吧。

Extreme Gradient Boosting (XGBoost) Ensemble in Python

Python 中的极端梯度提升(XGBoost)集成
图片由 Andrés Nieto Porras 提供,保留部分权利。

教程概述

本教程分为三个部分;它们是:

  1. 极限梯度提升算法
  2. XGBoost Scikit-Learn API
    1. 用于分类的 XGBoost 集成
    2. 用于回归的 XGBoost 集成
  3. XGBoost 超参数
    1. 探索树的数量
    2. 探索树深度
    3. 探索学习率
    4. 探索样本数量
    5. 探索特征数量

极限梯度提升算法

梯度提升是指一类集成机器学习算法,可用于分类或回归预测建模问题。

集成模型由决策树模型构建。树被一个接一个地添加到集成中,并进行拟合以纠正先前模型所做的预测错误。这是一种被称为“提升”的集成机器学习模型。

模型使用任何任意可微损失函数和梯度下降优化算法进行拟合。这赋予了该技术“梯度提升”的名称,因为在模型拟合时,损失梯度被最小化,很像神经网络。

有关梯度提升的更多信息,请参阅本教程。

极限梯度提升,简称 XGBoost,是梯度提升算法的高效开源实现。因此,XGBoost 既是一种算法,也是一个开源项目,同时也是一个 Python 库。

它最初由 陈天奇 开发,并由陈和 Carlos Guestrin 在 2016 年题为“XGBoost:一个可伸缩的树提升系统”的论文中进行了描述。

它旨在兼具计算效率(例如,执行速度快)和高效性,可能比其他开源实现更有效。

然而,xgboost 这个名字实际上指的是工程目标,即突破提升树算法的计算资源限制。这也是许多人使用 xgboost 的原因。

— 陈天奇,在 Quora 回答“R gbm(梯度提升机)和 xgboost(极限梯度提升)有什么区别?”这个问题时说。

使用 XGBoost 的两个主要原因是执行速度和模型性能。

通常,与其他梯度提升实现相比,XGBoost 速度更快。Szilard Pafka 进行了一些客观基准测试,比较了 XGBoost 与其他梯度提升和袋装决策树实现的性能。他在 2015 年 5 月在题为“基准测试随机森林实现”的博客文章中写下了他的结果。

他的结果表明,XGBoost 几乎总是比来自 R、Python Spark 和 H2O 的其他基准测试实现更快。

他的实验评论道:

我还尝试了 xgboost,这是一个流行的提升库,也能够构建随机森林。它速度快、内存效率高且准确度高。

随机森林实现基准测试,Szilard Pafka,2015。

XGBoost 在分类和回归预测建模问题上主导结构化或表格数据集。证据表明,它是 Kaggle 竞争数据科学平台比赛获胜者的首选算法。

在 2015 年 Kaggle 博客上发布的 29 个挑战获胜解决方案中,有 17 个解决方案使用了 XGBoost。 […] 该系统在 KDDCup 2015 中也取得了成功,前 10 名的每个获胜团队都使用了 XGBoost。

XGBoost: A Scalable Tree Boosting System, 2016。

现在我们已经熟悉了 XGBoost 是什么以及它为什么重要,接下来我们仔细研究一下如何在我们的预测建模项目中使用它。

想开始学习集成学习吗?

立即参加我为期7天的免费电子邮件速成课程(附示例代码)。

点击注册,同时获得该课程的免费PDF电子书版本。

XGBoost Scikit-Learn API

XGBoost 可以作为一个独立的库安装,并且可以使用 scikit-learn API 开发 XGBoost 模型。

第一步是安装 XGBoost 库(如果尚未安装)。这可以通过在大多数平台上使用 pip python 包管理器来实现;例如:

然后,您可以通过运行以下脚本来确认 XGBoost 库已正确安装并可以使用。

运行脚本将打印您已安装的 XGBoost 库的版本。

您的版本应该相同或更高。否则,您必须升级您的 XGBoost 库版本。

您可能会遇到最新版本库的问题。这不是您的错。

有时,最新版本的库会施加额外的要求或可能不太稳定。

如果您在尝试运行上述脚本时遇到错误,我建议降级到 1.0.1 版(或更低)。这可以通过在 pip 命令中指定要安装的版本来实现,如下所示:

如果您看到警告消息,现在可以安全地忽略它。例如,以下是您可能会看到并可以忽略的警告消息示例:

如果您需要特定于您的开发环境的说明,请参阅教程:

XGBoost 库有其自己的自定义 API,尽管我们将通过 scikit-learn 封装类使用该方法:XGBRegressorXGBClassifier。这将使我们能够使用 scikit-learn 机器学习库中的全套工具来准备数据和评估模型。

这两个模型的运行方式相同,并接受相同的参数,这些参数影响决策树的创建和添加到集成中的方式。

模型构建中使用了随机性。这意味着每次在相同数据上运行算法时,它都会生成一个略有不同的模型。

当使用具有随机学习算法的机器学习算法时,通过对多次运行或重复交叉验证的性能进行平均来评估它们是一个好习惯。在拟合最终模型时,可能需要增加树的数量,直到模型在重复评估中的方差减小,或者拟合多个最终模型并对它们的预测进行平均。

让我们看看如何为分类和回归开发 XGBoost 集成。

用于分类的 XGBoost 集成

在本节中,我们将探讨在分类问题中使用 XGBoost。

首先,我们可以使用 make_classification() 函数 创建一个包含 1,000 个示例和 20 个输入特征的合成二元分类问题。

完整的示例如下所示。

运行示例会创建数据集并总结输入和输出组件的形状。

接下来,我们可以在此数据集上评估 XGBoost 模型。

我们将使用重复分层 k 折交叉验证来评估模型,其中重复 3 次,折叠 10 次。我们将报告模型在所有重复和折叠中的平均准确度和标准差。

运行示例报告了模型的平均准确度和标准差。

注意:鉴于算法或评估过程的随机性,或数值精度的差异,您的结果可能会有所不同。考虑多次运行示例并比较平均结果。

在这种情况下,我们可以看到具有默认超参数的 XGBoost 集成在此测试数据集上实现了大约 92.5% 的分类准确率。

我们还可以将 XGBoost 模型用作最终模型,并进行分类预测。

首先,XGBoost 集成在所有可用数据上进行拟合,然后可以调用 predict() 函数对新数据进行预测。重要的是,此函数期望数据始终以 NumPy 数组的形式提供,作为每行一个输入样本的矩阵。

以下示例在我们的二元分类数据集上演示了这一点。

运行示例会拟合整个数据集上的 XGBoost 集成模型,然后用于对一行新数据进行预测,就像我们在应用程序中使用模型时一样。

现在我们已经熟悉了使用 XGBoost 进行分类,接下来我们看看回归的 API。

用于回归的 XGBoost 集成

在本节中,我们将探讨在回归问题中使用 XGBoost。

首先,我们可以使用 make_regression() 函数 创建一个包含 1,000 个示例和 20 个输入特征的合成回归问题。

完整的示例如下所示。

运行示例会创建数据集并总结输入和输出组件的形状。

接下来,我们可以在此数据集上评估 XGBoost 算法。

与上一节一样,我们将使用重复 K 折交叉验证来评估模型,重复 3 次,折叠 10 次。我们将报告模型在所有重复和折叠中的平均绝对误差 (MAE)。scikit-learn 库将 MAE 设为负数,以便将其最大化而不是最小化。这意味着较大的负 MAE 更好,完美模型的 MAE 为 0。

完整的示例如下所示。

运行示例报告了模型的平均准确度和标准差。

注意:鉴于算法或评估过程的随机性,或数值精度的差异,您的结果可能会有所不同。考虑多次运行示例并比较平均结果。

在这种情况下,我们可以看到具有默认超参数的 XGBoost 集成实现了大约 76 的 MAE。

我们还可以将 XGBoost 模型用作最终模型,并进行回归预测。

首先,XGBoost 集成在所有可用数据上进行拟合,然后可以调用 predict() 函数对新数据进行预测。与分类一样,单行数据必须以 NumPy 数组格式表示为二维矩阵。

以下示例在我们的回归数据集上演示了这一点。

运行示例会拟合整个数据集上的 XGBoost 集成模型,然后用于对一行新数据进行预测,就像我们在应用程序中使用模型时一样。

现在我们已经熟悉了使用 XGBoost Scikit-Learn API 来评估和使用 XGBoost 集成,接下来我们来看看如何配置模型。

XGBoost 超参数

在本节中,我们将仔细研究您应该考虑为梯度提升集成调优的一些超参数以及它们对模型性能的影响。

探索树的数量

XGBoost 集成算法的一个重要超参数是集成中使用的决策树数量。

回想一下,决策树是按顺序添加到模型中的,以纠正和改进先前树所做的预测。因此,通常树越多越好。

树的数量可以通过“n_estimators”参数设置,默认为 100。

下面的示例探讨了树的数量在 10 到 5,000 之间对性能的影响。

运行示例首先报告每个配置的决策树数量的平均准确率。

注意:鉴于算法或评估过程的随机性,或数值精度的差异,您的结果可能会有所不同。考虑多次运行示例并比较平均结果。

在这种情况下,我们可以看到在此数据集上的性能在大约 500 棵树之前有所提高,之后性能似乎趋于平稳或下降。

为每个配置的树数量创建了准确率分数的箱线图。

我们可以看到模型性能和集成规模增加的总体趋势。

Box Plots of XGBoost Ensemble Size vs. Classification Accuracy

XGBoost 集成大小与分类准确度的箱线图

探索树深度

改变添加到集成中的每棵树的深度是梯度提升的另一个重要超参数。

树的深度控制了每棵树对训练数据集的专业化程度:它可能有多么通用或过度拟合。人们更喜欢既不太浅也不太通用(如 AdaBoost)也不太深也不太专业(如 bootstrap aggregation)的树。

梯度提升通常在具有适度深度的树上表现良好,在技能和通用性之间取得平衡。

树深度通过“max_depth”参数控制,默认为 6。

下面的示例探讨了 1 到 10 之间的树深度以及对模型性能的影响。

运行示例首先报告每个配置的树深度的平均准确率。

注意:鉴于算法或评估过程的随机性,或数值精度的差异,您的结果可能会有所不同。考虑多次运行示例并比较平均结果。

在这种情况下,我们可以看到性能随着树深度的增加而提高,可能在深度为 3 到 8 左右达到峰值,之后更深、更专业的树会导致性能下降。

为每个配置的树深度的准确率分布创建了一个箱线图。

我们可以看到模型性能随着树深度的增加而提高的总体趋势,达到一定程度后,随着过度专业化的树,性能开始停滞或下降。

Box Plots of XGBoost Ensemble Tree Depth vs. Classification Accuracy

XGBoost 集成树深度与分类准确度的箱线图

探索学习率

学习率控制每个模型对集成预测的贡献量。

较小的学习率可能需要集成更多的决策树。

学习率可以通过“eta”参数控制,默认为 0.3。

下面的示例探讨了学习率,并比较了 0.0001 和 1.0 之间值的影响。

运行示例首先报告每个配置的学习率的平均准确率。

注意:鉴于算法或评估过程的随机性,或数值精度的差异,您的结果可能会有所不同。考虑多次运行示例并比较平均结果。

在这种情况下,我们可以看到更大的学习率在此数据集上获得了更好的性能。我们期望对于较小的学习率,向集成中添加更多树会进一步提高性能。

这突出了树的数量(训练速度)和学习率之间的权衡,例如,我们可以通过使用更少的树和更大的学习率来更快地拟合模型。

为每个配置的学习率的准确度分数分布创建了一个箱线图。

我们可以看到模型性能随着学习率增加 0.1 而提高的总体趋势,之后性能会下降。

Box Plot of XGBoost Learning Rate vs. Classification Accuracy

XGBoost 学习率与分类准确度的箱线图

探索样本数量

用于拟合每棵树的样本数量可以改变。这意味着每棵树都拟合在训练数据集的随机选择子集上。

使用较少的样本会为每棵树引入更多方差,尽管它可以提高模型的整体性能。

用于拟合每棵树的样本数量由“subsample”参数指定,可以设置为训练数据集大小的一部分。默认情况下,它设置为 1.0 以使用整个训练数据集。

下面的示例演示了样本大小对模型性能的影响,比率从 10% 到 100% 以 10% 的增量变化。

运行示例首先报告每个配置的样本大小的平均准确度。

注意:鉴于算法或评估过程的随机性,或数值精度的差异,您的结果可能会有所不同。考虑多次运行示例并比较平均结果。

在这种情况下,我们可以看到平均性能对于覆盖大部分数据集的样本大小(例如 80% 或更高)可能是最佳的。

为每个配置的采样比率的准确度分数分布创建了一个箱线图。

我们可以看到模型性能增加的总体趋势,可能在 80% 左右达到峰值并保持相对稳定。

Box Plots of XGBoost Ensemble Sample Ratio vs. Classification Accuracy

XGBoost 集成样本比率与分类准确度的箱线图

探索特征数量

用于拟合每棵决策树的特征数量可以改变。

与改变样本数量类似,改变特征数量会为模型引入额外的方差,这可能会提高性能,尽管这可能需要增加树的数量。

每棵树使用的特征数量作为随机样本抽取,由“colsample_bytree”参数指定,默认为训练数据集中的所有特征,例如 100% 或值为 1.0。您还可以为每个分割采样列,这由“colsample_bylevel”参数控制,但我们在此处不讨论此超参数。

下面的示例探讨了特征数量对模型性能的影响,比率从 10% 到 100% 以 10% 的增量变化。

运行示例首先报告每个配置的列比率的平均准确度。

注意:鉴于算法或评估过程的随机性,或数值精度的差异,您的结果可能会有所不同。考虑多次运行示例并比较平均结果。

在这种情况下,我们可以看到平均性能增加到大约一半的特征数(50%),之后保持相对稳定。令人惊讶的是,每棵树删除一半的输入变量影响如此之小。

为每个配置的列比率的准确度分数分布创建了一个箱线图。

我们可以看到模型性能增加的总体趋势,可能在 60% 的比率下达到峰值并保持相对稳定。

Box Plots of XGBoost Ensemble Column Ratio vs. Classification Accuracy

XGBoost 集成列比率与分类准确度的箱线图

进一步阅读

如果您想深入了解,本节提供了更多关于该主题的资源。

教程

论文

项目

API

文章

总结

在本教程中,您学习了如何开发用于分类和回归的极限梯度提升集成。

具体来说,你学到了:

  • 极限梯度提升是随机梯度提升集成算法的高效开源实现。
  • 如何使用 scikit-learn API 开发用于分类和回归的 XGBoost 集成。
  • 如何探究 XGBoost 模型超参数对模型性能的影响。

你有什么问题吗?
在下面的评论中提出你的问题,我会尽力回答。

掌握现代集成学习!

Ensemble Learning Algorithms With Python

在几分钟内改进您的预测

...只需几行python代码

在我的新电子书中探索如何实现
使用 Python 实现集成学习算法

它提供**自学教程**,并附有关于以下内容的**完整工作代码**:
堆叠、投票、提升、装袋、混合、超级学习器等等……

将现代集成学习技术带入
您的机器学习项目


查看内容

对《Python 中的极限梯度提升 (XGBoost) 集成》的 9 条评论

  1. 哈利 2021 年 1 月 1 日 上午 3:37 #

    贾森,我想知道我的结果是否会因为算法或评估过程的随机性,或者数值精度的差异而有所不同?抱歉,只是开玩笑。我注意到你在这里和其他文章中都使用了这句话。无论如何都是顶级的材料,感谢你整理这些文章,它们总是在很小的空间里包含大量信息。

    • 杰森·布朗利 2021 年 1 月 1 日 上午 5:34 #

      谢谢。

      是的,我使用了一个 WordPress 短代码,因此所有最近的教程中任何结果后面都带有相同的文本免责声明。这可以阻止每天收到数十封询问“为什么我的结果与您的结果略有不同?”的电子邮件。

  2. 沙欣 2021 年 2 月 11 日 晚上 8:20 #

    我可以使用梯度提升 (XGBoost) 进行多输出回归吗?

  3. 阿提 2021 年 9 月 3 日 晚上 7:12 #

    嗨,Jason,

    感谢这篇精彩的教程,它对我非常有帮助。
    我有一个问题。我想实现一个由 CNN、深度自动编码器和 XGB 组成的结构。我定义了一个由 CNN 和深度自动编码器组成的功能模型。在第二层中,深度自动编码器的潜在向量应该输入到一个基于极限梯度提升的分类器中。

    我使用了 StackingClassifier,但我收到了错误:估计器 Functional 应该是一个分类器
    您能帮我怎么做吗?

    • 杰森·布朗利 2021 年 9 月 4 日 上午 5:19 #

      也许您可以将神经网络用作预处理步骤,保存数据,然后使用它来训练另一个模型,例如 XGB。

      • 阿莫比 2022 年 5 月 12 日 下午 3:55 #

        嗨,Jason,

        您能解释一下您所说的将神经网络用作预处理步骤,然后使用数据来训练 XGB 是什么意思吗?预处理指的是什么?我正在研究极 XGB 模型,偶然发现了您的代码,非常有趣。顺便说一下,您的工作很棒。您让我们的生活更轻松。谢谢您。

        如果您能给我清晰的解释或指引我到哪里可以看到您所说的预处理示例,我将
        非常高兴

  4. 阿莫比 2022 年 5 月 13 日 下午 5:00 #

    非常感谢。我已经看过了。现在我明白了。

    我有一个小问题。在研究您关于集成神经网络(深度学习神经网络的集成)的帖子时,我想知道在解决神经网络回归问题时是否可以使用 XGBoost 作为元学习器。

发表评论

Machine Learning Mastery 是 Guiding Tech Media 的一部分,Guiding Tech Media 是一家领先的数字媒体出版商,专注于帮助人们了解技术。访问我们的公司网站以了解更多关于我们的使命和团队的信息。