XGBoost Python 迷你课程。
XGBoost 是梯度提升的一种实现,被用于赢得机器学习竞赛。
它功能强大,但入门可能很困难。
在这篇文章中,您将学习到关于 Python 中 XGBoost 的 7 部分速成课程。
本迷你课程专为熟悉 scikit-learn 和 SciPy 生态系统的 Python 机器学习从业者设计。
通过我的新书《XGBoost With Python》启动您的项目,其中包括所有示例的分步教程和 Python 源代码文件。
让我们开始吧。
- 2017 年 1 月更新:已更新以反映 scikit-learn API 0.18.1 版本中的更改。
- **2018 年 3 月更新**:添加了下载数据集的备用链接,因为原始链接似乎已被删除。

XGBoost Python 迷你课程
图片由 Teresa Boardman 提供,保留部分权利。
(提示:您可能希望打印或收藏此页面,以便日后参考。)
本迷你课程适合谁?
在我们开始之前,让我们确保你来对了地方。下面的列表提供了一些关于本课程设计对象的一般性指导。
如果您不完全符合这些要点,请不要惊慌,您可能只需要在某个领域稍作补充即可跟上。
- 懂得编写少量代码的开发者。这意味着您使用 Python 完成任务不成问题,并且知道如何在您的工作站上设置 SciPy 生态系统(先决条件)。这并不意味着您是编程向导,但它确实意味着您不害怕安装软件包和编写脚本。
- 懂一点机器学习的开发者。这意味着您了解机器学习的基础知识,例如交叉验证、一些算法和偏差-方差权衡。这并不意味着您是机器学习博士,只是您知道里程碑或知道在哪里查找它们。
本迷你课程不是一本关于 XGBoost 的教科书。不会有任何方程式。
它将带您从一个懂一点 Python 机器学习的开发者,成长为一个能够取得成果并将 XGBoost 的强大功能引入您自己的项目的开发者。
在 Python 中使用 XGBoost 需要帮助吗?
参加我的免费 7 天电子邮件课程,探索 xgboost(含示例代码)。
立即点击注册,还将免费获得本课程的 PDF 电子书版本。
迷你课程概述(可以期待什么)
本迷你课程分为 7 个部分。
每节课都旨在让普通开发人员花费大约 30 分钟。您可能会更快完成一些,而另一些您可能会选择深入研究并花费更多时间。
您可以根据需要快速或缓慢地完成每个部分。一个舒适的时间表可能是每周完成一节课。强烈推荐。
您将在接下来的 7 节课中涵盖的主题如下:
- 第 01 课:梯度提升简介。
- 第 02 课:XGBoost 简介。
- 第 03 课:开发您的第一个 XGBoost 模型。
- 第 04 课:监控性能和提前停止。
- 第 05 课:XGBoost 的特征重要性。
- 第 06 课:如何配置梯度提升。
- 第 07 课:XGBoost 超参数调优。
这将非常有趣。
不过,您需要做一些工作,一些阅读,一些研究和一些编程。您想了解 XGBoost 对吗?
(提示:这些课程的帮助可以在本博客上找到,请使用搜索功能。)
有任何问题,请在下面的评论中提出。
在评论中分享你的结果。
坚持下去,不要放弃!
第 01 课:梯度提升简介
梯度提升是构建预测模型最强大的技术之一。
提升的想法源于能否改进一个弱学习器。在应用中取得巨大成功的第一个提升实现是自适应提升或简称 AdaBoost。AdaBoost 中的弱学习器是只有一次分割的决策树,因其短小而被称作决策桩。
AdaBoost 和相关算法在统计框架中被重新定义,并被称为梯度提升机。统计框架将提升视为一个数值优化问题,目标是通过使用梯度下降等过程添加弱学习器来最小化模型的损失,因此得名。
梯度提升算法包含三个要素:
- 一个要优化的损失函数,例如用于分类的交叉熵或用于回归问题的均方误差。
- 一个用于进行预测的弱学习器,例如贪婪构建的决策树。
- 一个加性模型,用于添加弱学习器以最小化损失函数。
新的弱学习器被添加到模型中,以纠正所有先前树的残差误差。结果是一个强大的预测建模算法,可能比随机森林更强大。
在下一课中,我们将更深入地了解梯度提升的 XGBoost 实现。
第 02 课:XGBoost 简介
XGBoost 是梯度提升决策树的一种实现,旨在提高速度和性能。
XGBoost 代表 eXtreme Gradient Boosting(极致梯度提升)。
它由陈天奇开发,专注于计算速度和模型性能,因此功能很少花哨。
除了支持该技术的所有关键变体之外,真正引起兴趣的是通过对实现的精心工程提供的速度,其中包括:
- 在训练期间使用所有 CPU 内核进行树构建的并行化。
- 使用机器集群训练超大型模型的分布式计算。
- 针对无法放入内存的超大型数据集的核外计算。
- 数据结构和算法的缓存优化,以充分利用硬件。
传统上,梯度提升的实现速度很慢,因为每棵树都必须按顺序构建并添加到模型中。
XGBoost 开发中的性能使其成为最佳预测建模算法之一,现在可以充分利用您的硬件平台或您可能在云端租用的大型计算机的功能。
因此,XGBoost 已成为竞争性机器学习的基石,是获胜者使用和推荐的技术。例如,以下是一些近期 Kaggle 竞赛获胜者所说的话:
作为越来越多 Kaggle 竞赛的获胜者,XGBoost 再次向我们展示了它是一种值得拥有在您的工具箱中的出色全能算法。
有疑问时,请使用 xgboost。
在下一课中,我们将在 Python 中开发我们的第一个 XGBoost 模型。
第 03 课:开发您的第一个 XGBoost 模型
假设您有一个可用的 SciPy 环境,XGBoost 可以使用 pip 轻松安装。
例如:
1 |
sudo pip install xgboost |
您可以在 XGBoost 安装说明中了解更多关于在您的平台上安装和构建 XGBoost 的信息。
XGBoost 模型可以使用包装器类直接在 scikit-learn 框架中使用,其中 XGBClassifier 用于分类问题,XGBRegressor 用于回归问题。
这是在 Python 中使用 XGBoost 的推荐方法。
下载 Pima Indians 糖尿病发病数据集。
这是一个很好的二元分类测试数据集,因为所有输入变量都是数值型的,这意味着该问题可以直接建模,无需数据预处理。
我们可以通过构建一个 XGBoost 模型并调用 model.fit() 函数来训练一个用于分类的 XGBoost 模型
1 2 |
model = XGBClassifier() model.fit(X_train, y_train) |
然后,该模型可以通过在新数据上调用 model.predict() 函数进行预测。
1 |
y_pred = model.predict(X_test) |
我们可以将所有这些结合起来,如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
# Pima Indians 数据集的第一个 XGBoost 模型 从 numpy 导入 loadtxt from xgboost import XGBClassifier from sklearn.model_selection import train_test_split from sklearn.metrics import accuracy_score # 加载数据 dataset = loadtxt('pima-indians-diabetes.csv', delimiter=",") # 将数据拆分为 X 和 y X = dataset[:,0:8] Y = dataset[:,8] # 将数据拆分为训练集和测试集 seed = 7 test_size = 0.33 X_train, X_test, y_train, y_test = train_test_split(X, Y, test_size=test_size, random_state=seed) # 在训练数据上拟合模型 model = XGBClassifier() model.fit(X_train, y_train) # 对测试数据进行预测 y_pred = model.predict(X_test) predictions = [round(value) for value in y_pred] # 评估预测 accuracy = accuracy_score(y_test, predictions) print("Accuracy: %.2f%%" % (accuracy * 100.0)) |
在下一课中,我们将探讨如何使用提前停止来限制过拟合。
第 04 课:监控性能和提前停止
XGBoost 模型可以在训练期间评估和报告测试集上的模型性能。
它通过在调用 model.fit() 训练模型时指定测试数据集和评估指标,并指定详细输出 (verbose=True) 来支持此功能。
例如,我们可以在训练 XGBoost 模型时,通过以下方式报告独立测试集 (eval_set) 上的二元分类错误率 (error):
1 2 |
eval_set = [(X_test, y_test)] model.fit(X_train, y_train, eval_metric="error", eval_set=eval_set, verbose=True) |
使用此配置运行模型将在添加每棵树后报告模型的性能。例如:
1 2 3 |
... [89] validation_0-error:0.204724 [90] validation_0-error:0.208661 |
我们可以使用这个评估来停止训练,一旦模型没有进一步改进。
我们可以通过在调用 model.fit() 时将 early_stopping_rounds 参数设置为在验证数据集上没有观察到改进的迭代次数来停止训练。
下面提供了使用 Pima Indians 糖尿病发病数据集的完整示例。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
# 提前停止的例子 从 numpy 导入 loadtxt from xgboost import XGBClassifier from sklearn.model_selection import train_test_split from sklearn.metrics import accuracy_score # 加载数据 dataset = loadtxt('pima-indians-diabetes.csv', delimiter=",") # 将数据拆分为 X 和 y X = dataset[:,0:8] Y = dataset[:,8] # 将数据拆分为训练集和测试集 seed = 7 test_size = 0.33 X_train, X_test, y_train, y_test = train_test_split(X, Y, test_size=test_size, random_state=seed) # 在训练数据上拟合模型 model = XGBClassifier() eval_set = [(X_test, y_test)] model.fit(X_train, y_train, early_stopping_rounds=10, eval_metric="logloss", eval_set=eval_set, verbose=True) # 对测试数据进行预测 y_pred = model.predict(X_test) predictions = [round(value) for value in y_pred] # 评估预测 accuracy = accuracy_score(y_test, predictions) print("Accuracy: %.2f%%" % (accuracy * 100.0)) |
在下一课中,我们将探讨如何使用 XGBoost 计算特征的重要性。
第 05 课:XGBoost 的特征重要性
使用梯度提升等决策树集成方法的一个好处是,它们可以自动从训练好的预测模型中提供特征重要性的估计。
训练好的 XGBoost 模型会自动计算您预测建模问题上的特征重要性。
这些重要性分数可在训练模型的 feature_importances_ 成员变量中获得。例如,它们可以直接打印如下:
1 |
打印(模型.feature_importances_) |
XGBoost 库提供了一个内置函数,可以按特征重要性排序绘制特征。
该函数名为 plot_importance(),可以如下使用:
1 2 |
plot_importance(model) pyplot.show() |
这些重要性分数可以帮助您决定保留或丢弃哪些输入变量。它们也可以用作自动特征选择技术的基础。
下面提供了使用 Pima Indians 糖尿病发病数据集绘制特征重要性分数的完整示例。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
# 使用内置函数绘制特征重要性 从 numpy 导入 loadtxt from xgboost import XGBClassifier from xgboost import plot_importance from matplotlib import pyplot # 加载数据 dataset = loadtxt('pima-indians-diabetes.csv', delimiter=",") # 将数据拆分为 X 和 y X = dataset[:,0:8] y = dataset[:,8] # 在训练数据上拟合模型 model = XGBClassifier() model.fit(X, y) # 绘制特征重要性 plot_importance(model) pyplot.show() |
在下一课中,我们将探讨如何启发式地最佳配置梯度提升算法。
第 06 课:如何配置梯度提升
梯度提升是应用机器学习中最强大的技术之一,因此正迅速成为最受欢迎的技术之一。
但如何在您的问题上配置梯度提升呢?
原始梯度提升论文中发布了一些配置启发式方法。它们可以总结为:
- 学习率或收缩(XGBoost 中的 learning_rate)应设置为 0.1 或更低,较小的值将需要添加更多树。
- 树的深度(XGBoost 中的 max_depth)应配置在 2 到 8 的范围内,更深的树没有太大益处。
- 行采样(XGBoost 中的 subsample)应配置在训练数据集的 30% 到 80% 的范围内,并与不采样的 100% 值进行比较。
这些是配置模型时的良好起点。
一个好的通用配置策略如下:
- 运行默认配置并查看训练集和验证集上的学习曲线图。
- 如果系统过拟合,请降低学习率和/或增加树的数量。
- 如果系统欠拟合,则通过增加学习率和/或减少树的数量来加快学习速度,使其更具侵略性。
Owen Zhang,前 Kaggle 排名第一的竞争者,现在是 Data Robot 的首席技术官,他提出了一种有趣的 XGBoost 配置策略。
他建议将树的数量设置为目标值,例如 100 或 1000,然后调整学习率以找到最佳模型。这是一种快速找到好模型的有效策略。
在下一课也是最后一课中,我们将看一个调整 XGBoost 超参数的示例。
第 07 课:XGBoost 超参数调优
scikit-learn 框架提供了搜索参数组合的功能。
此功能由 GridSearchCV 类提供,可用于发现配置模型以在您的问题上获得最佳性能的最佳方法。
例如,我们可以通过定义一个网格来评估树的数量 (n_estimators) 和树的大小 (max_depth):
1 2 3 |
n_estimators = [50, 100, 150, 200] max_depth = [2, 4, 6, 8] param_grid = dict(max_depth=max_depth, n_estimators=n_estimators) |
然后使用 10 折交叉验证评估每个参数组合,如下所示:
1 2 3 |
kfold = StratifiedKFold(n_splits=10, shuffle=True, random_state=7) grid_search = GridSearchCV(model, param_grid, scoring="neg_log_loss", n_jobs=-1, cv=kfold, verbose=1) result = grid_search.fit(X, label_encoded_y) |
然后我们可以审查结果,以确定最佳组合和参数组合变化的总体趋势。
这是将 XGBoost 应用于您自己的问题时的最佳实践。要考虑调整的参数是:
- 树的数量和大小(n_estimators 和 max_depth)。
- 学习率和树的数量(learning_rate 和 n_estimators)。
- 行和列的子采样率(subsample、colsample_bytree 和 colsample_bylevel)。
以下是一个在 Pima Indians 糖尿病发病数据集上仅调整 learning_rate 的完整示例。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
# 调整学习率 从 numpy 导入 loadtxt from xgboost import XGBClassifier from sklearn.model_selection import GridSearchCV from sklearn.model_selection import StratifiedKFold # 加载数据 dataset = loadtxt('pima-indians-diabetes.csv', delimiter=",") # 将数据拆分为 X 和 y X = dataset[:,0:8] Y = dataset[:,8] # 网格搜索 model = XGBClassifier() learning_rate = [0.0001, 0.001, 0.01, 0.1, 0.2, 0.3] param_grid = dict(learning_rate=learning_rate) kfold = StratifiedKFold(n_splits=10, shuffle=True, random_state=7) grid_search = GridSearchCV(model, param_grid, scoring="neg_log_loss", n_jobs=-1, cv=kfold) grid_result = grid_search.fit(X, Y) # 总结结果 print("Best: %f using %s" % (grid_result.best_score_, grid_result.best_params_)) means = grid_result.cv_results_['mean_test_score'] stds = grid_result.cv_results_['std_test_score'] params = grid_result.cv_results_['params'] for mean, stdev, param in zip(means, stds, params): print("%f (%f) with: %r" % (mean, stdev, param)) |
XGBoost 学习迷你课程回顾
恭喜,你做到了。干得好!
花点时间回顾一下你已经走了多远:
- 您学习了梯度提升算法和 XGBoost 库。
- 您开发了您的第一个 XGBoost 模型。
- 您学习了如何使用提前停止和特征重要性等高级功能。
- 您学习了如何配置梯度提升模型以及如何设计受控实验以调整 XGBoost 超参数。
不要轻视这一点,您在短时间内取得了长足的进步。这只是您在 Python 中使用 XGBoost 旅程的开始。继续练习并发展您的技能。
您喜欢这个迷你课程吗?您有什么问题或难点吗?
留下评论,让我知道。
问题在于
1. 如果系统过拟合,则降低学习率和/或增加树的数量。
2. 如果系统欠拟合,则通过增加学习率和/或减少树的数量来加快学习速度,使其更具侵略性。
我认为如果系统过拟合,这意味着它过度拟合,我认为应该增加学习率,减少树的深度,并减少树的数量。
嗨 Alexander,试试看。
我建议在过拟合时对模型/容量进行较少的更新,而在过拟合时进行相反的操作。
X = dataset[:,0:8]
Y = dataset[:,8]
不会是 Y = dataset[:,9] 吗?
不,考虑阅读 Python 数组切片。
嗨,jason
我们可以从 xgboost 二进制缓冲区文件加载数据吗?
我不知道,抱歉。
嗨,Jason,
在第 4 课中,第一个代码块显示 eval_metric=”error”,然后显示 eval_metric=”logloss”。当使用“error”时,我在迭代 [89] validation_0-error:0.204724 中得到最小值。当使用“logloss”时,我在迭代 [32] validation_0-logloss:0.487297 中得到最小值。为什么这两个 eval_metric 的最小值出现在不同的迭代中?我们应该遵循哪一个?谢谢。
通常,鉴于算法的随机性,您会在迭代中获得不同的最小分数。
https://machinelearning.org.cn/randomness-in-machine-learning/
我建议选择与您的项目目标最相关的指标。
您会发布 XGB Regressor 教程吗?我在任何地方都找不到!
感谢您的建议。
嗨,Jason!
感谢您提供所有这些精彩的教程!它们太棒了。感谢您以非常容易理解的方式传授这些知识。🙂
我正在使用 Windows 10 系统,Anaconda Python 3.6,使用 Spyder3 作为编辑器。我一直收到这个错误:
ImportError: [joblib] 尝试在不支持分叉的系统上进行并行计算,但未保护您的导入。要在脚本中使用并行计算,您必须使用“if __name__ == ‘__main__'”保护您的主循环。请参阅 joblib 文档中有关 Parallel 的更多信息。
我在 stackoverflow 上查阅了这个问题,但仍然不清楚如何解决。我尝试将所有内容放入“if __name__ == ‘__main__':”块中,但仍然收到此错误。两个问题:
1:有没有办法让这段代码在非 GPU 系统上运行?我的系统是 Intel(R) Core(TM) i7-4790 CPU @ 3.60GHz 3.60 GHz,16.0 GB RAM,64 位操作系统,x64 处理器。
2:如果我在带有 ND 系列 GPU 的 Windows 10 系统上运行此程序,它会解决这个问题吗?
非常感谢!
Aimee
是的,不需要 GPU。
也许尝试从命令行运行?
我以前从未见过此错误,请确认您的所有库都已更新?
我稍微调整了一下参数,最终通过在对 GridSearchCV 的调用中将 n_jobs 设置为 1 而不是 -1 来使其运行。据我在线阅读,这是因为 Windows 没有 fork 函数,因此当 n_jobs 设置为 -1 时,它不知道如何处理所请求的进程。
再次感谢。我学到了很多!没有什么比通过示例学习并亲自动手实践更好的了。
祝您有美好的一天!🙂
很好,谢谢分享。
嗨 Jason,我正在使用 XGBRegressor 模型来预测保险索赔的严重程度。
然而,每个记录的预测几乎相同。
我猜这是过拟合,或者您有什么建议来解决这个问题?
我这里有一系列想法:
https://machinelearning.org.cn/machine-learning-performance-improvement-cheat-sheet/
嗨,Jason,
我有 XGBOOST 书,它非常棒。它极大地帮助了我们对患病人群进行分类。但是,当我在使用 OneHotEncoder() 时,我遇到了特征名称不匹配的错误。当训练和测试数据集时,问题不会发生。只有当我尝试使用该模型预测模型未见过的新数据集时才会发生。我在这里发布了这个问题:https://stackoverflow.com/questions/51860759/xgboost-feature-name-error-python
我希望您也能提供一些克服此问题的想法。
非常感谢。
您需要使用与用于训练模型的数据相同编码器来准备新数据。
嗨,Jason,
非常感谢您的出色回答。我成功解决了这个问题,并在 stackoverflow.com 上提到了这个网站。
对于和我遇到同样情况的朋友们,您需要从 sklearn.externals 导入 joblib。在您拟合 OneHotEncoder 之后,您需要使用 joblib.dump(enc, "your_encoder.pkl") 保存拟合好的编码器。
现在,您可以将相同的编码器用于另一个数据集。
这是我的问题和答案的链接:https://stackoverflow.com/questions/51860759/xgboost-feature-name-error-python/51878832#51878832
再次,非常感谢 Jason。
干得好!
你能分享这本书吗?我想学习 XGB 的数学知识。
也许从论文开始。
感谢您的介绍性迷你课程 Jason,
在最后一步调整参数后,假设我们找到了候选参数中的最佳参数。我们是否必须使用这些参数再次训练模型?如果是这样,我们如何将最佳参数提供给分类器?谢谢。
是的,您可以在定义模型时通过参数配置模型。
在哪里可以下载 xgboost 电子书
如果您注册,它将通过电子邮件发送给您。
你好 Jason,
我刚刚尝试了“.fit”和“.predict”XGBClassifier 函数,结果出现了 feature_names 不匹配错误。然而,将相同的训练集和测试集通过一个简单的随机森林分类器时,却没有任何问题。我很困惑。XGB 是否需要特定类型或格式的训练集和测试集才能工作?
谢谢!
也许您的新数据集与训练集和测试集不同?
不,我为两个分类器使用了相同的训练集和测试集。随机森林预测没有问题。但是 XGB 却报错了。XGB 只接受 numpy 数组吗?我注意到您使用了 loadtxt 而不是 pd.read_csv。谢谢!
是的,如果您使用 sklearn 接口,那么模型将只接受 numpy 数组。
啊哈!谢谢!
你能用 xgboost 做时间序列预测吗?谢谢。
当然可以。
关于 Python 中 XGBoost 的最好、简短而清晰的文章之一,提供了深入的见解。
谢谢!
供参考,Pina Indian 数据集仍然可以在提供的 UCI 链接中找到,但是如果您搜索 UCI 网站,它会说由于权限限制而不再可用。Kaggle 现在也托管此数据集,网址为:
https://www.kaggle.com/uciml/pima-indians-diabetes-database
附有描述、列详细信息和汇总统计信息。可能需要更新您的课程以指向 Kaggle。
谢谢。
我在这里提供所有数据集
https://github.com/jbrownlee/Datasets
这是 pima 数据集
https://raw.githubusercontent.com/jbrownlee/Datasets/master/pima-indians-diabetes.csv
对于使用 conda envs 并且发现使用 sudo 命令难以安装 XGBoost 的个人,请尝试
$ sudo ~/anaconda3/bin/python -m pip install xgboost -H
希望这能帮助到您,谢谢……。
非常棒的提示,谢谢!
早上好,Jason,
我正在尝试将 XGBoost 与 SMOTE 结合使用。
我已经用其他算法(如随机森林和 Light GBM)测试了 SMOTE,并且完美运行。但是当我尝试将 XGBoost 与其一起使用时,在 .predict(X_test) 部分出现错误。
这是错误。
你能帮我吗?
先谢谢您了。
错误是什么?
如何创建 dataset = loadtxt(‘pima-indians-diabetes.csv’, delimiter=”,”) 因为这段代码显示错误。我正在使用 spyder 4.0。
我建议从命令行运行代码示例,而不是从笔记本或 IDE 运行
https://machinelearning.org.cn/faq/single-faq/how-do-i-run-a-script-from-the-command-line
嗨,我找到了解决方案。无需回答。谢谢。
很高兴听到这个消息。
大家好!
您有关于 XGBoost RANKER 的教程或书籍吗?
我有您关于 XGBoost 算法的书,但它不符合我的排序需求。
此外,我是 Python 新手,我需要一些代码来了解如何实现它。
有什么建议吗?
提前感谢您!
索菲亚
谢谢您的建议。但我们还没有。
为什么我在第三天的练习中得到了大约 78% 的准确率?增加 n_estimators 或降低学习率并没有太大帮助。
嗨 Sahil…以下可能对您有帮助
https://machinelearning.org.cn/tune-xgboost-performance-with-learning-curves/
你好。我正在尝试使用不平衡数据集(正类 = 7%)进行二元分类。
我尝试了多种算法,如 RF、gbm、SVM、catboost、xgboost 和 NB。
我通过 xgboost 算法获得了最佳性能。
通过过采样和参数设置,我将灵敏度从几乎 0 提高到 0.7。然而,特异性和准确性显著下降(从 0.9 降至 0.6),并且我没有获得高于 0.65 的 ROC AUC。
我主要用 R 语言编写代码。
有什么建议可以提高该模型的性能吗? (尝试其他算法,任何特定的参数设置)
嗨 Moon…以下可能对您有帮助
https://machinelearning.org.cn/tune-xgboost-performance-with-learning-curves/