Machine Learning Mastery XGBoost 教程(二)
如何在 macOS 上为 Python 安装 XGBoost
原文:
machinelearningmastery.com/install-xgboost-python-macos/
XGBoost 是一个用于开发非常快速和准确的梯度提升模型的库。
它是 Kaggle 数据科学竞赛中许多获奖解决方案中心的图书馆。
在本教程中,您将了解如何在 macOS 上安装 Python 的 XGBoost 库。
让我们开始吧。
如何在 macOS 上安装 XGBoost for Python 照片来自 auntjojo ,保留一些权利。
教程概述
本教程分为 3 个部分;他们是:
- 安装 MacPorts
- 构建 XGBoost
- 安装 XGBoost
注意:我已经在一系列不同的 macOS 版本上使用了这个程序多年,并且没有改变。本教程是在 macOS High Sierra(10.13.1)上编写和测试的。
1.安装 MacPorts
您需要安装 GCC 和 Python 环境才能构建和安装 XGBoost for Python。
我推荐使用 GCC 7 和 Python 3.6,我建议使用 MacPorts 安装这些先决条件。
- 1.有关逐步安装 MacPorts 和 Python 环境的帮助,请参阅本教程:
>>如何在 Mac OS X 上安装 Python 3 环境以进行机器学习和深度学习
- 2.安装 MacPorts 和可用的 Python 环境后,您可以按如下方式安装和选择 GCC 7:
sudo port install gcc7
sudo port select --set gcc mp-gcc7
- 3.确认您的 GCC 安装成功,如下所示:
gcc -v
你应该看到印刷版的 GCC;例如:
..
gcc version 7.2.0 (MacPorts gcc7 7.2.0_0)
你看到什么版本? 请在下面的评论中告诉我。
2.构建 XGBoost
下一步是为您的系统下载并编译 XGBoost。
- 1.首先,从 GitHub 查看代码库:
git clone --recursive https://github.com/dmlc/xgboost
- 2.转到 xgboost 目录。
cd xgboost/
- 3.复制我们打算用来将 XGBoost 编译到位的配置。
cp make/config.mk ./config.mk
- 4.编译 XGBoost;这要求您指定系统上的核心数(例如,8,根据需要进行更改)。
make -j8
构建过程可能需要一分钟,不应产生任何错误消息,尽管您可能会看到一些可以安全忽略的警告。
例如,编译的最后一个片段可能如下所示:
...
a - build/learner.o
a - build/logging.o
a - build/c_api/c_api.o
a - build/c_api/c_api_error.o
a - build/common/common.o
a - build/common/hist_util.o
a - build/data/data.o
a - build/data/simple_csr_source.o
a - build/data/simple_dmatrix.o
a - build/data/sparse_page_dmatrix.o
a - build/data/sparse_page_raw_format.o
a - build/data/sparse_page_source.o
a - build/data/sparse_page_writer.o
a - build/gbm/gblinear.o
a - build/gbm/gbm.o
a - build/gbm/gbtree.o
a - build/metric/elementwise_metric.o
a - build/metric/metric.o
a - build/metric/multiclass_metric.o
a - build/metric/rank_metric.o
a - build/objective/multiclass_obj.o
a - build/objective/objective.o
a - build/objective/rank_obj.o
a - build/objective/regression_obj.o
a - build/predictor/cpu_predictor.o
a - build/predictor/predictor.o
a - build/tree/tree_model.o
a - build/tree/tree_updater.o
a - build/tree/updater_colmaker.o
a - build/tree/updater_fast_hist.o
a - build/tree/updater_histmaker.o
a - build/tree/updater_prune.o
a - build/tree/updater_refresh.o
a - build/tree/updater_skmaker.o
a - build/tree/updater_sync.o
c++ -std=c++11 -Wall -Wno-unknown-pragmas -Iinclude -Idmlc-core/include -Irabit/include -I/include -O3 -funroll-loops -msse2 -fPIC -fopenmp -o xgboost build/cli_main.o build/learner.o build/logging.o build/c_api/c_api.o build/c_api/c_api_error.o build/common/common.o build/common/hist_util.o build/data/data.o build/data/simple_csr_source.o build/data/simple_dmatrix.o build/data/sparse_page_dmatrix.o build/data/sparse_page_raw_format.o build/data/sparse_page_source.o build/data/sparse_page_writer.o build/gbm/gblinear.o build/gbm/gbm.o build/gbm/gbtree.o build/metric/elementwise_metric.o build/metric/metric.o build/metric/multiclass_metric.o build/metric/rank_metric.o build/objective/multiclass_obj.o build/objective/objective.o build/objective/rank_obj.o build/objective/regression_obj.o build/predictor/cpu_predictor.o build/predictor/predictor.o build/tree/tree_model.o build/tree/tree_updater.o build/tree/updater_colmaker.o build/tree/updater_fast_hist.o build/tree/updater_histmaker.o build/tree/updater_prune.o build/tree/updater_refresh.o build/tree/updater_skmaker.o build/tree/updater_sync.o dmlc-core/libdmlc.a rabit/lib/librabit.a -pthread -lm -fopenmp
这一步对你有用吗? 请在下面的评论中告诉我。
3.安装 XGBoost
您现在可以在系统上安装 XGBoost 了。
- 1.将目录更改为 xgboost 项目的 Python 包。
cd python-package
- 2.安装 Python XGBoost 包。
sudo python setup.py install
安装非常快。
例如,在安装结束时,您可能会看到如下消息:
...
Installed /opt/local/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/xgboost-0.6-py3.6.egg
Processing dependencies for xgboost==0.6
Searching for scipy==1.0.0
Best match: scipy 1.0.0
Adding scipy 1.0.0 to easy-install.pth file
Using /opt/local/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages
Searching for numpy==1.13.3
Best match: numpy 1.13.3
Adding numpy 1.13.3 to easy-install.pth file
Using /opt/local/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages
Finished processing dependencies for xgboost==0.6
- 3.通过打印 xgboost 版本确认安装是否成功,这需要加载库。
将以下代码保存到名为 version.py 的文件中。
import xgboost
print("xgboost", xgboost.__version__)
从命令行运行脚本:
python version.py
您应该看到 XGBoost 版本打印到屏幕:
xgboost 0.6
你是怎么做的? 在以下评论中发布您的结果。
进一步阅读
如果您希望深入了解,本节将提供有关该主题的更多资源。
摘要
在本教程中,您了解了如何在 macOS 上逐步安装 XGBoost for Python。
你有任何问题吗? 在下面的评论中提出您的问题,我会尽力回答。
如何使用 Python 和 XGBoost 保存梯度提升模型
原文:
machinelearningmastery.com/save-gradient-boosting-models-xgboost-python/
XGBoost 可用于使用梯度提升算法为表格数据创建一些表现最佳的模型。
经过训练,将模型保存到文件中以便以后用于预测新的测试和验证数据集以及全新数据通常是一种很好的做法。
在本文中,您将了解如何使用标准 Python pickle API 将 XGBoost 模型保存到文件中。
完成本教程后,您将了解:
- 如何使用 pickle 保存并稍后加载训练有素的 XGBoost 模型。
- 如何使用 joblib 保存并稍后加载训练有素的 XGBoost 模型。
让我们开始吧。
- 2017 年 1 月更新:已更新,以反映 scikit-learn API 版本 0.18.1 中的更改。
- 更新 March / 2018 :添加了备用链接以下载数据集,因为原始图像已被删除。
如何在 Python 中使用 XGBoost 保存梯度提升模型 照片来自 Keoni Cabral ,保留一些权利。
使用 Pickle 序列化您的 XGBoost 模型
Pickle 是在 Python 中序列化对象的标准方法。
您可以使用 Python pickle API 序列化您的机器学习算法并将序列化格式保存到文件中,例如:
# save model to file
pickle.dump(model, open("pima.pickle.dat", "wb"))
稍后您可以加载此文件以反序列化模型并使用它来进行新的预测,例如:
# load model from file
loaded_model = pickle.load(open("pima.pickle.dat", "rb"))
以下示例演示了如何在 Pima 印第安人糖尿病数据集上训练 XGBoost 模型,将模型保存到文件中,然后加载它以做出预测(更新:从此处下载 )。
完整性代码清单如下所示。
# Train XGBoost model, save to file using pickle, load and make predictions
from numpy import loadtxt
import xgboost
import pickle
from sklearn import model_selection
from sklearn.metrics import accuracy_score
# load data
dataset = loadtxt('pima-indians-diabetes.csv', delimiter=",")
# split data into X and y
X = dataset[:,0:8]
Y = dataset[:,8]
# split data into train and test sets
seed = 7
test_size = 0.33
X_train, X_test, y_train, y_test = cross_validation.train_test_split(X, Y, test_size=test_size, random_state=seed)
# fit model no training data
model = xgboost.XGBClassifier()
model.fit(X_train, y_train)
# save model to file
pickle.dump(model, open("pima.pickle.dat", "wb"))
# some time later...
# load model from file
loaded_model = pickle.load(open("pima.pickle.dat", "rb"))
# make predictions for test data
y_pred = loaded_model.predict(X_test)
predictions = [round(value) for value in y_pred]
# evaluate predictions
accuracy = accuracy_score(y_test, predictions)
print("Accuracy: %.2f%%" % (accuracy * 100.0))
运行此示例将训练有素的 XGBoost 模型保存到当前工作目录中的 pima.pickle.dat pickle 文件中。
pima.pickle.dat
加载模型并对训练数据集做出预测后,将打印模型的准确率。
Accuracy: 77.95%
使用 joblib 序列化 XGBoost 模型
Joblib 是 SciPy 生态系统的一部分,并提供用于管道化 Python 作业的实用程序。
Joblib API 提供了用于保存和加载有效利用 NumPy 数据结构的 Python 对象的实用程序。对于非常大的模型,使用它可能是一种更快捷的方法。
API 看起来很像 pickle API,例如,您可以保存训练有素的模型,如下所示:
# save model to file
joblib.dump(model, "pima.joblib.dat")
您可以稍后从文件加载模型并使用它来进行如下预测:
# load model from file
loaded_model = joblib.load("pima.joblib.dat")
下面的示例演示了如何训练 XGBoost 模型在 Pima Indians 糖尿病数据集开始时进行分类,使用 Joblib 将模型保存到文件中,并在以后加载它以做出预测。
# Train XGBoost model, save to file using joblib, load and make predictions
from numpy import loadtxt
import xgboost
from sklearn.externals import joblib
from sklearn import model_selection
from sklearn.metrics import accuracy_score
# load data
dataset = loadtxt('pima-indians-diabetes.csv', delimiter=",")
# split data into X and y
X = dataset[:,0:8]
Y = dataset[:,8]
# split data into train and test sets
seed = 7
test_size = 0.33
X_train, X_test, y_train, y_test = cross_validation.train_test_split(X, Y, test_size=test_size, random_state=seed)
# fit model no training data
model = xgboost.XGBClassifier()
model.fit(X_train, y_train)
# save model to file
joblib.dump(model, "pima.joblib.dat")
# some time later...
# load model from file
loaded_model = joblib.load("pima.joblib.dat")
# make predictions for test data
y_pred = loaded_model.predict(X_test)
predictions = [round(value) for value in y_pred]
# evaluate predictions
accuracy = accuracy_score(y_test, predictions)
print("Accuracy: %.2f%%" % (accuracy * 100.0))
运行该示例将模型保存为当前工作目录中的 pima.joblib.dat 文件,并为模型中的每个 NumPy 数组创建一个文件(在本例中为两个附加文件)。
pima.joblib.dat
pima.joblib.dat_01.npy
pima.joblib.dat_02.npy
加载模型后,将在训练数据集上对其进行评估,并打印预测的准确率。
Accuracy: 77.95%
摘要
在这篇文章中,您了解了如何序列化经过训练的 XGBoost 模型,然后加载它们以做出预测。
具体来说,你学到了:
- 如何使用 pickle API 序列化并稍后加载训练有素的 XGBoost 模型。
- 如何使用 joblib API 序列化并稍后加载训练有素的 XGBoost 模型。
您对序列化 XGBoost 模型或此帖子有任何疑问吗?在评论中提出您的问题,我会尽力回答。
从梯度提升开始,比较 165 个数据集上的 13 种算法
原文:
machinelearningmastery.com/start-with-gradient-boosting/
你应该使用哪种机器学习算法?
这是应用机器学习的核心问题。
在 Randal Olson 和其他人最近的一篇论文中,他们试图回答它并为您提供算法和参数指南,以便在检查更广泛的算法套件之前首先尝试您的问题。
在这篇文章中,您将发现从大量机器学习数据集中评估许多机器学习算法的研究和结果,以及本研究提出的建议。
阅读这篇文章后,你会知道:
- 该集合树算法在各种数据集中表现良好。
- 由于没有银弹算法,因此测试一套问题的算法至关重要。
- 测试给定算法的一组配置至关重要,因为它可以使某些问题的表现提高 50%。
让我们开始吧。
从 Gradient Boosting 开始,但始终检查算法和配置 照片由 Ritesh Man Tamrakar ,保留一些权利。
论文
2017 年, Randal Olson 等。发布了一篇论文的预印本,其中有一个有趣的标题“数据驱动建议将机器学习应用于生物信息学问题”。
他们的工作目标是解决每个从业者在开始预测性建模问题时面临的问题;即:
我应该使用什么算法?
作者将此问题描述为选择重载,如下所示:
虽然有几个容易获得的 ML 算法实现对于寻求超越简单统计的生物信息学研究人员是有利的,但是许多研究人员经历“选择过载”并且难以为他们的问题选择正确的 ML 算法。
他们通过在大量标准机器学习数据集样本中运行适当的算法样本来解决问题,以查看哪些算法和参数通常最有效。
他们将论文描述为:
...在一组 165 个公开可用的分类问题上对 13 种最先进的常用机器学习算法进行全面分析,以便为当前研究人员提供数据驱动的算法建议
它非常类似于论文“我们需要数百个分类器来解决现实世界的分类问题吗? “覆盖在帖子中”使用随机森林:在 121 个数据集上测试 179 个分类器“的方法和结果。
机器学习算法
共有 13 种不同的算法被选择用于该研究。
选择算法以提供类型或基本假设的混合。
目标是代表文献中使用的最常见的算法类别,以及最新的最新算法
下面提供了完整的算法列表。
- 高斯朴素贝叶斯(GNB)
- 伯努利朴素贝叶斯(BNB)
- 多项式朴素贝叶斯(MNB)
- 逻辑回归(LR)
- 随机梯度下降(SGD)
- 被动攻击性分类器(PAC)
- 支持向量分类器(SVC)
- K-最近邻(KNN)
- 决策树(DT)
- 随机森林(RF)
- 额外树分类器(ERF)
- AdaBoost(AB)
- 梯度树提升(GTB)
scikit-learn 库用于实现这些算法。
每个算法具有零个或多个参数,并且针对每个算法执行跨合理参数值的网格搜索。
对于每种算法,使用固定网格搜索来调整超参数。
下面列出了算法表和评估的超参数,摘自论文。
算法和参数表
使用 10 倍交叉验证和平衡准确度测量来评估算法。
交叉验证没有重复,可能会在结果中引入一些统计噪声。
机器学习数据集
选择 165 个标准机器学习问题进行研究。
许多问题来自生物信息学领域,尽管并非所有数据集都属于这一研究领域。
所有预测问题都是具有两个或更多类别的分类类型问题。
在 Penn 机器学习基准(PMLB)的 165 个监督分类数据集上比较算法。 [...] PMLB 是一组公开可用的分类问题,这些问题已经标准化为相同的格式,并在中心位置收集,可通过 Python 轻松访问。
数据集来自 Penn 机器学习基准(PMLB)集合,该集合是一个以统一格式提供标准机器学习数据集并通过简单的 Python API 提供的项目。您可以在 GitHub 项目上了解有关此数据集目录的更多信息:
在拟合模型之前,所有数据集都是标准化的。
在评估每个 ML 算法之前,我们通过减去平均值并将特征缩放到单位方差来缩放每个数据集的特征。
未执行其他数据准备,也未执行特征选择或特征工程。
结果分析
进行大量实验后,需要分析很多技能分数。
对结果的分析处理得很好,提出了有趣的问题,并以易于理解的图表的形式提供了结果。
整个实验设计总共包含超过 550 万 ML 算法和参数评估,从而从多个角度分析了丰富的数据集......
对每个数据集进行算法表现排序,然后计算每个算法的平均等级。
这提供了一个粗略且易于理解的概念,即平均哪些算法表现良好。
结果表明,梯度提升和随机森林的等级最低(表现最好),朴素贝叶斯方法的平均等级最高(表现最差)。
事后测试强调了 Gradient Tree Boosting 的令人印象深刻的表现,其显着优于除了随机森林之外的每个算法(p <0.05)。 0.01 级。
这是从一篇很好的图表中得到的证明,摘自论文。
算法平均等级
没有一种算法表现最佳或最差。
这是机器学习从业者所熟知的智慧,但对于该领域的初学者来说很难掌握。
没有灵丹妙药,你必须在给定的数据集上测试一套算法,看看哪种算法效果最好。
...值得注意的是,没有一种 ML 算法在所有 165 个数据集中表现最佳。例如,尽管分别是整体最差和最佳排名的算法,但是有多个 NB 数据集,其中多项式 NB 执行以及优于梯度树增强(Gradient Tree Boosting)。因此,在将 ML 应用于新数据集时,考虑不同的 ML 算法仍然很重要。
此外,选择正确的算法是不够的。您还必须为数据集选择正确的算法配置。
......选择正确的 ML 算法并调整其参数对大多数问题都至关重要。
结果发现,调整算法可以将方法的技能提高 3%到 50%,具体取决于算法和数据集。
结果证明了使用默认 ML 算法超参数是不明智的:调整通常会将算法的准确度提高 3-5%,具体取决于算法。在某些情况下,参数调整导致 CV 精度提高 50%。
这可以通过论文中的图表来证明,该图表显示了参数调整对每种算法的改进。
通过参数调整提高算法表现
并非所有算法都是必需的。
结果发现,在 165 个测试数据集中的 106 个中,五个算法和特定参数的表现达到了 1%。
建议将这五种算法作为生物信息学中给定数据集上的点检查算法的起点,但我还建议更一般:
- 梯度提升
- 随机森林
- 支持向量分类器
- 额外的树木
- 逻辑回归
本文提供了这些算法的表格,包括推荐的参数设置和所涵盖的数据集的数量,例如:算法和配置达到最高 1%的表现。
建议的算法
实际发现
本文有两个重要的发现,对于从业者来说很有价值,特别是那些刚出生的人或那些因自己的预测模型问题而受到压力的人。
1.使用 Ensemble Trees
如果有疑问或时间压力,请在数据集上使用集合树算法,例如梯度提升和随机森林。
该分析展示了最先进的基于树的集成算法的强度,同时也显示了 ML 算法表现的依赖于问题的性质。
2.现场检查和调整
没有人可以看你的问题并告诉你使用什么算法,并且没有银弹算法。
您必须为每种算法测试一套算法和一套参数,以查看哪种算法最适合您的特定问题。
此外,分析表明,选择正确的 ML 算法并彻底调整其参数可以显着提高大多数问题的预测准确率,并且是每个 ML 应用中的关键步骤。
我一直在谈论这个问题;例如,看帖子:
进一步阅读
如果您希望深入了解,本节将提供有关该主题的更多资源。
- 将机器学习应用于生物信息学问题的数据驱动建议
- scikit-learn GitHub 基准测试
- 宾州机器学习基准
- scikit-learn 的预测模型在大量机器学习数据集上的定量比较:一个良好的开端
- 使用随机森林:在 121 个数据集上测试 179 个分类器
摘要
在这篇文章中,您发现了一项研究和调查结果,这些研究和结果来自大量机器学习数据集中的许多机器学习算法。
具体来说,你学到了:
- 该集合树算法在各种数据集中表现良好。
- 由于没有银弹算法,因此测试一套问题的算法至关重要。
- 测试给定算法的一组配置至关重要,因为它可以使某些问题的表现提高 50%。
你有任何问题吗? 在下面的评论中提出您的问题,我会尽力回答。
使用 Python、XGBoost 和 scikit-learn 的随机梯度提升
原文:
machinelearningmastery.com/stochastic-gradient-boosting-xgboost-scikit-learn-python/
用于集合决策树的简单技术涉及在训练数据集的子样本上训练树。
可以采用训练数据中的行的子集来训练称为装袋的单个树。当在计算每个分裂点时也获取训练数据的行的子集时,这被称为随机森林。
这些技术也可以在称为随机梯度提升的技术中用于梯度树增强模型。
在这篇文章中,您将发现随机梯度提升以及如何使用 XGBoost 和 Python 中的 scikit-learn 来调整采样参数。
阅读这篇文章后你会知道:
- 在数据的子样本上训练树的原理以及如何在梯度提升中使用它。
- 如何使用 scikit-learn 调整 XGBoost 中基于行的子采样。
- 如何在 XGBoost 中通过树和分割点调整基于列的子采样。
让我们开始吧。
- 2017 年 1 月更新:已更新,以反映 scikit-learn API 版本 0.18.1 中的更改。
随机梯度提升 XGBoost 和 scikit-Python 摄影:HenningKlokkeråsen,保留一些权利。
随机梯度提升
梯度提升是一个贪婪的程序。
将新决策树添加到模型中以校正现有模型的残差。
使用贪婪搜索过程创建每个决策树,以选择最佳地最小化目标函数的分割点。这可能导致树一次又一次地使用相同的属性甚至相同的分裂点。
Bagging 是一种技术,其中创建决策树的集合,每个决策树来自训练数据的不同行的随机子集。结果是,从树集合中获得了更好的表现,因为样本中的随机性允许创建略微不同的树,从而增加了集合预测的方差。
通过允许在选择分割点时对特征(列)进行二次采样,随机森林更进一步,向树集合添加进一步的方差。
这些相同的技术可用于在称为随机梯度提升的变化中的梯度提升中的决策树的构造中。
通常使用训练数据的积极子样本,例如 40%至 80%。
教程概述
在本教程中,我们将研究不同子采样技术在梯度提升中的效果。
我们将调整 Python 中 XGBoost 库支持的三种不同风格的随机梯度提升,具体来说:
- 在创建每个树时,对数据集中的行进行子采样。
- 在创建每个树时对数据集中的列进行子采样。
- 在创建每个树时,对数据集中每个拆分的列进行子采样。
问题描述:Otto Dataset
在本教程中,我们将使用 Otto Group 产品分类挑战数据集。
此数据集可从 Kaggle 免费获得(您需要注册 Kaggle 才能下载此数据集)。您可以从数据页面下载训练数据集 train.csv.zip ,并将解压缩的 train.csv 文件放入您的工作目录。
该数据集描述了超过 61,000 种产品的 93 个模糊细节,这些产品分为 10 个产品类别(例如时装,电子产品等)。输入属性是某种不同事件的计数。
目标是对新产品做出预测,因为 10 个类别中的每个类别都有一组概率,并且使用多类对数损失(也称为交叉熵)来评估模型。
这个竞赛在 2015 年 5 月完成,这个数据集对 XGBoost 来说是一个很好的挑战,因为它有很多例子,问题的难度以及需要很少数据准备的事实(除了将字符串类变量编码为整数)。
在 XGBoost 中调整行子采样
行子采样涉及选择训练数据集的随机样本而无需替换。
行子采样可以在子样本参数中的 XGBoost 类的 scikit-learn 包装器中指定。默认值为 1.0,不进行子采样。
我们可以使用 scikit-learn 内置的网格搜索功能来评估 Otto 数据集中 0.1 到 1.0 的不同子样本值的影响。
[0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 1.0]
子样本有 9 种变体,每种模型将使用 10 倍交叉验证进行评估,这意味着需要训练和测试 9×10 或 90 个模型。
完整的代码清单如下。
# XGBoost on Otto dataset, tune subsample
from pandas import read_csv
from xgboost import XGBClassifier
from sklearn.model_selection import GridSearchCV
from sklearn.model_selection import StratifiedKFold
from sklearn.preprocessing import LabelEncoder
import matplotlib
matplotlib.use('Agg')
from matplotlib import pyplot
# load data
data = read_csv('train.csv')
dataset = data.values
# split data into X and y
X = dataset[:,0:94]
y = dataset[:,94]
# encode string class values as integers
label_encoded_y = LabelEncoder().fit_transform(y)
# grid search
model = XGBClassifier()
subsample = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 1.0]
param_grid = dict(subsample=subsample)
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, label_encoded_y)
# summarize results
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))
# plot
pyplot.errorbar(subsample, means, yerr=stds)
pyplot.title("XGBoost subsample vs Log Loss")
pyplot.xlabel('subsample')
pyplot.ylabel('Log Loss')
pyplot.savefig('subsample.png')
运行此示例将打印每个已测试配置的最佳配置以及日志丢失。
我们可以看到,获得的最佳结果是 0.3,或使用 30%的训练数据集样本训练树。
Best: -0.000647 using {'subsample': 0.3}
-0.001156 (0.000286) with: {'subsample': 0.1}
-0.000765 (0.000430) with: {'subsample': 0.2}
-0.000647 (0.000471) with: {'subsample': 0.3}
-0.000659 (0.000635) with: {'subsample': 0.4}
-0.000717 (0.000849) with: {'subsample': 0.5}
-0.000773 (0.000998) with: {'subsample': 0.6}
-0.000877 (0.001179) with: {'subsample': 0.7}
-0.001007 (0.001371) with: {'subsample': 0.8}
-0.001239 (0.001730) with: {'subsample': 1.0}
我们可以绘制这些平均值和标准差对数损失值,以更好地理解表现如何随子采样值变化。
XGBoost 中调整行采样率的图
我们可以看到确实有 30%的人具有最佳的平均表现,但我们也可以看到,随着比率的增加,表现的差异也会显着增加。
值得注意的是,所有子样本值的平均表现优于没有子采样的平均表现(子样本= 1.0 )。
按树在 XGBoost 中调整列子采样
我们还可以在增强模型中创建每个决策树之前创建要使用的特征(或列)的随机样本。
在用于 scikit-learn 的 XGBoost 包装器中,这由 colsample_bytree 参数控制。
默认值为 1.0,表示在每个决策树中使用所有列。我们可以评估 colsample_bytree 的值在 0.1 和 1.0 之间递增 0.1。
[0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 1.0]
完整的代码清单如下。
# XGBoost on Otto dataset, tune colsample_bytree
from pandas import read_csv
from xgboost import XGBClassifier
from sklearn.model_selection import GridSearchCV
from sklearn.model_selection import StratifiedKFold
from sklearn.preprocessing import LabelEncoder
import matplotlib
matplotlib.use('Agg')
from matplotlib import pyplot
# load data
data = read_csv('train.csv')
dataset = data.values
# split data into X and y
X = dataset[:,0:94]
y = dataset[:,94]
# encode string class values as integers
label_encoded_y = LabelEncoder().fit_transform(y)
# grid search
model = XGBClassifier()
colsample_bytree = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 1.0]
param_grid = dict(colsample_bytree=colsample_bytree)
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, label_encoded_y)
# summarize results
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))
# plot
pyplot.errorbar(colsample_bytree, means, yerr=stds)
pyplot.title("XGBoost colsample_bytree vs Log Loss")
pyplot.xlabel('colsample_bytree')
pyplot.ylabel('Log Loss')
pyplot.savefig('colsample_bytree.png')
Running this example prints the best configuration as well as the log loss for each tested configuration.
我们可以看到该模型的最佳表现是 colsample_bytree = 1.0 。这表明对此问题的子采样列不会增加价值。
Best: -0.001239 using {'colsample_bytree': 1.0}
-0.298955 (0.002177) with: {'colsample_bytree': 0.1}
-0.092441 (0.000798) with: {'colsample_bytree': 0.2}
-0.029993 (0.000459) with: {'colsample_bytree': 0.3}
-0.010435 (0.000669) with: {'colsample_bytree': 0.4}
-0.004176 (0.000916) with: {'colsample_bytree': 0.5}
-0.002614 (0.001062) with: {'colsample_bytree': 0.6}
-0.001694 (0.001221) with: {'colsample_bytree': 0.7}
-0.001306 (0.001435) with: {'colsample_bytree': 0.8}
-0.001239 (0.001730) with: {'colsample_bytree': 1.0}
绘制结果,我们可以看到模型平台的表现(至少在这个尺度上),其值在 0.5 到 1.0 之间。
在 XGBoost 中调整每树列采样的图
通过拆分调整 XGBoost 中的列子采样
我们可以在决策树中的每个拆分中对它们进行二次采样,而不是对每个树进行一次子采样。原则上,这是随机森林中使用的方法。
我们可以在 XGBoost 包装器类的 colsample_bylevel 参数中为 scikit-learn 设置每个拆分使用的列样本的大小。
和以前一样,我们将比例从 10%变为默认的 100%。
The full code listing is provided below.
# XGBoost on Otto dataset, tune colsample_bylevel
from pandas import read_csv
from xgboost import XGBClassifier
from sklearn.model_selection import GridSearchCV
from sklearn.model_selection import StratifiedKFold
from sklearn.preprocessing import LabelEncoder
import matplotlib
matplotlib.use('Agg')
from matplotlib import pyplot
# load data
data = read_csv('train.csv')
dataset = data.values
# split data into X and y
X = dataset[:,0:94]
y = dataset[:,94]
# encode string class values as integers
label_encoded_y = LabelEncoder().fit_transform(y)
# grid search
model = XGBClassifier()
colsample_bylevel = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 1.0]
param_grid = dict(colsample_bylevel=colsample_bylevel)
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, label_encoded_y)
# summarize results
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))
# plot
pyplot.errorbar(colsample_bylevel, means, yerr=stds)
pyplot.title("XGBoost colsample_bylevel vs Log Loss")
pyplot.xlabel('colsample_bylevel')
pyplot.ylabel('Log Loss')
pyplot.savefig('colsample_bylevel.png')
Running this example prints the best configuration as well as the log loss for each tested configuration.
我们可以看到通过将 colsample_bylevel 设置为 70%来实现最佳结果,导致(反向)日志丢失-0.001062,这比将每树列采样设置为-0.001239 更好。 100%。
如果每个树的结果建议使用 100%的列,那么建议不要放弃列子采样,而是尝试按每个拆分列子采样。
Best: -0.001062 using {'colsample_bylevel': 0.7}
-0.159455 (0.007028) with: {'colsample_bylevel': 0.1}
-0.034391 (0.003533) with: {'colsample_bylevel': 0.2}
-0.007619 (0.000451) with: {'colsample_bylevel': 0.3}
-0.002982 (0.000726) with: {'colsample_bylevel': 0.4}
-0.001410 (0.000946) with: {'colsample_bylevel': 0.5}
-0.001182 (0.001144) with: {'colsample_bylevel': 0.6}
-0.001062 (0.001221) with: {'colsample_bylevel': 0.7}
-0.001071 (0.001427) with: {'colsample_bylevel': 0.8}
-0.001239 (0.001730) with: {'colsample_bylevel': 1.0}
我们可以绘制每个 colsample_bylevel 变体的表现。结果显示相对较低的方差,并且在此规模的值为 0.3 之后,表现似乎是表现的平台。
在 XGBoost 中调整每分割列采样的图
摘要
在这篇文章中,您发现了使用 Python 中的 XGBoost 进行随机梯度提升。
具体来说,你学到了:
- 关于随机增强以及如何对训练数据进行二次采样以改进模型的泛化
- 如何在 Python 和 scikit-learn 中使用 XGBoost 调整行子采样。
- 如何使用每个树和每个拆分的 XGBoost 调整列子采样。
您对随机梯度提升或关于这篇文章有任何疑问吗?在评论中提出您的问题,我会尽力回答。
如何使用 Amazon Web Services 在云中训练 XGBoost 模型
原文:
machinelearningmastery.com/train-xgboost-models-cloud-amazon-web-services/
XGBoost 库提供了针对速度和表现而设计的梯度提升实现。
它的实现是为了充分利用您的计算资源,包括所有 CPU 内核和内存。
在这篇文章中,您将了解如何在亚马逊的云服务上设置服务器,以便快速,廉价地创建非常大的模型。
阅读这篇文章后你会知道:
- 如何设置和配置 Amazon EC2 服务器实例以与 XGBoost 一起使用。
- 如何确认 XGBoost 的并行功能正在您的服务器上运行。
- 如何将数据和代码传输到您的服务器并训练一个非常大的模型。
让我们开始吧。
如何使用亚马逊网络服务在云中训练 XGBoost 模型 照片由 Dennis Jarvis 拍摄,保留一些权利。
教程概述
这个过程非常简单。以下是我们将在本教程中完成的步骤的概述。
- 设置您的 AWS 账户(如果需要)。
- 启动您的 AWS 实例。
- 登录并运行您的代码。
- 训练 XGBoost 模型。
- 关闭您的 AWS 实例。
注意,在 Amazon 上使用虚拟服务器实例需要花钱。临时模型开发的成本非常低(例如每小时不到一美元),这就是为什么它如此吸引人,但它不是免费的。
服务器实例运行 Linux。尽管不需要您知道如何导航 Linux 或类 Unix 环境,但这是可取的。我们只是运行我们的 Python 脚本,因此不需要高级技能。
1.设置您的 AWS 账户(如果需要)
您需要在 Amazon Web Services 上拥有一个帐户。
- 1.您可以通过单击“登录到控制台”,使用 Amazon Web Services 门户创建帐户。从那里,您可以使用现有的亚马逊帐户登录或创建新帐户。
AWS 登录按钮
- 2.如果要创建帐户,您需要提供您的详细信息以及亚马逊可以收取的有效信用卡。如果您已经是亚马逊客户并且已将您的信用卡存档,那么此过程会快得多。
注意:如果您已经创建了一个新帐户,则可能需要向 Amazon 支持请求才能获得批准在本教程的其余部分中使用更大(非免费)的服务器实例。
2.启动服务器实例
现在您已拥有 AWS 账户,您希望启动可在其上运行 XGBoost 的 EC2 虚拟服务器实例。
启动实例就像选择要加载和启动虚拟服务器的映像一样简单。
我们将使用现有的 Fedora Linux 映像并手动安装 Python 和 XGBoost。
- 1.如果您尚未登录 AWS 控制台,请登录。
AWS 控制台
- 2.单击 EC2 以启动新的虚拟服务器。
- 3.选择“N.加州“从右上角的下拉菜单开始。这很重要,否则您可能无法找到我们计划使用的图像(称为 AMI)。
选择 N California
- 4.单击“启动实例”按钮。
- 5.单击“社区 AMI”。 AMI 是亚马逊机器映像。它是服务器的冻结实例,您可以在新虚拟服务器上进行选择和实例化。
社区 AMI
- 6.在“搜索社区 AMI”搜索框中输入 AMI:“ ami-02d09662 ”,然后按 Enter 键。您应该看到一个结果。
这是 Fedora Linux 24 版本的基础安装图像。这是一个非常易于使用的 Linux 发行版。
选择 64 位 Fedora Linux AMI
- 7.单击“选择”以在搜索结果中选择 AMI。
- 8.现在您需要选择运行映像的硬件。向下滚动并选择“c3.8xlarge”硬件。
这是一个包含 32 个 CPU 核心,60 GB RAM 和 2 个大型 SSD 磁盘的大型实例。
选择 c3.8xlarge 实例类型
- 9.单击“查看并启动”以完成服务器实例的配置。
您将看到类似“您的实例配置不符合免费使用套餐”的警告。这只是表明您将在此服务器上收取费用。我们知道这一点,忽略这个警告。
您的实例配置不符合免费使用套餐的条件
- 10.单击“启动”按钮。
- 11.选择 SSH 密钥对。
- 如果您之前使用过 EC2,则选择“选择现有密钥对”并从列表中选择密钥对。然后检查“我确认......”。
- 如果您没有密钥对,请选择“创建新密钥对”选项并输入“密钥对名称”,例如“xgboost-keypair”。单击“下载密钥对”按钮。
- 12.打开终端并将目录更改为您下载密钥对的位置。
- 13.如果尚未执行此操作,请限制密钥对文件的访问权限。这是 SSH 访问服务器的一部分。例如,在您的控制台上,您可以键入:
cd Downloads
chmod 600 xgboost-keypair.pem
- 14.单击“启动实例”。
注意:如果这是您第一次使用 AWS,亚马逊可能需要验证您的请求,这可能需要 2 个小时(通常只需几分钟)。
- 15.单击“查看实例”以查看实例的状态。
检查您的运行实例并记下其 IP 地址
您的服务器现在正在运行,可以登录。
3.登录和配置
现在您已经启动了服务器实例,现在可以登录并配置它以供使用。
每次启动服务器时都需要配置服务器。因此,批处理所有工作是个好主意,这样您就可以充分利用已配置的服务器。
配置服务器不会花费很长时间,总共可能需要 10 分钟。
- 1.如果您还没有,请单击 Amazon EC2 控制台中的“查看实例”。
- 2.将“公共 IP”(在“描述”中的屏幕底部)复制到剪贴板。
在此示例中,我的 IP 地址为 52.53.185.166。 请勿使用此 IP 地址,您的 IP 地址会有所不同。
- 3.打开终端并将目录更改为您下载密钥对的位置。使用 SSH 登录您的服务器,例如您可以输入:
ssh -i xgboost-keypair.pem fedora@52.53.185.166
- 4.第一次登录服务器实例时可能会提示您警告。您可以忽略此警告,只需键入“是”并按 Enter 键即可。
您现在已登录到您的服务器。
通过键入,仔细检查实例上的 CPU 核心数
cat /proc/cpuinfo | grep processor | wc -l
你应该看到:
32
3A。安装支持包
第一步是安装所有软件包以支持 XGBoost。
这包括 GCC,Python 和 SciPy 栈。我们将使用 Fedora 包管理器 dnf (新的 yum)。
这是一行:
sudo dnf install gcc gcc-c++ make git unzip python python2-numpy python2-scipy python2-scikit-learn python2-pandas python2-matplotlib
输入“y”并在提示时按 Enter 确认要安装的软件包。
这将需要几分钟时间来下载并安装所有必需的软件包。
完成后,我们可以确认环境已成功安装。
i)检查 GCC
类型:
gcc --version
You should see:
gcc (GCC) 6.1.1 20160621 (Red Hat 6.1.1-3)
Copyright (C) 2016 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
ii)检查 Python
Type:
python --version
You should see:
Python 2.7.12
iii)检查 SciPy
Type:
python -c "import scipy;print(scipy.__version__)"
python -c "import numpy;print(numpy.__version__)"
python -c "import pandas;print(pandas.__version__)"
python -c "import sklearn;print(sklearn.__version__)"
你应该看到类似的东西:
0.16.1
1.11.0
0.18.0
0.17.1
注意:如果其中任何一项检查失败,请停止并更正任何错误。在继续之前,您必须拥有完整的工作环境。
我们现在准备安装 XGBoost。
3B。构建并安装 XGBoost
XGBoost 的安装说明已完成,我们可以直接关注它们。
首先,我们需要在服务器上下载项目。
git clone --recursive https://github.com/dmlc/xgboost
cd xgboost
接下来我们需要编译它。 -j 参数可用于指定期望的核心数。对于 AWS 实例上的 32 个核心,我们可以将其设置为 32。
如果您选择了不同的 AWS 硬件,则可以适当地进行设置。
make -j32
XGBoost 项目应该成功构建(例如没有错误)。
我们现在准备安装该库的 Python 版本。
cd python-package
sudo python setup.py install
这就对了。
我们可以输入以下内容确认安装是否成功:
python -c "import xgboost;print(xgboost.__version__)"
这应该打印如下:
0.4
4.训练 XGBoost 模型
让我们通过运行带有大量内核的 XGBoost 来测试您的大型 AWS 实例。
在本教程中,我们将使用 Otto Group 产品分类挑战数据集。
此数据集可从 Kaggle 免费获得(您需要注册 Kaggle 才能下载此数据集)。它描述了超过 61,000 种产品的 93 个模糊细节,这些产品分为 10 个产品类别(例如时装,电子产品等)。输入变量是某种不同事件的计数。
目标是对新产品做出预测,因为 10 个类别中的每个类别都有一组概率,并且使用多类对数损失(也称为交叉熵)来评估模型。
这个竞赛在 2015 年 5 月完成,这个数据集对 XGBoost 来说是一个很好的挑战,因为它有很多例子,问题的难度以及需要很少数据准备的事实(除了将字符串类变量编码为整数)。
在工作站上创建一个名为 work / 的新目录。
您可以从数据页面下载训练数据集 train.csv.zip 并将其放在工作站上的工作/ 目录中。
我们将使用不同数量的核心评估在此数据集上训练 XGBoost 所花费的时间。
我们将尝试 1 个核心,一半核心 16 和所有 32 个核心。我们可以通过在 XGBClassifier 类(XGBoost 的 scikit-learn 包装器)中设置 nthread 参数来指定 XGBoost 算法使用的核心数。
下面列出了完整的示例。将其保存在名为 work / script.py 的文件中。
# Otto multi-core test
from pandas import read_csv
from xgboost import XGBClassifier
from sklearn.preprocessing import LabelEncoder
import time
# load data
data = read_csv('train.csv')
dataset = data.values
# split data into X and y
X = dataset[:,0:94]
y = dataset[:,94]
# encode string class values as integers
label_encoded_y = LabelEncoder().fit_transform(y)
# evaluate the effect of the number of threads
results = []
num_threads = [1, 16, 32]
for n in num_threads:
start = time.time()
model = XGBClassifier(nthread=n)
model.fit(X, label_encoded_y)
elapsed = time.time() - start
print(n, elapsed)
results.append(elapsed)
现在,我们可以将您的工作/ 目录与数据和脚本一起复制到您的 AWS 服务器。
从工作/ 目录所在的当前目录中的工作站,键入:
scp -r -i xgboost-keypair.pem work fedora@52.53.185.166:/home/fedora/
当然,您需要使用密钥文件和服务器的 IP 地址。
这将在服务器的主目录中创建一个新的工作/ 目录。
重新登录到您的服务器实例(如果需要):
ssh -i xgboost-keypair.pem fedora@52.53.185.166
将目录更改为工作目录并解压缩训练数据。
cd work
unzip ./train.csv.data
现在我们可以运行脚本并训练我们的 XGBoost 模型并计算使用不同数量的核心所需的时间:
python script.py
您应该看到如下输出:
(1, 84.26896095275879)
(16, 6.597043037414551)
(32, 7.6703619956970215)
您可以看到 16 到 32 个核心之间的差别很小。我相信这样做的原因是 AWS 可以通过超线程访问 16 个物理内核,从而提供额外的虚拟内核。不过,在 7 秒内构建一个大型 XGBoost 模型非常棒。
您可以将此作为模板用于将自己的数据和脚本复制到 AWS 实例。
一个好的建议是将脚本作为后台进程运行,并将任何输出转发到文件。这是为了防止您与服务器的连接中断或者您要关闭它并让服务器整晚运行您的代码。
您可以将代码作为后台进程运行,并通过键入以下内容将输出重定向到文件:
nohup python script.py >script.py.out 2>&1 &
现在我们完成了,我们可以关闭 AWS 实例。
5.关闭您的 AWS 实例
完成工作后,您必须关闭实例。
请记住,您需要按照使用该实例的时间收费。它很便宜,但如果你不使用它,你不想留下实例。
- 1.在终端注销您的实例,例如您可以输入:
exit
- 2.使用 Web 浏览器登录 AWS 账户。
- 3.单击 EC2。
- 4.单击左侧菜单中的“Instances”。
- 5.从列表中选择正在运行的实例(如果您只有一个正在运行的实例,则可能已选中该实例)。
- 6.单击“操作”按钮并选择“实例状态”,然后选择“终止”。确认您要终止正在运行的实例。
实例可能需要几秒钟才能关闭并从实例列表中删除。
而已。
摘要
在这篇文章中,您了解了如何在 Amazon 云基础架构上训练大型 XGBoost 模型。
具体来说,你学到了:
- 如何在 Amazon EC2 上为 XGBoost 启动和配置 Linux 服务器实例。
- 如何安装在 Python 中运行 XGBoost 库所需的所有必需软件。
- 如何将数据和代码传输到服务器并使用服务器上的所有核心训练大型模型。
您对在 Amazon Web Services 或此帖子上训练 XGBoost 模型有任何疑问吗?在评论中提出您的问题,我会尽力回答。
使用 Python 和 XGBoost 调整梯度提升的学习率
原文:
machinelearningmastery.com/tune-learning-rate-for-gradient-boosting-with-xgboost-in-python/
梯度提升决策树的问题在于它们快速学习和过度训练数据。
在梯度提升模型中减慢学习速度的一种有效方法是使用学习速率,也称为收缩(或 XGBoost 文档中的 eta)。
在这篇文章中,您将发现梯度提升中学习速率的影响以及如何使用 Python 中的 XGBoost 库将其调整到机器学习问题上。
阅读这篇文章后你会知道:
- 效果学习率对梯度提升模型有影响。
- 如何在您的机器上调整学习率来学习您的问题。
- 如何调整提升树木数量和问题学习率之间的权衡。
让我们开始吧。
- 2017 年 1 月更新:已更新,以反映 scikit-learn API 版本 0.18.1 中的更改。
在 Python 中使用 XGBoost 调整梯度提升的学习率 照片由 Robert Hertel 拍摄,保留一些权利。
缓慢学习梯度提升与学习率
梯度提升涉及按顺序为模型创建和添加树。
创建新树以从现有树序列中校正预测中的残差。
效果是模型可以快速拟合,然后过拟合训练数据集。
在梯度提升模型中减慢学习的技术是在添加到模型时应用新树的校正的加权因子。
这种加权称为收缩因子或学习率,取决于文献或工具。
天然梯度提升与收缩时的梯度提升相同,其中收缩系数设定为 1.0。设置值小于 1.0 会对添加到模型中的每个树进行较少的更正。这反过来导致必须将更多树添加到模型中。
通常具有 0.1 至 0.3 范围内的小值,以及小于 0.1 的值。
让我们研究一下学习率对标准机器学习数据集的影响。
问题描述:Otto Dataset
在本教程中,我们将使用 Otto Group 产品分类挑战数据集。
此数据集可从 Kaggle 免费获得(您需要注册 Kaggle 才能下载此数据集)。您可以从数据页面下载训练数据集 train.csv.zip ,并将解压缩的 train.csv 文件放入您的工作目录。
该数据集描述了超过 61,000 种产品的 93 个模糊细节,这些产品分为 10 个产品类别(例如时装,电子产品等)。输入属性是某种不同事件的计数。
目标是对新产品做出预测,因为 10 个类别中的每个类别都有一组概率,并且使用多类对数损失(也称为交叉熵)来评估模型。
这个竞赛在 2015 年 5 月完成,这个数据集对 XGBoost 来说是一个很好的挑战,因为它有很多例子,问题的难度以及需要很少数据准备的事实(除了将字符串类变量编码为整数)。
在 XGBoost 中调整学习率
使用 scikit-learn 包装器创建具有 XGBoost 的梯度提升模型时,可以设置 learning_rate 参数来控制添加到模型中的新树的权重。
我们可以使用 scikit-learn 中的网格搜索功能来评估训练具有不同学习速率值的梯度提升模型的对数损失的影响。
我们将树的数量保持为默认值 100,并评估 Otto 数据集上学习率的标准值套件。
learning_rate = [0.0001, 0.001, 0.01, 0.1, 0.2, 0.3]
要测试的学习率有 6 种变化,每种变化将使用 10 倍交叉验证进行评估,这意味着总共需要训练和评估 6×10 或 60 个 XGBoost 模型。
将打印每个学习率的对数损失以及导致最佳表现的值。
# XGBoost on Otto dataset, Tune learning_rate
from pandas import read_csv
from xgboost import XGBClassifier
from sklearn.model_selection import GridSearchCV
from sklearn.model_selection import StratifiedKFold
from sklearn.preprocessing import LabelEncoder
import matplotlib
matplotlib.use('Agg')
from matplotlib import pyplot
# load data
data = read_csv('train.csv')
dataset = data.values
# split data into X and y
X = dataset[:,0:94]
y = dataset[:,94]
# encode string class values as integers
label_encoded_y = LabelEncoder().fit_transform(y)
# grid search
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, label_encoded_y)
# summarize results
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))
# plot
pyplot.errorbar(learning_rate, means, yerr=stds)
pyplot.title("XGBoost learning_rate vs Log Loss")
pyplot.xlabel('learning_rate')
pyplot.ylabel('Log Loss')
pyplot.savefig('learning_rate.png')
运行此示例将打印每个评估学习速率的最佳结果以及日志丢失。
Best: -0.001156 using {'learning_rate': 0.2}
-2.155497 (0.000081) with: {'learning_rate': 0.0001}
-1.841069 (0.000716) with: {'learning_rate': 0.001}
-0.597299 (0.000822) with: {'learning_rate': 0.01}
-0.001239 (0.001730) with: {'learning_rate': 0.1}
-0.001156 (0.001684) with: {'learning_rate': 0.2}
-0.001158 (0.001666) with: {'learning_rate': 0.3}
有趣的是,我们可以看到最佳学习率为 0.2。
这是一个很高的学习率,它表明,100 的默认树数可能太低,需要增加。
我们还可以绘制(倒置的)对数损失分数的学习率的影响,尽管所选择的 learning_rate 值的 log10 样扩展意味着大多数被压缩在接近零的图的左侧。
在 XGBoost 中调整学习率
接下来,我们将研究在改变学习率的同时改变树的数量。
调整学习率和 XGBoost 中的树数
较小的学习率通常需要将更多树添加到模型中。
我们可以通过评估参数对的网格来探索这种关系。决策树的数量将在 100 到 500 之间变化,学习率在 log10 范围内从 0.0001 变化到 0.1。
n_estimators = [100, 200, 300, 400, 500]
learning_rate = [0.0001, 0.001, 0.01, 0.1]
n_estimators 有 5 种变体, learning_rate 有 4 种变体。每个组合将使用 10 倍交叉验证进行评估,因此总共需要训练和评估 4x5x10 或 200 个 XGBoost 模型。
期望的是,对于给定的学习率,随着树木数量的增加,表现将提高然后稳定。完整的代码清单如下。
# XGBoost on Otto dataset, Tune learning_rate and n_estimators
from pandas import read_csv
from xgboost import XGBClassifier
from sklearn.model_selection import GridSearchCV
from sklearn.model_selection import StratifiedKFold
from sklearn.preprocessing import LabelEncoder
import matplotlib
matplotlib.use('Agg')
from matplotlib import pyplot
import numpy
# load data
data = read_csv('train.csv')
dataset = data.values
# split data into X and y
X = dataset[:,0:94]
y = dataset[:,94]
# encode string class values as integers
label_encoded_y = LabelEncoder().fit_transform(y)
# grid search
model = XGBClassifier()
n_estimators = [100, 200, 300, 400, 500]
learning_rate = [0.0001, 0.001, 0.01, 0.1]
param_grid = dict(learning_rate=learning_rate, n_estimators=n_estimators)
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, label_encoded_y)
# summarize results
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))
# plot results
scores = numpy.array(means).reshape(len(learning_rate), len(n_estimators))
for i, value in enumerate(learning_rate):
pyplot.plot(n_estimators, scores[i], label='learning_rate: ' + str(value))
pyplot.legend()
pyplot.xlabel('n_estimators')
pyplot.ylabel('Log Loss')
pyplot.savefig('n_estimators_vs_learning_rate.png')
运行该示例将打印每个已评估对的最佳组合以及日志丢失。
Best: -0.001152 using {'n_estimators': 300, 'learning_rate': 0.1}
-2.155497 (0.000081) with: {'n_estimators': 100, 'learning_rate': 0.0001}
-2.115540 (0.000159) with: {'n_estimators': 200, 'learning_rate': 0.0001}
-2.077211 (0.000233) with: {'n_estimators': 300, 'learning_rate': 0.0001}
-2.040386 (0.000304) with: {'n_estimators': 400, 'learning_rate': 0.0001}
-2.004955 (0.000373) with: {'n_estimators': 500, 'learning_rate': 0.0001}
-1.841069 (0.000716) with: {'n_estimators': 100, 'learning_rate': 0.001}
-1.572384 (0.000692) with: {'n_estimators': 200, 'learning_rate': 0.001}
-1.364543 (0.000699) with: {'n_estimators': 300, 'learning_rate': 0.001}
-1.196490 (0.000713) with: {'n_estimators': 400, 'learning_rate': 0.001}
-1.056687 (0.000728) with: {'n_estimators': 500, 'learning_rate': 0.001}
-0.597299 (0.000822) with: {'n_estimators': 100, 'learning_rate': 0.01}
-0.214311 (0.000929) with: {'n_estimators': 200, 'learning_rate': 0.01}
-0.080729 (0.000982) with: {'n_estimators': 300, 'learning_rate': 0.01}
-0.030533 (0.000949) with: {'n_estimators': 400, 'learning_rate': 0.01}
-0.011769 (0.001071) with: {'n_estimators': 500, 'learning_rate': 0.01}
-0.001239 (0.001730) with: {'n_estimators': 100, 'learning_rate': 0.1}
-0.001153 (0.001702) with: {'n_estimators': 200, 'learning_rate': 0.1}
-0.001152 (0.001704) with: {'n_estimators': 300, 'learning_rate': 0.1}
-0.001153 (0.001708) with: {'n_estimators': 400, 'learning_rate': 0.1}
-0.001153 (0.001708) with: {'n_estimators': 500, 'learning_rate': 0.1}
我们可以看到观察到的最佳结果是有 300 棵树的学习率为 0.1。
很难从原始数据和小的负日志损失结果中挑选出趋势。下面是每个学习率的图表,显示了树木数量变化时的对数损失表现。
调整 XGBoost 中的学习率和树数
我们可以看到预期的总趋势成立,其中表现(反向对数损失)随着树木数量的增加而提高。
对于较小的学习率,表现通常较差,这表明可能需要更多的树木。我们可能需要将树的数量增加到数千,这可能在计算上非常昂贵。
由于图的大 y 轴比例, learning_rate = 0.1 的结果变得模糊。我们可以只为 learning_rate = 0.1 提取表现测量并直接绘制它们。
# Plot performance for learning_rate=0.1
from matplotlib import pyplot
n_estimators = [100, 200, 300, 400, 500]
loss = [-0.001239, -0.001153, -0.001152, -0.001153, -0.001153]
pyplot.plot(n_estimators, loss)
pyplot.xlabel('n_estimators')
pyplot.ylabel('Log Loss')
pyplot.title('XGBoost learning_rate=0.1 n_estimators vs Log Loss')
pyplot.show()
运行此代码会显示随着树木数量的增加而提高的表现,其次是 400 和 500 棵树的表现平稳。
学习率的曲线= 0.1 并且改变 XGBoost 中的树数
摘要
在这篇文章中,您发现了为梯度提升模型加权添加新树的效果,称为收缩或学习率。
具体来说,你学到了:
- 增加学习速率旨在减慢模型对训练数据的适应性。
- 如何评估机器学习问题的一系列学习率值。
- 如何评估改变树木数量和学习率的关系。
您对梯度提升或此帖的收缩有任何疑问吗?在评论中提出您的问题,我会尽力回答。
使用 Python 和 XGBoost 调整决策树的数量和大小
原文:
machinelearningmastery.com/tune-number-size-decision-trees-xgboost-python/
梯度提升包括顺序创建和添加决策树,每个尝试纠正前面的学习器的错误。
这提出了一个问题:在梯度提升模型中要配置多少树(弱学习器或估计者)以及每棵树应该有多大。
在这篇文章中,您将了解如何设计系统实验来选择决策树的数量和大小以用于您的问题。
阅读这篇文章后你会知道:
- 如何评估向 XGBoost 模型添加更多决策树的效果。
- 如何评估为 XGBoost 模型创建更大的决策树的效果。
- 如何调查问题树的数量和深度之间的关系。
让我们开始吧。
- 2017 年 1 月更新:已更新,以反映 scikit-learn API 版本 0.18.1 中的更改。
如何在 Python 中使用 XGBoost 调整决策树的数量和大小 照片由 USFWSmidwest ,保留一些权利。
问题描述:Otto Dataset
在本教程中,我们将使用 Otto Group 产品分类挑战数据集。
此数据集可从 Kaggle 免费获得(您需要注册 Kaggle 才能下载此数据集)。您可以从数据页面下载训练数据集 train.csv.zip ,并将解压缩的 train.csv 文件放入您的工作目录。
该数据集描述了超过 61,000 种产品的 93 个模糊细节,这些产品分为 10 个产品类别(例如时装,电子产品等)。输入属性是某种不同事件的计数。
目标是对新产品做出预测,因为 10 个类别中的每个类别都有一组概率,并且使用多类对数损失(也称为交叉熵)来评估模型。
这个竞赛在 2015 年 5 月完成,这个数据集对 XGBoost 来说是一个很好的挑战,因为它有很多例子,问题的难度以及需要很少数据准备的事实(除了将字符串类变量编码为整数)。
调整 XGBoost 中的决策树数量
大多数梯度提升的实现默认配置有相对较少数量的树,例如数百或数千。
一般原因是,在大多数问题上,添加超出限制的更多树不会改善模型的表现。
原因在于构造了增强树模型的方式,顺序地每个新树尝试建模并校正由先前树序列产生的错误。很快,该模型达到了收益递减的程度。
我们可以在 Otto 数据集上轻松证明这一收益递减点。
XGBoost 模型中的树(或舍入)数量是在 n_estimators 参数中指定给 XGBClassifier 或 XGBRegressor 类的。 XGBoost 库中的默认值为 100。
使用 scikit-learn,我们可以对 n_estimators 模型参数进行网格搜索,评估 50 到 350 的一系列值,步长为 50(50,150,200,250,300,350) 。
# grid search
model = XGBClassifier()
n_estimators = range(50, 400, 50)
param_grid = dict(n_estimators=n_estimators)
kfold = StratifiedKFold(n_splits scoring="neg_log_loss", n_jobs=-1, cv=kfold)
result = grid_search.fit(X, label_encoded_y)
我们可以在 Otto 数据集上执行此网格搜索,使用 10 倍交叉验证,需要训练 60 个模型(6 个配置* 10 倍)。
完整性代码清单如下所示。
# XGBoost on Otto dataset, Tune n_estimators
from pandas import read_csv
from xgboost import XGBClassifier
from sklearn.model_selection import GridSearchCV
from sklearn.model_selection import StratifiedKFold
from sklearn.preprocessing import LabelEncoder
import matplotlib
matplotlib.use('Agg')
from matplotlib import pyplot
# load data
data = read_csv('train.csv')
dataset = data.values
# split data into X and y
X = dataset[:,0:94]
y = dataset[:,94]
# encode string class values as integers
label_encoded_y = LabelEncoder().fit_transform(y)
# grid search
model = XGBClassifier()
n_estimators = range(50, 400, 50)
param_grid = dict(n_estimators=n_estimators)
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, label_encoded_y)
# summarize results
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))
# plot
pyplot.errorbar(n_estimators, means, yerr=stds)
pyplot.title("XGBoost n_estimators vs Log Loss")
pyplot.xlabel('n_estimators')
pyplot.ylabel('Log Loss')
pyplot.savefig('n_estimators.png')
运行此示例将打印以下结果。
Best: -0.001152 using {'n_estimators': 250}
-0.010970 (0.001083) with: {'n_estimators': 50}
-0.001239 (0.001730) with: {'n_estimators': 100}
-0.001163 (0.001715) with: {'n_estimators': 150}
-0.001153 (0.001702) with: {'n_estimators': 200}
-0.001152 (0.001702) with: {'n_estimators': 250}
-0.001152 (0.001704) with: {'n_estimators': 300}
-0.001153 (0.001706) with: {'n_estimators': 350}
我们可以看到交叉验证日志损失分数是负数。这是因为 scikit-learn 交叉验证框架颠倒了它们。原因是在内部,框架要求所有正在优化的度量标准都要最大化,而日志丢失则是最小化度量标准。通过反转分数可以很容易地使其最大化。
最好的树数是 n_estimators = 250 ,导致对数损失为 0.001152,但与 n_estimators = 200 实际上没有显着差异。事实上,如果我们绘制结果,那么在 100 到 350 之间的树木数量之间没有很大的相对差异。
下面的线图显示了树木数量与平均(倒置)对数损失之间的关系,标准差显示为误差条。
调整 XGBoost 中的树数
调整 XGBoost 中决策树的大小
在梯度提升中,我们可以控制决策树的大小,也称为层数或深度。
预计浅树的表现不佳,因为它们捕捉的问题细节很少,通常被称为弱学习器。更深的树通常捕获太多问题细节并过拟合训练数据集,限制了对新数据做出良好预测的能力。
通常,提升算法配置有弱学习器,具有少量层的决策树,有时像根节点一样简单,也称为决策树而不是决策树。
可以在 max_depth 参数中的 XGBC 分类器和 XGBRegressor XGBoost 包装类中指定最大深度。此参数采用整数值,默认值为 3。
model = XGBClassifier(max_depth=3)
我们可以使用关于 Otto 数据集的 scikit-learn 中的网格搜索基础结构来调整 XGBoost 的这个超参数。下面我们评估 max_depth 的奇数值在 1 到 9 之间(1,3,5,7,9)。
使用 10 倍交叉验证评估 5 种配置中的每一种,从而构建 50 个模型。完整性代码清单如下所示。
# XGBoost on Otto dataset, Tune max_depth
from pandas import read_csv
from xgboost import XGBClassifier
from sklearn.model_selection import GridSearchCV
from sklearn.model_selection import StratifiedKFold
from sklearn.preprocessing import LabelEncoder
import matplotlib
matplotlib.use('Agg')
from matplotlib import pyplot
# load data
data = read_csv('train.csv')
dataset = data.values
# split data into X and y
X = dataset[:,0:94]
y = dataset[:,94]
# encode string class values as integers
label_encoded_y = LabelEncoder().fit_transform(y)
# grid search
model = XGBClassifier()
max_depth = range(1, 11, 2)
print(max_depth)
param_grid = dict(max_depth=max_depth)
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)
grid_result = grid_search.fit(X, label_encoded_y)
# summarize results
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))
# plot
pyplot.errorbar(max_depth, means, yerr=stds)
pyplot.title("XGBoost max_depth vs Log Loss")
pyplot.xlabel('max_depth')
pyplot.ylabel('Log Loss')
pyplot.savefig('max_depth.png')
运行此示例将打印每个 max_depth 的日志丢失。
最佳配置为 max_depth = 5 ,导致对数损失为 0.001236。
Best: -0.001236 using {'max_depth': 5}
-0.026235 (0.000898) with: {'max_depth': 1}
-0.001239 (0.001730) with: {'max_depth': 3}
-0.001236 (0.001701) with: {'max_depth': 5}
-0.001237 (0.001701) with: {'max_depth': 7}
-0.001237 (0.001701) with: {'max_depth': 9}
回顾日志损失得分图,我们可以看到从 max_depth = 1 到 max_depth = 3 的显着跳跃,然后其余的表现相当均匀 max_depth 的值]。
尽管 max_depth = 5 观察到最佳评分,但值得注意的是,使用 max_depth = 3 或 max_depth = 7 之间几乎没有差异。
这表明 max_depth 在你可以使用网格搜索挑出的问题上的收益递减点。将 max_depth 值的图对下面的(反向)对数损失作图。
调整 XGBoost 中的最大树深度
调整 XGBoost 中的树数和最大深度
模型中的树木数量与每棵树的深度之间存在关系。
我们期望更深的树将导致模型中需要更少的树,并且更简单的树(例如决策树桩)需要更多树以实现类似结果。
我们可以通过评估 n_estimators 和 max_depth 配置值的网格来研究这种关系。为避免评估花费太长时间,我们将限制评估的配置值总数。选择参数来梳理关系而不是优化模型。
我们将创建一个包含 4 个不同 n_estimators 值(50,100,150,200)和 4 个不同 max_depth 值(2,4,6,8)的网格,并且将使用 10 倍交叉验证来评估每个组合。将训练和评估总共 4 * 4 * 10 或 160 个型号。
完整的代码清单如下。
# XGBoost on Otto dataset, Tune n_estimators and max_depth
from pandas import read_csv
from xgboost import XGBClassifier
from sklearn.model_selection import GridSearchCV
from sklearn.model_selection import StratifiedKFold
from sklearn.preprocessing import LabelEncoder
import matplotlib
matplotlib.use('Agg')
from matplotlib import pyplot
import numpy
# load data
data = read_csv('train.csv')
dataset = data.values
# split data into X and y
X = dataset[:,0:94]
y = dataset[:,94]
# encode string class values as integers
label_encoded_y = LabelEncoder().fit_transform(y)
# grid search
model = XGBClassifier()
n_estimators = [50, 100, 150, 200]
max_depth = [2, 4, 6, 8]
print(max_depth)
param_grid = dict(max_depth=max_depth, n_estimators=n_estimators)
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)
grid_result = grid_search.fit(X, label_encoded_y)
# summarize results
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))
# plot results
scores = numpy.array(means).reshape(len(max_depth), len(n_estimators))
for i, value in enumerate(max_depth):
pyplot.plot(n_estimators, scores[i], label='depth: ' + str(value))
pyplot.legend()
pyplot.xlabel('n_estimators')
pyplot.ylabel('Log Loss')
pyplot.savefig('n_estimators_vs_max_depth.png')
运行代码会生成每个参数对的 logloss 列表。
Best: -0.001141 using {'n_estimators': 200, 'max_depth': 4}
-0.012127 (0.001130) with: {'n_estimators': 50, 'max_depth': 2}
-0.001351 (0.001825) with: {'n_estimators': 100, 'max_depth': 2}
-0.001278 (0.001812) with: {'n_estimators': 150, 'max_depth': 2}
-0.001266 (0.001796) with: {'n_estimators': 200, 'max_depth': 2}
-0.010545 (0.001083) with: {'n_estimators': 50, 'max_depth': 4}
-0.001226 (0.001721) with: {'n_estimators': 100, 'max_depth': 4}
-0.001150 (0.001704) with: {'n_estimators': 150, 'max_depth': 4}
-0.001141 (0.001693) with: {'n_estimators': 200, 'max_depth': 4}
-0.010341 (0.001059) with: {'n_estimators': 50, 'max_depth': 6}
-0.001237 (0.001701) with: {'n_estimators': 100, 'max_depth': 6}
-0.001163 (0.001688) with: {'n_estimators': 150, 'max_depth': 6}
-0.001154 (0.001679) with: {'n_estimators': 200, 'max_depth': 6}
-0.010342 (0.001059) with: {'n_estimators': 50, 'max_depth': 8}
-0.001237 (0.001701) with: {'n_estimators': 100, 'max_depth': 8}
-0.001161 (0.001688) with: {'n_estimators': 150, 'max_depth': 8}
-0.001153 (0.001679) with: {'n_estimators': 200, 'max_depth': 8}
我们可以看到, n_estimators = 200 和 max_depth = 4 实现了最佳结果,类似于前两轮独立参数调整中发现的最佳值( n_estimators = 250 , max_depth = 5 )。
我们可以绘制给定 n_estimators 的每个 max_depth 值系列之间的关系。
调整 XGBoost 中的树数和最大树深度
线条重叠使得很难看到这种关系,但通常我们可以看到我们期望的互动。随着树木深度的增加,需要更少的树木。
此外,我们期望由更深的单个树提供的增加的复杂性导致训练数据的更大过拟合,这将通过具有更多树而加剧,进而导致更低的交叉验证分数。我们在这里看不到这一点,因为我们的树木不是那么深,我们也没有太多。探索这种期望是一种你可以自己探索的练习。
摘要
在这篇文章中,您发现了在 Python 中使用 XGBoost 进行梯度提升时如何调整决策树的数量和深度。
具体来说,你学到了:
- 如何调整 XGBoost 模型中的决策树数量。
- 如何在 XGBoost 模型中调整决策树的深度。
- 如何在 XGBoost 模型中共同调整树的数量和树深度
您对梯度提升模型或此帖中决策树的数量或大小有任何疑问吗?在评论中提出您的问题,我会尽力回答。
通过学习曲线调整 XGBoost 表现
XGBoost 是梯度增强集成算法的一个强大而有效的实现。
配置 XGBoost 模型的超参数可能具有挑战性,这通常会导致使用既耗时又计算成本高的大型网格搜索实验。
配置 XGBoost 模型的另一种方法是在训练期间评估算法每次迭代的模型表现,并将结果绘制为学习曲线。这些学习曲线提供了一种诊断工具,可以对其进行解释,并建议对模型超参数进行特定的更改,从而提高预测表现。
在本教程中,您将发现如何在 Python 中绘制和解释 XGBoost 模型的学习曲线。
完成本教程后,您将知道:
- 学习曲线为理解像 XGBoost 这样的监督学习模型的训练动态提供了一个有用的诊断工具。
- 如何配置 XGBoost 来评估每次迭代的数据集,并将结果绘制为学习曲线。
- 如何解读和使用学习曲线图提高 XGBoost 模型表现?
我们开始吧。
通过学习曲线调整 XGBoost 表现 图片由伯纳德·斯拉格提供。新西兰,保留部分权利。
教程概述
本教程分为四个部分;它们是:
- 极限梯度助推
- 学习曲线
- 绘制扩展学习曲线
- 使用学习曲线调整 XGBoost 模型
极限梯度助推
梯度提升是指一类可用于分类或回归预测建模问题的集成机器学习算法。
集成是由决策树模型构建的。树被一次一个地添加到集合中,并且适合于校正由先前模型产生的预测误差。这是一种称为 boosting 的集成机器学习模型。
使用任意可微损失函数和梯度下降优化算法拟合模型。这给这项技术起了个名字,叫做“梯度增强”,因为随着模型的拟合,损失梯度被最小化,很像一个神经网络。
有关渐变增强的更多信息,请参见教程:
极限梯度增强,简称 XGBoost,是梯度增强算法的一个高效开源实现。因此,XGBoost 是一个算法、一个开源项目和一个 Python 库。
它最初是由陈天棋开发的,并由陈和在他们 2016 年的论文《XGBoost:一个可扩展的树木提升系统》中进行了描述
它被设计为既有计算效率(例如,执行速度快),又非常有效,可能比其他开源实现更有效。
使用 XGBoost 的两个主要原因是执行速度和模型表现。
XGBoost 在分类和回归预测建模问题上主导结构化或表格数据集。证据是,它是 Kaggle 竞争数据科学平台上竞争赢家的 go-to 算法。
在 2015 年 Kaggle 博客上发布的 29 个挑战获胜解决方案 3 中,有 17 个解决方案使用了 XGBoost。[……]该系统的成功也在 KDDCup 2015 中得到了见证,在该赛事中,XGBoost 被前 10 名中的每一个获胜团队所使用。
——xboost:一个可扩展的树提升系统,2016。
有关 xboost 以及如何安装和使用 XGBoost Python API 的更多信息,请参见教程:
既然我们已经熟悉了什么是 XGBoost 以及它为什么重要,那么让我们来仔细看看学习曲线。
学习曲线
一般来说,学习曲线是在 x 轴上显示时间或经验,在 y 轴上显示学习或进步的曲线。
学习曲线在机器学习中被广泛用于随时间递增学习(优化其内部参数)的算法,例如深度学习神经网络。
用于评估学习的指标可能是最大化,这意味着更好的分数(更大的数字)表明更多的学习。分类准确性就是一个例子。
更常见的是使用最小化的分数,例如损失或错误,由此更好的分数(更小的数字)表示更多的学习,值 0.0 表示训练数据集被完美地学习并且没有出错。
在机器学习模型的训练期间,可以评估在训练算法的每个步骤中模型的当前状态。可以在训练数据集上对其进行评估,以给出模型学习有多好的想法也可以在不属于训练数据集的保留验证数据集上对其进行评估。对验证数据集的评估给出了该模型概括的“T2”程度的概念
*在训练和验证数据集的训练过程中,为机器学习模型创建双重学习曲线是很常见的。
学习曲线的形状和动态可以用于诊断机器学习模型的行为,并且反过来可能建议可以进行的配置改变的类型,以改进学习和/或表现。
在学习曲线中,你可能会观察到三种常见的动态;它们是:
- 在它下面。
- 吃多了。
- 很合身。
最常见的是,学习曲线用于诊断模型的过拟合行为,这可以通过调整模型的超参数来解决。
过拟合是指模型对训练数据集的学习太好,包括训练数据集中的统计噪声或随机波动。
过拟合的问题是,模型对训练数据越专门化,它对新数据的泛化能力就越差,导致泛化误差增加。泛化误差的增加可以通过模型在验证数据集上的表现来衡量。
有关学习曲线的更多信息,请参见教程:
现在我们已经熟悉了学习曲线,让我们看看如何为 XGBoost 模型绘制学习曲线。
绘制扩展学习曲线
在本节中,我们将绘制一个 XGBoost 模型的学习曲线。
首先,我们需要一个数据集作为拟合和评估模型的基础。
在本教程中,我们将使用合成二进制(两类)分类数据集。
make _ classification()sci kit-learn 功能可用于创建合成分类数据集。在这种情况下,我们将使用 50 个输入特征(列)并生成 10,000 个样本(行)。伪随机数生成器的种子是固定的,以确保每次生成样本时使用相同的基数“问题”。
下面的示例生成了合成分类数据集,并总结了生成数据的形状。
# test classification dataset
from sklearn.datasets import make_classification
# define dataset
X, y = make_classification(n_samples=10000, n_features=50, n_informative=50, n_redundant=0, random_state=1)
# summarize the dataset
print(X.shape, y.shape)
运行该示例会生成数据并报告输入和输出组件的大小,从而确认预期的形状。
(10000, 50) (10000,)
接下来,我们可以在这个数据集上拟合一个 XGBoost 模型,并绘制学习曲线。
首先,我们必须将数据集分成一部分用于训练模型(train),另一部分不用于训练模型,而是保留下来用于评估训练算法(测试集或验证集)每一步的模型。
...
# split data into train and test sets
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.50, random_state=1)
然后我们可以定义一个带有默认超参数的 XGBoost 分类模型。
...
# define the model
model = XGBClassifier()
接下来,可以在数据集上拟合模型。
在这种情况下,我们必须向训练算法指定,我们希望它在每次迭代中评估模型和测试集的表现(例如,在每个新树被添加到集合中之后)。
为此,我们必须指定要评估的数据集和要评估的指标。
数据集必须指定为元组列表,其中每个元组包含数据集的输入和输出列,列表中的每个元素都是要评估的不同数据集,例如训练集和测试集。
...
# define the datasets to evaluate each iteration
evalset = [(X_train, y_train), (X_test,y_test)]
我们可能需要评估许多指标,尽管假设这是一个分类任务,我们将评估模型的对数损失(交叉熵),这是一个最小化分数(值越低越好)。
这可以通过在调用 fit() 时指定“ eval_metric ”参数并为其提供我们将评估的度量名称“ logloss ”来实现。我们还可以通过“ eval_set ”参数指定要评估的数据集。 fit() 函数按照常规将训练数据集作为前两个参数。
...
# fit the model
model.fit(X_train, y_train, eval_metric='logloss', eval_set=evalset)
一旦模型被拟合,我们可以评估它的表现作为测试数据集上的分类精确率。
...
# evaluate performance
yhat = model.predict(X_test)
score = accuracy_score(y_test, yhat)
print('Accuracy: %.3f' % score)
然后,我们可以通过调用 evals_result() 函数来检索为每个数据集计算的指标。
...
# retrieve performance metrics
results = model.evals_result()
这将返回一个字典,该字典首先按数据集(' T0 ' validation _ 0'和' validation_1 '组织,然后按度量(' T4】 logloss ')组织。
我们可以为每个数据集创建度量的线图。
...
# plot learning curves
pyplot.plot(results['validation_0']['logloss'], label='train')
pyplot.plot(results['validation_1']['logloss'], label='test')
# show the legend
pyplot.legend()
# show the plot
pyplot.show()
就这样。
将所有这些结合在一起,下面列出了在综合分类任务上拟合 XGBoost 模型并绘制学习曲线的完整示例。
# plot learning curve of an xgboost model
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
from xgboost import XGBClassifier
from matplotlib import pyplot
# define dataset
X, y = make_classification(n_samples=10000, n_features=50, n_informative=50, n_redundant=0, random_state=1)
# split data into train and test sets
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.50, random_state=1)
# define the model
model = XGBClassifier()
# define the datasets to evaluate each iteration
evalset = [(X_train, y_train), (X_test,y_test)]
# fit the model
model.fit(X_train, y_train, eval_metric='logloss', eval_set=evalset)
# evaluate performance
yhat = model.predict(X_test)
score = accuracy_score(y_test, yhat)
print('Accuracy: %.3f' % score)
# retrieve performance metrics
results = model.evals_result()
# plot learning curves
pyplot.plot(results['validation_0']['logloss'], label='train')
pyplot.plot(results['validation_1']['logloss'], label='test')
# show the legend
pyplot.legend()
# show the plot
pyplot.show()
运行该示例符合 XGBoost 模型,检索计算出的指标,并绘制学习曲线。
注:考虑到算法或评估程序的随机性,或数值精确率的差异,您的结果可能会有所不同。考虑运行该示例几次,并比较平均结果。
首先,报告模型表现,表明该模型在等待测试集上实现了约 94.5%的分类精确率。
Accuracy: 0.945
该图显示了训练和测试数据集的学习曲线,其中 x 轴是算法的迭代次数(或添加到集合中的树的数量),y 轴是模型的对数损失。每行显示给定数据集每次迭代的对数损失。
从学习曲线中,我们可以看到模型在训练数据集上的表现(蓝色线)比模型在测试数据集上的表现(橙色线)更好或损失更低,这是我们通常可能预期的。
综合分类数据集上 XGBoost 模型的学习曲线
现在我们知道了如何绘制 XGBoost 模型的学习曲线,让我们看看如何使用这些曲线来提高模型表现。
使用学习曲线调整 XGBoost 模型
我们可以使用学习曲线作为诊断工具。
这些曲线可以被解释并用作对模型配置提出可能导致更好表现的具体改变的基础。
上一节中的模型和结果可以用作基线和起点。
看一下图,我们可以看到两条曲线都是向下倾斜的,这表明更多的迭代(增加更多的树)可能会导致损失的进一步减少。
让我们试试看。
我们可以通过默认为 100 的“n _ estimates”超参数来增加算法的迭代次数。让我们把它增加到 500。
...
# define the model
model = XGBClassifier(n_estimators=500)
下面列出了完整的示例。
# plot learning curve of an xgboost model
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
from xgboost import XGBClassifier
from matplotlib import pyplot
# define dataset
X, y = make_classification(n_samples=10000, n_features=50, n_informative=50, n_redundant=0, random_state=1)
# split data into train and test sets
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.50, random_state=1)
# define the model
model = XGBClassifier(n_estimators=500)
# define the datasets to evaluate each iteration
evalset = [(X_train, y_train), (X_test,y_test)]
# fit the model
model.fit(X_train, y_train, eval_metric='logloss', eval_set=evalset)
# evaluate performance
yhat = model.predict(X_test)
score = accuracy_score(y_test, yhat)
print('Accuracy: %.3f' % score)
# retrieve performance metrics
results = model.evals_result()
# plot learning curves
pyplot.plot(results['validation_0']['logloss'], label='train')
pyplot.plot(results['validation_1']['logloss'], label='test')
# show the legend
pyplot.legend()
# show the plot
pyplot.show()
运行示例拟合和评估模型,并绘制模型表现的学习曲线。
注:考虑到算法或评估程序的随机性,或数值精确率的差异,您的结果可能会有所不同。考虑运行该示例几次,并比较平均结果。
我们可以看到,更多的迭代导致精确率从大约 94.5%提升到大约 95.8%。
Accuracy: 0.958
我们可以从学习曲线中看到,实际上算法的额外迭代导致曲线继续下降,然后在大约 150 次迭代后变平,在那里它们保持相当平坦。
具有更多迭代的 XGBoost 模型的学习曲线
长而平坦的曲线可能表明算法学习太快,我们可能会受益于减慢它。
这可以使用学习速率来实现,学习速率限制了添加到集合中的每棵树的贡献。这可以通过“ eta ”超参数控制,默认值为 0.3。我们可以尝试较小的值,例如 0.05。
...
# define the model
model = XGBClassifier(n_estimators=500, eta=0.05)
下面列出了完整的示例。
# plot learning curve of an xgboost model
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
from xgboost import XGBClassifier
from matplotlib import pyplot
# define dataset
X, y = make_classification(n_samples=10000, n_features=50, n_informative=50, n_redundant=0, random_state=1)
# split data into train and test sets
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.50, random_state=1)
# define the model
model = XGBClassifier(n_estimators=500, eta=0.05)
# define the datasets to evaluate each iteration
evalset = [(X_train, y_train), (X_test,y_test)]
# fit the model
model.fit(X_train, y_train, eval_metric='logloss', eval_set=evalset)
# evaluate performance
yhat = model.predict(X_test)
score = accuracy_score(y_test, yhat)
print('Accuracy: %.3f' % score)
# retrieve performance metrics
results = model.evals_result()
# plot learning curves
pyplot.plot(results['validation_0']['logloss'], label='train')
pyplot.plot(results['validation_1']['logloss'], label='test')
# show the legend
pyplot.legend()
# show the plot
pyplot.show()
运行示例拟合和评估模型,并绘制模型表现的学习曲线。
注:考虑到算法或评估程序的随机性,或数值精确率的差异,您的结果可能会有所不同。考虑运行该示例几次,并比较平均结果。
我们可以看到,学习率越小,准确率越差,从 95.8%左右下降到 95.1%左右。
Accuracy: 0.951
我们可以从学习曲线中看到,学习确实已经慢了下来。这些曲线表明,我们可以继续增加更多的迭代,并可能获得更好的表现,因为曲线将有更多的机会继续减少。
学习率较小的 XGBoost 模型的学习曲线
让我们尝试将迭代次数从 500 次增加到 2000 次。
...
# define the model
model = XGBClassifier(n_estimators=2000, eta=0.05)
下面列出了完整的示例。
# plot learning curve of an xgboost model
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
from xgboost import XGBClassifier
from matplotlib import pyplot
# define dataset
X, y = make_classification(n_samples=10000, n_features=50, n_informative=50, n_redundant=0, random_state=1)
# split data into train and test sets
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.50, random_state=1)
# define the model
model = XGBClassifier(n_estimators=2000, eta=0.05)
# define the datasets to evaluate each iteration
evalset = [(X_train, y_train), (X_test,y_test)]
# fit the model
model.fit(X_train, y_train, eval_metric='logloss', eval_set=evalset)
# evaluate performance
yhat = model.predict(X_test)
score = accuracy_score(y_test, yhat)
print('Accuracy: %.3f' % score)
# retrieve performance metrics
results = model.evals_result()
# plot learning curves
pyplot.plot(results['validation_0']['logloss'], label='train')
pyplot.plot(results['validation_1']['logloss'], label='test')
# show the legend
pyplot.legend()
# show the plot
pyplot.show()
运行示例拟合和评估模型,并绘制模型表现的学习曲线。
注:考虑到算法或评估程序的随机性,或数值精确率的差异,您的结果可能会有所不同。考虑运行该示例几次,并比较平均结果。
我们可以看到,更多的迭代给了算法更大的改进空间,达到了 96.1%的准确率,是目前为止最好的。
Accuracy: 0.961
学习曲线再次显示了算法的稳定收敛,具有陡峭的下降和长的平坦化。
具有较小学习率和多次迭代的 XGBoost 模型的学习曲线
我们可以重复降低学习率和增加迭代次数的过程,看看是否有可能进一步改进。
减缓学习速度的另一种方法是以减少样本数量和用于构建集成中每棵树的特征(行和列)的形式添加正则化。
在这种情况下,我们将尝试分别通过“子样本”和“ colsample_bytree ”超参数将样本和特征的数量减半。
...
# define the model
model = XGBClassifier(n_estimators=2000, eta=0.05, subsample=0.5, colsample_bytree=0.5)
下面列出了完整的示例。
# plot learning curve of an xgboost model
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
from xgboost import XGBClassifier
from matplotlib import pyplot
# define dataset
X, y = make_classification(n_samples=10000, n_features=50, n_informative=50, n_redundant=0, random_state=1)
# split data into train and test sets
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.50, random_state=1)
# define the model
model = XGBClassifier(n_estimators=2000, eta=0.05, subsample=0.5, colsample_bytree=0.5)
# define the datasets to evaluate each iteration
evalset = [(X_train, y_train), (X_test,y_test)]
# fit the model
model.fit(X_train, y_train, eval_metric='logloss', eval_set=evalset)
# evaluate performance
yhat = model.predict(X_test)
score = accuracy_score(y_test, yhat)
print('Accuracy: %.3f' % score)
# retrieve performance metrics
results = model.evals_result()
# plot learning curves
pyplot.plot(results['validation_0']['logloss'], label='train')
pyplot.plot(results['validation_1']['logloss'], label='test')
# show the legend
pyplot.legend()
# show the plot
pyplot.show()
运行示例拟合和评估模型,并绘制模型表现的学习曲线。
注:考虑到算法或评估程序的随机性,或数值精确率的差异,您的结果可能会有所不同。考虑运行该示例几次,并比较平均结果。
我们可以看到,正则化的加入导致了进一步的改进,碰撞精确率从大约 96.1%提高到大约 96.6%。
Accuracy: 0.966
这些曲线表明,正则化减缓了学习,也许增加迭代次数可能会带来进一步的改进。
正则化 XGBoost 模型的学习曲线
这个过程可以继续,我有兴趣看看你能想出什么。
进一步阅读
如果您想更深入地了解这个主题,本节将提供更多资源。
教程
报纸
- XGBoost:一个可扩展的树木助推系统,2016。
蜜蜂
摘要
在本教程中,您发现了如何在 Python 中绘制和解释 XGBoost 模型的学习曲线。
具体来说,您了解到:
- 学习曲线为理解像 XGBoost 这样的监督学习模型的训练动态提供了一个有用的诊断工具。
- 如何配置 XGBoost 来评估每次迭代的数据集,并将结果绘制为学习曲线。
- 如何解读和使用学习曲线图提高 XGBoost 模型表现?
你有什么问题吗? 在下面的评论中提问,我会尽力回答。*
如何使用 Python 和 XGBoost 可视化梯度提升决策树
原文:
machinelearningmastery.com/visualize-gradient-boosting-decision-trees-xgboost-python/
绘制单个决策树可以提供对给定数据集的梯度提升过程的深入了解。
在本教程中,您将了解如何使用 Python 中的 XGBoost 从训练好的梯度提升模型中绘制单个决策树。
让我们开始吧。
- 更新 March / 2018 :添加了备用链接以下载数据集,因为原始图像已被删除。
如何用 Python 中的 XGBoost 可视化梯度提升决策树 Kaarina Dillabough 的照片,保留一些权利。
绘制单个 XGBoost 决策树
XGBoost Python API 提供了在经过训练的 XGBoost 模型中绘制决策树的功能。
**plot_tree()**函数提供了此功能,该函数将训练模型作为第一个参数,例如:
plot_tree(model)
这将绘制模型中的第一个树(索引 0 处的树)。可以使用 matplotlib 和 **pyplot.show()**将该图保存到文件或显示在屏幕上。
此绘图功能要求您安装 graphviz 库。
我们可以在 Pima 印第安人糖尿病数据集上创建一个 XGBoost 模型,并绘制模型中的第一棵树(更新:从这里下载)。完整的代码清单如下:
# plot decision tree
from numpy import loadtxt
from xgboost import XGBClassifier
from xgboost import plot_tree
import matplotlib.pyplot as plt
# load data
dataset = loadtxt('pima-indians-diabetes.csv', delimiter=",")
# split data into X and y
X = dataset[:,0:8]
y = dataset[:,8]
# fit model no training data
model = XGBClassifier()
model.fit(X, y)
# plot single tree
plot_tree(model)
plt.show()
运行代码会在模型中创建第一个决策树(索引 0)的图,显示每个拆分的特征和特征值以及输出叶节点。
单一决策树的 XGBoost 图
您可以看到变量自动命名为 f1 和 f5,与输入数组中的特征索引相对应。
您可以看到每个节点内的拆分决策以及左右分割的不同颜色(蓝色和红色)。
**plot_tree()**函数需要一些参数。您可以通过指定 num_trees 参数的索引来绘制特定图形。例如,您可以按顺序绘制序列中的第 5 个提升树:
plot_tree(model, num_trees=4)
您还可以通过将 rankdir 参数更改为“LR”(从左到右)而不是默认的从上到下(UT)来更改图表的布局从左到右(更容易阅读) )。例如:
plot_tree(model, num_trees=0, rankdir='LR')
以从左到右的布局绘制树的结果如下所示。
从左到右的单一决策树的 XGBoost 图
摘要
在这篇文章中,您学习了如何使用 Python 中训练有素的 XGBoost 梯度提升模型绘制单个决策树。
你有关于在 XGBoost 中绘制决策树或关于这篇文章的任何问题吗?在评论中提出您的问题,我会尽力回答。