亚马逊AWS官方博客

使用 AWS Data Exchange 和 Amazon SageMaker 构建机器学习工作流

Original URL:https://aws.amazon.com/blogs/machine-learning/building-machine-learning-workflows-with-aws-data-exchange-and-amazon-sagemaker/

得益于诸如 Amazon SageMakerAWS Data Exchange 等云服务,现在实施机器学习 (ML) 比以往更加容易。本博文将介绍如何使用 AWS Data Exchange 和 Amazon SageMaker 构建模型,以预测纽约市餐厅的餐厅等级。我们使用 AWS Data Exchange中的数据集(包含 23372 个餐厅检查等级和分数)和 Amazon SageMaker中的线性学习器算法训练和部署模型。

背景

ML 工作流是一个迭代过程,需要做出许多决策,例如是否需要训练数据、要捕获哪些属性、要使用哪些算法和在何处部署经过训练的模型。所有这些决策都将影响学习系统的结果。明确问题后,您必须从四种不同类型的学习系统中选择所需的学习系统。有些学习系统完全依赖训练数据,而另一些学习系统则根本不需要训练数据,而是需要一个明确定义的环境和行动空间。当算法依赖于训练数据时,最终模型的质量和灵敏度在很大程度上取决于训练集的特征。正因如此,许多人进入了一个繁琐的循环,试图找到合理的功能平衡,从而获得一个均衡且准确的模型。以下是每个学习系统的概述:

  1. 监督学习 – 在监督学习中,训练集包含标签,因此,在给定一组属性的情况下,算法能知道哪个是正确的标签。例如,属性可以是鱼的颜色和重量,而标签是鱼的类型。最终,模型将学习如何分配正确的或最有可能的标签。典型的监督学习任务是分类,即将文本或图像等输入分配给多个预定义类别之一。示例包括根据邮件标题和内容检测垃圾邮件,根据 MRI 扫描结果将细胞归类为恶性或良性细胞,以及根据形状对星系进行分类(Tan 等人,2006 年)。这类算法通常包括 k 近邻、线性回归、逻辑回归、支持向量机和神经网络。
  2. 无监督学习 – 无监督式学习使用算法来发现无标签数据中的关系。算法必须能够探索数据并根据已知特性查找关系。非监督式学习常用的一些算法包括聚类(K-means、DBSCAN 和层次聚类分析,它们对相似数据点进行分组)、异常检测(找出异常值)和关联规则学习(发现特征之间的关联)(Aurélien 2019)。在实践中,可以通过基于犯罪率将城市聚类来了解哪些城市是相似的,或者根据顾客年龄对杂货店商品进行聚类来发现模式。
  3. 半监督学习 – 半监督学习使用的训练数据由有标签数据和无标签数据组成。算法通常是无监督学习算法和监督学习算法的组合。如果您有一个数据集,其中包含无标签数据,则第一步是为数据添加标签。数据集添加标签后,您可以使用传统的监督学习方法训练算法,将特征映射到已知标签。照片托管服务通常使用此工作流,首先需要您来标记未知的面孔。一旦人脸被识别,另一种算法可以扫描所有照片以识别现在已知的面孔。
  4. 强化学习 – 强化学习 (RL) 不同于前面的学习系统,因为它不必从训练数据中学习。相反,该模型从其在明确定义的环境中获得的经验学习。该学习系统称为代理,代理可以观察环境,根据策略选择和执行操作,并获得奖励。随着时间的推移,代理最终学会根据以前的经验获得最大奖励。有关 RL 的更多信息,请参阅 Amazon SageMaker RL 中的相关文档。

构建餐厅等级预测模型的步骤

在开始 ML 项目时,必须要考虑整个流程,而不仅仅是最终产品。在此项目中,我们将执行以下步骤:

  1. 明确要解决的问题。在本例中,我们希望根据清洁度做出在纽约市哪个餐厅用餐的更明智选择。
  2. 找到用于训练模型的数据集。我们需要一个数据集,其中包含纽约市的餐厅检查等级和分数。
  3. 查看数据。我们希望确保所需的数据存在,并且有足够的数据来训练模型。
  4. 准备并清理数据集,以便在 Amazon SageMaker 中进行训练。我们希望仅包含所需的数据,例如“行政区”和“食品类别”,并确保使用正确的格式。
  5. 选择多分类模型。在本例中,我们将使用线性学习器算法进行训练。
  6. 将模型部署到 Amazon SageMaker。通过将模型部署到 Amazon SageMaker,我们可以调用终端节点以获取预测。

数据是机器学习的基础;最终模型的质量取决于用于训练的数据的质量。在我们的工作流中,一半步骤与数据收集和准备有关。这一主题在大多数 ML 项目中都可以看到,通常是最具挑战性的部分。此外,您必须考虑数据的特征,以防止模型过于敏感或者不够敏感。此外,并非所有数据都是内部数据。您可能必须使用免费或付费的第三方数据来扩充内部数据集并提高模型的质量,但多年来,查找、授权和使用此类第三方数据一直是一个难题。幸运的是,您现在可使用 AWS Data Exchange。

使用 AWS Data Exchange

AWS Data Exchange 让您能在云中轻松查找、订阅和使用第三方数据,从而简化数据收集过程。您可以在 AWS Marketplace 中浏览来自 90 多家合格数据提供商的 1500 多种数据产品。以前,需要访问更多数据以推动分析、训练 ML 模型并做出数据驱动型决策,但现在,借助 AWS Data Exchange,您可以一站式完成所有这些操作。有关更多信息,请参见 AWS Data Exchange – 查找、订阅和使用数据产品

借助 AWS Data Exchange,您可以轻松开始实施 ML。您可以使用数百个可用数据集中的一个或多个的组合来快速启动项目。您还可以使用外部第三方数据来扩充内部数据。所有数据集均可使用一个云原生API 来获取,该 API 可将您的数据直接传送到 Amazon S3,我们将在后面的工作流中看到这一点。这样可以节省您和您的团队宝贵的时间和资源,而将这些时间和资源可用于进行更有价值的活动。通过这种组合,您可以从 AWS Data Exchange 获取数据,并将其提供给 Amazon SageMaker 以训练和部署您的模型。

使用 Amazon SageMaker

Amazon SageMaker 是一项完全托管的服务,使您能够快速轻松地构建、训练和部署 ML 模型。您可以从 AWS Data Exchange 获取纽约市餐厅数据,并使用 Amazon SageMaker 的功能来训练和部署模型。您将使用运行 Jupyter 笔记本的完全托管实例来浏览和预处理训练数据。这些笔记本预先加载了常用深度学习平台需要的 CUDA 和 cuDNN 驱动程序、Anaconda 软件包以及 TensorFlow、Apache MXNet 和 PyTorch 的库。

您还将使用线性学习器算法等监督学习算法来训练模型。最后,该模型将部署到 Amazon SageMaker 终端节点,以开始服务请求并预测餐厅等级。通过将 AWS Data Exchange 的强大功能与 Amazon SageMaker 相结合,您就获得了一套强大的工具来着手解决最具挑战性的 ML 问题,现在可以开始着手构建多分类器了。

解决方案概览

本博文的解决方案产生了一个多分类器,可以根据行政区和食品类别预测纽约市的餐厅等级。下图显示了完整架构。

首先,从 AWS Data Exchange 获取数据,然后将其放入 S3 存储桶中。将一个 AWS Glue 爬网程序指向它,以创建数据的数据目录。在数据目录就绪的情况下,使用 Amazon Athena 查询、清理和格式化数据,以准备进行训练。数据转换后,将训练集加载回 S3。最后,在 Amazon SageMaker 中创建 Jupyter 笔记本以训练、部署和调用预测程序。

将数据存储在 S3 中

在 ML 项目中,获取训练数据通常是一个非常耗时且具有挑战性的部分。在本例中,您需要确保可以找到一个足够大的数据集,该数据集包含纽约市餐厅的检查信息,并且包含正确的属性。幸运的是,借助 AWS Data Exchange,您可以开始在产品目录中搜索数据。在本例中,您关注的是纽约市餐厅的质量,因此在搜索栏中输入 New York Restaurant Data 并筛选出免费数据集。Intellect Design Arena, Inc. 提供了一个免费产品,标题为 NY City Restaurant Data with inspection grade & score (Trial)(包含检查等级和分数的纽约市餐厅数据 [试用版])。

订阅数据集后,您需要找到一种将数据公开给其他 AWS 服务的方法。要达到此目的,请选择订阅、数据集、修订、导出到 S3,以将数据导出。当数据位于 S3 中时,您可以下载文件并查看数据,以了解所捕获的特征。以下屏幕截图显示了修订页面,您可以使用“导出到 Amazon S3”按钮导出数据。

现在,您可以下载文件并查看内容,以了解有多少数据以及捕获了哪些属性。在本例中,您只需要关注三个属性:行政区(标记为 BORO)、美食描述和等级。系统会创建一个新文件(仅包含与此用例相关的数据),并将其加载回 S3。使用位于 S3 中的数据,其他 AWS 服务可以快速安全地访问数据。以下屏幕截图展示了加载文件夹和数据后 S3 存储桶的样子。

使用 AWS Glue 爬网程序创建数据目录

当前的数据并不满足针对 Amazon SageMaker 训练数据的要求,因此您需要建立提取、转换、加载 (ETL) 管道,以将此数据集转换为正确的格式。稍后在管道中,您将使用 Athena 查询此数据并生成格式化的训练集,但目前数据只是存储桶中的 CSV 文件,我们需要一种方法与数据进行交互。您可以使用 AWS Glue 爬网程序扫描数据并生成数据目录,从而使 Athena 能够查询 S3 内的数据。有关详细信息,请参见定义爬网程序。运行 AWS Glue 爬网程序后,您现在获得了一个数据目录,Athena 可以使用该目录查询数据。数据的详细信息将被捕获,您可通过单击新创建的数据目录来查看这些信息。以下屏幕截图显示了数据目录界面,其中包含与您的数据相关的所有信息。

在 Athena 中查询数据并创建训练集

现在,您已将数据集放入 S3,并通过 AWS Glue 爬网程序获得了数据目录,因此,您可以使用 Athena 开始查询和格式化数据。您可以使用集成的查询编辑器来生成 SQL 查询,以便浏览和转换数据。对于本例,您创建了 SQL 查询以生成以下训练集。这是为了简化训练流程,因为您正从基于文本的属性转移到基于数字的属性。当使用线性学习器算法进行多分类训练时,类标签必须为 0 到 N-1 之间的数值,其中 N 是可能的类数。在 Athena 中运行查询后,您可以下载结果并将新数据集放入 S3 中。现在,您可以开始在 Amazon SageMaker 中训练模型。请参阅以下代码:

SELECT boro_data.id AS "boro_label",
         category_data.id AS "cat_label",
         class_label
FROM data
LEFT JOIN boro_data
    ON data.boro = boro_data.boro
LEFT JOIN category_data
    ON data.cuisine_description = category_data.cuisine_description

SQL 查询创建了属性和类标签的数字表示形式,如下表所示。

boro_label cat_label class_label
1 5 8 0
2 5 8 0
3 5 8 0
4 5 8 0
5 5 8 0
6 5 8 0
7 5 8 0
8 5 8 0
9 5 8 0
10 5 8 0
11 5 8 0
12 5 8 0
13 5 8 0
14 5 8 0
15 5 8 0

在 Amazon SageMaker 中训练和部署模型

现在您已获得了干净的数据,您将使用 Amazon SageMaker 构建、训练和部署模型。首先,在 Amazon SageMaker 中创建 Jupyter 笔记本,以开始编写和执行代码。然后,您将数据从 S3 导入到 Jupyter 笔记本环境中,并继续训练模型。要训练模型,请使用 Amazon SageMaker 中包含的线性学习器算法。线性学习器算法为分类和回归问题提供了解决方案,但在本博文中,您将重点关注分类。以下 Python 代码显示了加载、格式化和训练模型的步骤:

import numpy as np
import pandas as pd
import boto3
from sklearn.model_selection import train_test_split
import sagemaker

#declare bucket name and file name
bucket = 'qs-demo-bgf'
prefix = 'transformed-data-no-header/'
fileName = 'transformed_data_no_header.csv'

#load data 
s3 = boto3.resource('s3')

KEY = prefix+fileName
print(KEY)

#load data into jupyter environment
s3.Bucket(bucket).download_file(KEY,'transformed_data_no_header.csv')

data = pd.read_csv('transformed_data_no_header.csv',dtype='float32').values

data_features, data_labels = data[:, :2], data[:, 2]
np.random.seed(0)
train_features, test_features, train_labels, test_labels = train_test_split(
    data_features, data_labels, test_size=0.2)

# further split the test set into validation and test sets
val_features, test_features, val_labels, test_labels = train_test_split(
    test_features, test_labels, test_size=0.5)

# instantiate the LinearLearner estimator object
multiclass_estimator = sagemaker.LinearLearner(role=sagemaker.get_execution_role(),
                                               train_instance_count=1,
                                               train_instance_type='ml.m4.xlarge',
                                               predictor_type='multiclass_classifier',
                                               num_classes=3)
# wrap data in RecordSet objects
train_records = multiclass_estimator.record_set(train_features, train_labels, channel='train')
val_records = multiclass_estimator.record_set(val_features, val_labels, channel='validation')
test_records = multiclass_estimator.record_set(test_features, test_labels, channel='test')

# start a training job
multiclass_estimator.fit([train_records, val_records, test_records])

训练作业完成后,您可以将模型部署到实例上。这为您提供了一个用于监听预测请求的终端节点。请参阅以下 Python 代码:

# deploy a model hosting endpoint
multiclass_predictor = multiclass_estimator.deploy(initial_instance_count=1, instance_type='ml.m4.xlarge')

调用 Amazon SageMaker 终端节点

现在您已部署了经过训练的模型,您可以开始调用终端节点以获取预测。终端节点为每个类的类型提供一个分数,并根据最高分数提供一个预测标签。您现在获得了一个可集成到应用程序中的终端节点。以下 Python 代码是在 Amazon SageMaker 笔记本中调用终端节点的示例:

import json 
import boto3 
client = boto3.client('runtime.sagemaker')

#define a dictionary to map text to numerical values
area = {
    "Queens":1.0,
    "Staten Island":2.0,
    "Brooklyn":3.0,
    "Bronx":4.0,
    "Manhattan":5.0
}

cat = {
    "Hotdogs/Pretzels":1.0,
    "Donuts":2.0,
    "Bangladeshi":3.0,
    "Caribbean":4.0,
    "Chicken":5.0
}

#assign features to pass to endpoint
location = area["Manhattan"]
category = cat["Hotdogs/Pretzels"]

values = str(location)+','+str(category)

#get response from endpoint
response = client.invoke_endpoint(EndpointName='linear-learner-2019-11-04-01-57-20-572',
                                  ContentType='text/csv',
                                  Body=values)

#parse the results
result = json.loads(response['Body'].read().decode())

predict = result['predictions'][0]
print(predict)

grade = predict['predicted_label']

if(grade==0.0):
    letter = "A"
elif(grade==1.0):
    letter = "B"
else:
    letter = "C"

#get readable prediction
print("\Restaurant Grade: "+letter)

在调用终端节点后,系统将提供响应并将其格式化为可读的预测结果。请参阅以下代码:

{'score': [0.9355735182762146, 0.0486408956348896, 0.01578556001186371], 'predicted_label': 0.0}

Restaurant Grade: A

清理资源

为防止出现任何持续计费的情况,您应清理资源。先从 AWS Data Exchange 开始,如果您订阅了本示例中使用的数据集,请将订阅设置为在一个月试用期结束时终止。删除存储本示例中所用数据的所有 S3 存储桶。删除因 AWS Glue 爬网程序而创建的 AWS Glue 数据目录。此外,删除您的 Amazon SageMaker 笔记本实例和您在部署模型时创建的终端节点。

小结

本博文提供了一个示例工作流,该工作流使用 AWS Data Exchange 和 Amazon SageMaker 构建、训练和部署多分类器。您可以借助 AWS Data Exchange 使用第三方数据快速启动 ML 项目,并使用 Amazon SageMaker 的内置工具和算法为 ML 任务创建解决方案。如果您处于 ML 项目的早期阶段,或者正设法改进现有数据集,请查看 AWS Data Exchange,您可以节省数小时的数据整理时间。

参考资料

  • Géron Aurélien。Hands-on Machine Learning with Scikit-Learn, Keras, and TensorFlow: Concepts, Tools, and Techniques to Build Intelligent Systems(Scikit-Learn、Keras 和 TensorFlow 机器学习动手实践:智能系统构建概念、工具和技术)。OReilly,2019 年。
  • Tan、Pan-Ning 等人。Introduction to Data Mining(数据挖掘简介)。Pearson,2006 年。

关于作者

Ben Fields 是战略客户解决方案架构师,在华盛顿州西雅图工作。他对 AI/ML、容器和大数据非常感兴趣,而且经验丰富。他经常在攀岩馆攀岩,在溜冰场打冰球,或者在家看一场精彩的比赛,与家人共度温馨时光。