亚马逊AWS官方博客

使用开源 AutoML 库 AutoGluon 进行机器学习

如果您从事数据科学工作,您可能会认为机器学习最难的一点是不知道您何时能够完成。首先您有一个问题,然后构建数据集,接着构想如何解决问题,但在已然浪费了时间之后,您却不知道您的方案是否可行。机器学习流程之所以如此艰难,部分原因是存在许多经验丰富的从业者才知道的最佳实践。如果您刚刚开始使用数据科学,您可能会花费大量时间践行一种您认为正确的方法,但是在这之前本来会有一名专家从业者告诉您这个方法是行不通的。

如果您可以将这些最佳实践编纂成一个简单易用的软件包,供所有开发人员使用,会怎么样? 一个可以自动准备数据集,尝试不同的机器学习方法并将其结果组合在一起以提供高质量模型的库 – 所有这些功能由几行代码实现?

这是自动化机器学习 (AutoML) 背后的理念,也是 AutoGluon AutoML 库的设计理念,该库由 Amazon Web Services (AWS)re:invent 2019 上开源。使用 AutoGluon,您可以训练最先进的机器学习模型,以进行图像分类、对象检测、文本分类和表格式数据预测,而几乎无需具备机器学习方面的经验。您可以随时随地运行 AutoGluon – 从笔记本电脑或工作站到功能强大的 Amazon Elastic Compute Cloud (Amazon EC2) – 实例,以利用多个内核并更快地获得结果。

AWS 的 AutoGluon 团队发表了一篇论文,详细介绍了 AutoGluon-Tabular 的内部工作原理,这是一种开源 AutoGluon 功能,允许您对来自电子表格和数据库表格等来源的表格数据集的机器学习模型进行训练。

AutoGluon-Tabular 论文的屏幕截图 https://arxiv.org/abs/2003.06505

AutoGluon-Tabular 论文的位置如下:https://arxiv.org/abs/2003.06505

在本文的上半部分,我

将介绍 AutoGluon-Tabular,并总结该论文中介绍的关键创新以及使用 AutoGluon-Tabular 在幕后发生的神奇操作。在本文的下半部分,我将介绍一个端到端代码示例,说明如何使用 AutoGluon-Tabular 凭借几行代码在数据科学竞赛中获得排名前 1% 的分数,且无需机器学习经验。

 

如果您想快速入门并开始学习本示例,请转到“在下一次数据科学竞赛中抢占先机”部分。演示用的 Jupyter 笔记本可在我的 GitHub 上获得。

AutoML 的 AutoGluon-Tabular 解决方案

虽然图像和视频领域的机器学习应用程序引起了极大的关注,但人们几十年来一直在将统计技术应用于表格数据(思考电子表格或数据库中的行和列),以构建预测模型或收集汇总统计数据。大量数据科学问题属于这一类别,例如,基于库存和需求数据的销售预测、交易数据的欺诈检测以及根据用户偏好生成产品建议。

本博文将重点介绍 AutoGluon 处理表格数据的功能的子集,我们将其称为 AutoGluon-Tabular

AutoGluon-Tabular 让您可以通过用户友好型 API 访问专家数据科学家使用的所有最佳实践,并且其设计采用以下主要原则:

  1. 简易性:用户应能够使用几行代码即可训练分类和回归模型,并部署它们。
  2. 稳定性:用户应能够提供原始数据,而无需任何特征工程和数据操作。
  3. 可预测的时间安排:用户应能够指定时间预算并在该时间限制下获得最佳模型。
  4. 容错能力:用户应能够在中断时恢复训练,并能够检查所有中间步骤。

如果您已经是一名数据科学专家从业者,并且想知道 AutoGluon-Tabular 对您是否有用,答案是肯定的。即使对于专家来说,AutoGluon-Tabular 也可以通过自动执行耗时的手动步骤来节省时间 – 处理丢失的数据、手动功能转换、数据拆分、模型选择、算法选择、超参数选择和调整、集成多个模型,以及在数据更改时重复此过程。

AutoGluon-Tabular 还包括用于多层堆叠集成的新技术,可显著提高模型的准确性。由于 AutoGluon 完全开源,具有透明度和可扩展性,因此您可以全面了解它在流程的每个阶段所做的工作,甚至可以引入自己的算法并将它们与 AutoGluon 一起使用。

AutoGluon API

AutoGluon-Tabular 用户只需知道如何使用三个 Python 函数:Dataset()fit()predict()。不要让 API 的简洁性欺骗了您 – 在幕后有很多操作发生,AutoGluon-Tabular 代表您努力工作,为您提供高质量的模型。在下一节中,我们将详细介绍这些函数,并讨论它们的不同之处。

第 0 步:启动您的 Amazon EC2 实例;安装并导入 AutoGluon。

AutoGluon 可以利用多核 CPU 来加快训练速度。我建议从 C5 或 M5 系列启动 Amazon EC2 实例。选择较高的 vCPU 数量以获得更快的性能。有关如何启动实例和访问实例的简要指南,请阅读 Amazon EC2 入门文档。按照 AutoGluon 网页上的说明安装 AutoGluon。在大多数情况下,您应该只能运行 pip install

要运行 AutoGluon-Tabular,首先告诉 AutoGluon 您感兴趣的任务是为表格数据构建预测器。将 TabularPrediction 替换为 ImageClassification 以解决图像分类问题,替换为 ObjectDetection 以解决对象检测问题,替换为 TextClassification 以解决文本分类问题。API 的其余部分保持不变。这使您可以轻松地在问题之间切换,而无需重新学习 API。

从 AutoGluon 导入 TabularPrediction 作为任务

第 1 步:加载数据集。

如果您是 pandas 用户,则可以轻松使用 Dataset 函数,这可为您提供类似 pandas 的体验,这样您就可以执行一些操作,如删除变量或加入多个数据集。由于 AutoGluon-Tabular 自动为您管理数据预处理,因此您不需要进行任何数据操作。

data = task.Dataset(DATASET_PATH) 

第 2 步:模型拟合。

fit() 函数执行所有繁重的工作,我们将在下一节中介绍这一点。此函数有两大任务:它研究数据集,然后为训练做准备,它适合多个模型,并将它们组合在一起以生成高精度模型。

predictor = task.fit(data_train, label=LABEL_COLUMN_NAME)

第 3 步:做出预测。

predict 函数通过新数据生成预测。预测可能导致预测类别和概率的分类问题,或连续值的回归问题。当您运行 fit() 函数时,将生成多个模型并保存到磁盘中。如果您在以后重新访问它们,只需使用 load 命令加载预测器并使用它运行预测即可。

prediction = predictor.predict(new_data)

fit() 函数的魔力

将数据集传递给 task.fit() 函数时,它会执行两项操作:数据预处理和模型拟合。现在,我们来了解一下幕后的工作情况。

数据预处理

AutoGluon-Tabular 首先检查标签列,并确定您是否存在分类问题(预测类别)或回归问题(预测连续值)。然后,它将启动数据预处理步骤,将数据转换为一种在 fit() 阶段将被许多不同的机器学习算法占用的表格。

在预处理步骤中,AutoGluon-Tabular 首先将每个特征分类为数字、类别、文本或日期/时间。不能分类的列,如包含非数字信息且不重复(被视为类别)的列,将被弃用,例如用户 ID。

文本列转换为 n-gram(连续的 n 项或词序列)特征的数值向量;日期和时间特征转换为合适的数值。为了处理缺少的离散变量,AutoGluon-Tabular 会创建一个额外的未知类别,而不是输入(用平均值等代理替换)。在真实的数据集中,由于各种原因(例如数据损坏、传感器故障和人为错误),数值可能会缺失,但这并不意味着没有任何有趣的东西。将其归类为未知允许 AutoGluon-Tabular 在用新数据生成预测时处理以前不可见的类别。在模型拟合阶段,AutoGluon-Tabular 还执行特定于模型的额外数据预处理步骤。

模型拟合

调用 fit() 函数时,AutoGluon-Tabular 将基于预处理的数据训练一系列的机器学习模型。然后使用集成和堆叠将多个模型组合起来。

AutoGluon-Tabular 以专门选择的顺序训练各个模型。首先,训练性能可靠的模型(如随机森林),然后逐步训练需要计算量更大但可靠性更低的模型,如 k 最近邻。这种方法的好处是可以对 fit() 函数施加时间限制,并将返回在时间限制下可以训练的最佳模型。利用 AutoGluon-Tabular,可以灵活地决定是无约束地实现最佳精度,还是在特定的成本或时间预算下实现最佳精度。

AutoGluon-Tabular 目前支持以下算法,如果没有时间限制,可以对所有这些算法进行训练:

  1. 随机森林
  2. 超随机树
  3. k 最近邻
  4. LightGBM 提升树
  5. CatBoost 提升树
  6. AutoGluon-Tabular 深度神经网络

AutoGluon-Tabular 深度神经网络架构的新颖性

在数据科学界有一种常见误解,即深度学习方法不能很好地处理表格数据。之所以产生这种想法是因为:在神经网络中引入了卷积,以便通过权值共享实现平移不变性。此方法对于一维信号、二维或者三维图像或视频数据集非常有效,因为这些数据集中的每个信号采样或像素值本身的预测能力很低。在许多表格数据集应用程序中,每个特征都具有独特的重要性,并且比图像中的单个像素具有更高的预测能力。在这些情况下,前馈或卷积神经网络架构的性能往往低于基于决策树的同类架构。

为了解决这些问题,AutoGluon-Tabular 采用了如下图所示的新型神经网络架构。实证研究表明,精心设计的神经网络可以显著提升准确度,特别是创建与其他模型类型的集成时,我们将在下一节讨论这一点。

AutoGluon-Tabular 采用新型神经网络架构

与常用的纯前馈网络架构不同,AutoGluon-Tabular 为每个分类特征都引入了一个嵌入层,其中嵌入维数根据特征中唯一类别的数量按比例选择。嵌入层的优点是,在被后续前馈层使用之前,为每个分类特征引入了一个可学习组件。然后,将分类特征的嵌入与数值特征连接成一个大矢量,该矢量既馈入一个三层前馈网络,又通过线性跳接(类似于剩余网络族)直接连接到输出预测。

集成和多层堆叠

将多个模型组合起来,创建一个“集成”,从而相比每个参与者都具有更高的预测准确度,这种想法并不新鲜。集成技术最早的实现可以追溯到 20 世纪 90 年代早期,当时出现了提升法(和 AdaBoost 算法)和自助聚合法 (Bootstrap Aggregation)。这些技术创建了决策树的集成,这些决策树是弱分类器(不比随机猜测强多少)且不稳定(对数据集的变化很敏感)。但是,当许多决策树组合在一起时,就生成了具有高预测能力的模型,不受过拟合的影响。这些早期成果是许多流行机器学习包的基础,如 LightGBM、CatBoost 和 scikit-learn 的 RandomForest,这些都在 AutoGluon 中所采用。

如果您想知道是否可以组合 RandomForest、CatBoost、k 最近邻等的输出来进一步提高模型准确度,答案是肯定的。有经验的机器学习从业者已经这样做了很多年,能够熟练设计巧妙的方法来组合多个模型。请查看奥托集团产品分类挑战赛 Kaggle 竞赛的获奖作品。第一名的解决方案包括 33 个模型,再使用这些模型的输出训练另外 3 个模型(堆叠),然后进行加权平均。

第一名的解决方案包括 33 个模型,再使用这些模型的输出训练另外 3 个模型(堆叠),然后进行加权平均

利用 AutoGluon-Tabular,您不必具备堆叠和集成技术。AutoGluon-Tabular 会自动帮您执行。AutoGluon-Tabular 引入了一种新型的多层堆叠集成,如上图所示。下面介绍了其工作原理:

  • 基础层:分别训练模型拟合部分中描述的多个基础模型。
  • Concat 层:将第一层的输出与输入特征连接在一起。
  • Stacker 层:基于 concat 层输出训练多个 stacker 模型。AutoGluon-Tabular 带来的新颖性在于,Stacker 重用与基础层完全相同的模型,包括在 stacker 模型中使用其超参数。由于输入特征与基础层的输出连接在一起,因此 stacker 模型也有机会查看输入数据集。
  • 加权层:实施选择的集成方法,即将 stacker 模型引入到一个新的集成中,从而最大程度地提高验证准确度。

为了确保每个分类器都能看到整个数据集,AutoGluon-Tabular 执行 k-折交叉验证。为了进一步提高预测准确度和减少过拟合,AutoGluon-Tabular 将对 n 个不同的随机输入数据分区重复执行 n 次 k-折交叉验证。数字 n 的选择方法是,在调用 fit() 函数时,估计在指定的时间限制内可以完成多少次循环。

AutoGluon-Tabular 和容错

在生活和数据科学中,事情可能不会按计划进行。当使用 AutoGluon-Tabular 时,您可能会不小心按下 Ctrl+C,或者遇到电源浪涌,导致您的计算机断电,或者关闭了所有正在运行的 Amazon EC2 实例,而没有意识到正在运行训练作业。出现错误以及事情没有按计划进行时,您不希望被数据丢失和停滞不前所困扰。AutoGluon-Tabular 为这类情况提供了一些内置保护。

当您调用 fit() 函数时,AutoGluon-Tabular 首先估计所需的训练时间,如果超出训练某层的剩余时间,则跳过该层,继续训练下一层。为了确保没有停滞不前,训练每个新模型后,会立即将其保存到磁盘。如果确实发生了故障,AutoGluon-Tabular 只要在发生故障之前(或在达到时间限制之前)至少对一个模型训练了一折(共 k 折),仍然可以进行预测。对于在训练过程中支持中间检查点的算法,如基于树的算法和神经网络,AutoGluon-Tabular 仍然可以使用这些检查点生成预测。AutoGluon-Tabular 还可以预测模型在训练过程的哪个阶段会失败,然后跳到下一阶段。

代码示例:在下一次数据科学竞赛中抢占先机

现在您应该对 AutoGluon-Tabular 的工作方式有了一定的了解,但是数据科学是一门实践性很强的学科,因此最好的学习方法是进行实践。

在本节中,我们将介绍一个使用 AutoGluon-Tabular 基于数据集训练模型的端到端示例,该数据集曾在 Kaggle 上的奥托集团产品分类挑战赛上使用。执行下面的示例后,您应该能够取得不错的成绩,在排行榜上可位列前 1%。比赛已经结束,但是您仍然可以提交模型,在公开排行榜和非公开排行榜上占一席之地。

参赛数据集由代表产品的 20 万行和代表产品特征的 93 列组成。产品分为训练数据集中标签列指定的 10 类。比赛的目标是根据产品的 93 个特征预测产品类别。可以在比赛页面上阅读有关比赛的更多信息。

先决条件

如果您想在一边阅读时一边运行示例,可以在 GitHub 上获取演示用的 Jupyter 笔记本。

要下载数据集并将您的分数提交给 Kaggle,请确保进入比赛页面,单击“参加比赛”并同意其条款和条件,然后再继续。

我在 AWS 上的一个 c5.24xlarge EC2 实例上运行了这些示例,整个训练耗时 2 小时 30 分钟。c5.24xlarge 是经过计算优化的实例,并提供 96 个 CPU 内核。我选择了具有大量内核的实例类型,因为许多 AutoGluon-Tabular 算法都是多线程的,可以利用所有内核。下面的屏幕截图显示了在训练(神经网络训练)阶段在 EC2 实例上使用 htop 命令时的 CPU 使用情况。绿色水平条表示 CPU 内核忙碌。黑色条表示每个内核的利用率不到 100%。平均负载分数 84 表示截取屏幕快照时所有 96 个 CPU 的平均负载。

如果选择内核数量较少的 CPU 实例,则训练时间将更长。为了节省成本,请考虑在 EC2 Spot 实例上运行,您可以享受实例价格的折扣,但是可以抢占这些实例。由于 AutoGluon-Tabular 设计为具有容错能力,因此当容量再次可用时,您始终可以恢复训练。

任务、负载和正常运行时间的屏幕截图

下载 Kaggle CLI

按照 Kaggle API GitHub 页面上的说明下载 Kaggle CLI。借助 CLI,您可以轻松下载数据集并以编程方式提交预测结果,而无需离开 Jupyter 笔记本。

下载 AutoGluon

按照 AutoGluon 网页上的说明安装 AutoGluon。在大多数情况下,您应该可以使用 pip 进行安装。

入门

以下步骤来自 GitHub 上托管的 otto-kaggle-example.ipynb Jupyter 笔记本。让我们详细了解每个步骤。

第 1 步:下载数据集

此步骤假设您已安装 Kaggle CLI,并且您已同意通过访问比赛页面来参加比赛。

dataset = 'dataset'
!kaggle competitions download -p {dataset} -q otto-group-product-classification-challenge
!unzip -d {dataset} {dataset}/otto-group-product-classification-challenge.zip
!rm {dataset}/otto-group-product-classification-challenge.zip

输出:

Archive: dataset/otto-group-product-classification-challenge.zip
 inflating: dataset/sampleSubmission.csv 
 inflating: dataset/test.csv 
 inflating: dataset/train.csv

第 2 步:导入 AutoGluon 并检查数据集

在此步骤中,我们导入一个 TabularPrediction 任务。如果您熟悉 pandas,则会非常熟悉 task.Dataset() 函数,该函数可以读取各种表格数据文件,并返回类似 pandas 的对象。由于 AutoGluon-Tabular 并不希望您进行任何预处理,因此除了删除不需要的变量或加入多个数据集之外,您不需要进行大量数据操作。

from autogluon import TabularPrediction as task train_data = task.Dataset(file_path=f'{dataset}/train.csv').drop('id', axis=1) train_data.head()

输出:

Loaded data from: dataset/train.csv | Columns = 95 / 95 | Rows = 61878 -> 61878
feat_1 feat_2 feat_3 feat_4 feat_5 feat_6 feat_7 feat_8 feat_9 feat_10 ... feat_85 feat_86 feat_87 feat_88 feat_89 feat_90 feat_91 feat_92 feat_93 target
0 1 0 0 0 0 0 0 0 0 0 ...1 0 0 0 0 0 0 0 0 Class_1
1 0 0 0 0 0 0 0 1 0 0 ...0 0 0 0 0 0 0 0 0 Class_1
2 0 0 0 0 0 0 0 1 0 0 ...0 0 0 0 0 0 0 0 0 Class_1
3 1 0 0 1 6 1 5 0 0 1 ...0 1 2 0 0 0 0 0 0 Class_1
4 0 0 0 0 0 0 0 0 0 0 ...1 0 0 0 0 1 0 0 0 Class_1
5 rows × 94 columns

第 3 步:拟合 AutoGluon 模型

label_column = 'target' # specifies which column do we want to predict
savedir = 'otto_models/' # where to save trained models
predictor = task.fit(train_data=train_data,
                        label=label_column,
                        output_directory=savedir,
                        eval_metric='log_loss',
                        auto_stack=True,
                        verbosity=2,
                        visualizer='tensorboard')

fit() 函数的必需参数是 train_datalabel,其余参数是可选的。在此示例中,我还指定了以下选项:

  • output_directory:您要保存所有模型和中间步骤的位置。
  • eval_metric:指标 AutoGluon 将用于优化您的模型;有关支持的指标的完整列表,请参见文档页面。
  • auto_stack:如果您希望 AutoGluon 利用本文“集成和多层堆叠”部分中所述的堆叠,则此选项为 true。
  • verbosity:值为 0 表示您看不到任何输出。4 是最高详细级别。
  • visualizer:如果将此设置为 tensorboard,则可以在 TensorBoard 上监控训练进度以进行神经网络训练。

输出:

Beginning AutoGluon training ...
AutoGluon will save models to otto_models/
Train Data Rows: 61878
Train Data Columns: 94
Preprocessing data ...
Here are the first 10 unique label values in your data: ['Class_1' 'Class_2' 'Class_3' 'Class_4' 'Class_5' 'Class_6' 'Class_7'
 'Class_8' 'Class_9']
AutoGluon infers your prediction problem is: multiclass (because dtype of label-column == object)
If this is wrong, please specify `problem_type` argument in fit() instead (You may specify problem_type as one of: ['binary', 'multiclass', 'regression'])Feature Generator processed 61878 data points with 93 features
Original Features:
 int features: 93
Generated Features:
 int features: 0
All Features:
 int features: 93
 Data preprocessing and feature engineering runtime = 0.36s ...
AutoGluon will gauge predictive performance using evaluation metric: log_loss
This metric expects predicted probabilities rather than predicted class labels, so you'll need to use predict_proba() instead of predict()
To change this, specify the eval_metric argument of fit()
AutoGluon will early stop models using evaluation metric: log_loss
/home/ubuntu/anaconda3/envs/autogluon/lib/python3.7/imp.py:342: DeprecationWarning: Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated since Python 3.3,and in 3.9 it will stop working
 return _load(spec)
Fitting model: RandomForestClassifierGini_STACKER_l0 ...
 -0.5691 = Validation log_loss score
 27.63s = Training runtime
 0.03s = Validation runtime
…
…

您可以使用 TensorBoard 监控神经网络训练性能。安装 TensorBoard 并运行:

tensorboard —logdir otto_models/models/

并将您的浏览器指向 http://0.0.0.0:6006/

将浏览器指向 http://0.0.0.0:6006/ 时监控神经网络训练性能的屏幕截图

第 4 步:获取拟合摘要

results = predictor.fit_summary() # display detailed summary of fit() process

输出:

*** Summary of fit() ***
Number of models trained: 22
Types of models trained: 
{'WeightedEnsembleModel', 'StackerEnsembleModel'}
Validation performance of individual models: {'RandomForestClassifierGini_STACKER_l0': -0.5691089791208548,...}
Best model (based on validation performance): weighted_ensemble_k0_l2
Hyperparameter-tuning used: False
Bagging used: True (with 10 folds)
Stack-ensembling used: True (with 1 levels)
User-specified hyperparameters:
{'NN': {'num_epochs': 500, 'visualizer': 'tensorboard'}, 'GBM': {'num_boost_round': 10000}, ...}
Plot summary of models saved to file: SummaryOfModels.html
*** End of fit() summary ***

要比较集成中的所有模型,请调用 leaderboard()

lboard = predictor.leaderboard()
lboard.sort_values(by='score_val', ascending=False)

输出:

具有模型、score_val、fit_time、pred_time_val 和 stack_level 的输出的屏幕截图

第 5 步:加载测试数据集并进行预测

dataset = 'dataset'
test_data_full = task.Dataset(file_path=f'{dataset}/test.csv')
test_data = test_data_full.drop('id', axis=1)
pred_probablities = predictor.predict_proba(test_data, as_pandas=True)

第 6 步:将结果提交给 Kaggle

submission_name = 'autogluon-submission.csv'
pred_probablities.to_csv(submission_name,index=False)

!kaggle competitions submit otto-group-product-classification-challenge -f {submission_name} -m "autogluon {submission_name}"

前往比赛页面,您应该会看到分数。我收到的分数是 0.40708,在 3,511 个提交中,我排名第 32 位,处于所有提交前 1% 之外。

有关如何在其他 Kaggle 比赛中使用 AutoGluon 的说明,请查看 AutoGluon 文档“如何在 Kaggle 比赛中使用 AutoGluon”中的教程。

kaggle 提交的屏幕截图

第一名的解决方案包括 33 个模型,再使用这些模型的输出训练另外 3 个模型(堆叠),然后进行加权平均

结论

在本文中,我介绍了 AutoGluon 和 AutoGluon-Tabular,并解释了如何使用它来加速数据科学项目。如果您想了解有关 AutoGluon-Tabular 的更多信息,以及如何在流行的 AutoML 和 Kaggle 基准测试中运行,如何与其他 AutoML 解决方案进行比较的详细信息,请阅读 AutoGluon-Tabular 白皮书“AutoGluon-Tabular:适用于结构化数据稳健而精确的 AutoML”

数据科学是关于不断发展的目标函数和持续的优化。如果您在探索 AutoGluon 功能时有任何疑问或建议,请告诉我们。请在 Twitter 上关注 @shshnkp 或通过 LinkedIn 与我联系,或通过在 GitHub 上提交问题与 AutoGluon 团队联系。

AutoGluon 积极接受 AutoGluon 项目的代码贡献。如果您有兴趣为 AutoGluon 做出贡献,请访问 GitHub 上的贡献页面以获取更多信息。

我们代表 AutoGluon 团队感谢您的阅读,并祝您愉快使用 AutoGluon 进行自动化机器学习!