搞定基于表格数据的 ML 模型,有 Amazon SageMaker 就够了

image

表格类数据一直是众多行业(包括金融、医疗保健以及制造业等)所采取的主要数据存储方法。大多数机器学习(ML)用例也主要面向传统的结构化或表格数据。例如,欺诈检测用例会通过表格形式的输入内容(包括客户账户的历史记录或付款明细),以检测交易中是否存在欺诈风险。客户流失检测或产品需求预测等也都属于这类依赖于表格数据的用例。而在使用机器学习处理表格数据时,我们往往需要引入人工审核流程,协助管理工作流中需要人工加以判断的敏感环节。

在此类用例的工作流中,人工审核人员需要查看ML模型中以静态表格格式(通常被称为「数据框」)作为输入的全部或部分数字化特征,同时对输出结果中的某些行做出动态修改。在前一种情况下,负责构建工作 UI 的开发人员可能要求将表格数据作为静态、不可变的对象直接摄取至 UI 当中。而在后一种用例内,我们则可以对表进行动态摄取。这时表将作为 UI 的一部分生成,并供审查者随时对其做出修改。

在本文中,我们将了解如何使用 Amazon SageMaker 来构建、训练及部署基于表格数据的ML模型;同时使用 Amazon Augmented AI(Amazon A2I)构建并呈现自定义工作模板,帮助审查人员随时查看静态或动态表。

Amazon SageMaker 是一项全托管服务,能够将快速构建、训练以及部署ML模型的能力交付至每一位开发人员及数据科学家手中。Amazon SageMaker消除了机器学习流程中各环节所带来的繁重工作,帮助客户构建起人工审核工作流,借此审查并验证ML模型的预测结果。Amazon A2I则消除了构建这些人工检查工作流所带来的种种系统管理负担。

其他常见人工工作流程还包括图像与视频内容审核,以及从文档中提取文本与实体等。我们可以直接使用 ML 模型识别不当内容或者提取实体,但在实践中往往仍然需要工作人员结合具体用例及业务环境对模型预测加以验证。在这方面,Amazon A2I 能够帮助大家快速设计并建立起此类人工工作流。

我们还可以通过 Amazon A2I 将 ML 预测出的随机样本发送给人工审查员,或者使用这些结果向利益相关方展示模型性能并审核模型预测能力。

先决条件

要完成本文的演练,需要满足以下先决条件:

  1. IAM 角色 —— 要创建人工审核工作流,我们需要提供一个 AWS Identity and Access Management (IAM)角色,用于向 Amazon A2I 授予访问 Amazon Simple Storage Service (Amazon S3)的权限,进而编写人工审核结果。此角色还需要具备其他信任策略,保证 Amazon SageMaker 有权使用该角色。如此一来,Amazon A2I 即可根据角色对应的权限执行操作。关于如何对用于创建工作流定义的角色进行策略修改与添加,请参阅如何创建流定义
  2. Amazon SageMaker notebook 实例 —— 关于创建 Amazon SageMaker notebook 实例的详细说明,请参阅创建一个 Notebook 实例
  3. S3 存储桶 —— 创建一个 S3 存储桶以保存人工工作流输出结果。请记录该存储桶的 ARN,以供后续在随附的 Jupyter notebook 中使用。
  4. 专项团队 —— 即负责对文档进行人工审核的员工。我们可以指定内部员工组建审核团队,也可以选择由 Amazon Mechanical Turk 聘用的员工、供应商的员工或者以外包形式募集的其他人员。在本文中,我们将指定内部员工组建审核团队,由他们审查 Amazon A2I 工作流。关于更多详细信息,请参阅创建专项团队。请记录该团队的 ARN,以供后续在随附的 Jupyter notebook 中使用。
  5. Jupyter notebook—— 本文直接使用 GitHub%20Integration%20with%20tabular%20data.ipynb) 上提供的 Jupyter notebook。在数据集方面,我们使用 scikit-learn [1] 提供的UCI乳腺癌检测数据集,即使用医学诊断数据预测病变属于良性还是恶性。

在 Amazon SageMaker 上训练并部署模型

训练与部署阶段中的关键步骤包括:

  1. 导入必要的库并加载数据集。
  2. 将数据集划分为训练数据集与测试数据集,而后训练 ML 模型。在本文中,我们将使用 Amazon SageMaker 中内置的 XGBoost 算法训练模型,以得出二元预测结果。
  3. 创建一个端点,用以生成关于测试数据的推理示例。

我们可以使用 scikit-learn 中的内置实用程序导入数据、导入数据集、生成训练与测试数据集,并最终完成模型训练以及预测结果生成。Scikit-learn 还提供另外一款实用程序,可根据固定比率(在大部分数据科学应用中通常为80:20)以及随机状态将数据集划分为训练集与测试集,借此确保结果的可重现性。数据集详情,参见以下截屏中的表格。

image

要完成模型训练,我们需要使用内置的 XGBoost 算法,这是一种用于监督学习的高效、可扩展梯度提升树算法。关于更多详细信息,请参阅 XGBoost 工作原理

按照 Notebook 中的步骤完成模型训练。在模型训练完成后,Amazon SageMaker 会接手模型终端节点的部署与托管,如 Notebook 中所示。Amazon SageMaker 将为训练后的构型构建 HTTPS 终端节点,并根据需求自动扩展以在推理时提供流量。完成模型部署后,即可生成预测结果。请参阅随附 Notebook 中的以下源码:

## Lets now run predictions on our test set and use it to create a table containing our outputs.
import numpy as np
def predict(data, model, rows=500):
 split_array = np.array_split(data, int(data.shape[0] / float(rows) + 1))
 predictions = ''
 for array in split_array:
 predictions = ','.join([predictions, model.predict(array).decode('utf-8')])
 return np.round(np.fromstring(predictions[1:], sep=','))
## Generate predictions on the test set for the difference models
predictions = predict(test_data[list(test_data.columns)[1:]].values, xgb_predictor)

该单元格的输出为一系列预测结果:1或0分别代表恶性或良性。

随后,我们可以将模型输出合并至人工工作流当中。

创建工作任务模板、人工审查工作流以及人工循环

随附的Jupyter notebook中包含以下操作步骤:

  1. 创建一个工作任务(worker task)模板,用于创建工作UI。此工作UI将显示输入数据,例如文档或图像,以及对审核人员的指导性说明。此外,其中还提供供工作人员完成任务的交互式工具。关于更多详细信息,请参阅创建工作 UI
  2. 创建一个人工审查工作流,也被称为流程定义。我们使用流程定义来配置人工团队,并提供关于如何完成人工审查任务的指导信息。大家可以使用单一流定义创建多个人工循环。关于更多详细信息,请参阅创建流定义
  3. 创建一个人工循环,用于启动人工审查工作流并发送数据以供人工检查。在本文中,我们使用自定义任务类型并通过 Amazon A2I Runtime API启动人工循环。在自定义应用程序中调用 StartHumanLoop,即可将任务发送给人工审核人员。

下面,我们将详细讨论如何在工作任务 UI 当中添加表格数据。

将表纳入工作任务 UI

Amazon A2I 使用 Liquid 实现模板自动化。Liquid 是一种开源内联标记语言,可在大括号内包含文本,并通过指令创建过滤器与控制流。

在本文中,我们要求审核人员查看测试数据的特征,以判断模型输出结果是否准确。现在我们开始编写模板。此模板由两部分组成:包含测试数据集特征的静态表,以及包含允许用户修改的预测结果的动态表。

这里使用以下模板:

template = r"""
<script src="https://assets.crowd.aws/crowd-html-elements.js"></script>

<style>
 table, tr, th, td {
 border: 1px solid black;
 border-collapse: collapse;
 padding: 5px;
 }
</style>

<crowd-form>
 <div>
 <h1>Instructions</h1>
 <p>Please review the predictions in the Predictions table based on the input data table below, and make corrections where appropriate. </p>
 <p> Here are the labels: </p>
 <p> 0: Benign </p>
 <p> 1: Malignant </p>
 </div>
 <div>
 <h3> Breast cancer dataset </h3>
 <div id="my_table"> {{ task.input.table | skip_autoescape }} </div>
 </div>
 <br>
 <h1> Predictions Table </h1>
 <table>
 <tr>
 <th>ROW NUMBER</th>
 <th>MODEL PREDICTION</th>
 <th>AGREE/DISAGREE WITH ML RATING?</th>
 <th>YOUR PREDICTION</th>
 <th>CHANGE REASON </th>
 </tr>
 
 {% for pair in task.input.Pairs %}
 
 <tr>
 <td>{{ pair.row }}</td>
 <td><crowd-text-area name="predicted{{ forloop.index }}" value="{{ pair.prediction }}"></crowd-text-area></td>
 <td>
 <p>
 <input type="radio" id="agree{{ forloop.index }}" name="rating{{ forloop.index }}" value="agree" required>
 <label for="agree{{ forloop.index }}">Agree</label>
 </p>
 <p>
 <input type="radio" id="disagree{{ forloop.index }}" name="rating{{ forloop.index }}" value="disagree" required>
 <label for="disagree{{ forloop.index }}">Disagree</label> 
 </p>
 </td>
 <td>
 <p>
 <input type="text" name="True Prediction" placeholder="Enter your Prediction" />
 </p>
 </td>
 <td>
 <p>
 <input type="text" name="Change Reason" placeholder="Explain why you changed the prediction" />
 </p>
 </td>
 </tr>
 
 {% endfor %}
 
 </table>
</crowd-form>
"""

def create_task_ui():
 '''
 Creates a Human Task UI resource.
 
 Returns:
 struct: HumanTaskUiArn
 '''
 
 response = sagemaker_client.create_human_task_ui(
 HumanTaskUiName=taskUIName,
 UiTemplate={'Content': template})
 return response

其中的 task.input.table 字段允许大家将静态表提取至工作任务 UI 当中。而 skip_autoescape 过滤器则负责将 pandas 表呈现为 HTML 形式。关于更多详细信息,请参阅创建自定义工作模板

其中的 task.input.Pairs 字段用于在工作任务 UI 中动态生成表。由于此表中包含预测结果并需要配合人工输入,因此大家可以在其中同时包含单选按钮与文本字段,以帮助工作人员对模型的预测结果做出同意/不同意标记、在必要时更改模型预测结果,并提出更改的潜在原因。另外,这样的设计思路还可以限制我们在 ML 模型中的使用的特征类型,借此满足某些严格要求避免偏见因素的监管要求,充分遵守法规与合规性条款。

我们还需要使用 pandas 实用程序,其用于将数据框转换为 HTML 格式。在以下示例代码片段当中,我们需要加载测试数据的前五行以供人工审核者查看。对于表的动态部分,创建一个包含列标识符以及此前模型实际预测结果的表。

item_list = [{'row': "ROW_{}".format(x), 'prediction': predictions[x]} for x in range(5)]

[{'row': 'ROW_0', 'prediction': 1.0},
 {'row': 'ROW_1', 'prediction': 0.0},
 {'row': 'ROW_2', 'prediction': 0.0},
 {'row': 'ROW_3', 'prediction': 1.0},
 {'row': 'ROW_4', 'prediction': 1.0}]

现在我们可以创建工作任务模板与人工审核工作流了。具体请参见以下代码片段:

# Create task UI
humanTaskUiResponse = create_task_ui()
humanTaskUiArn = humanTaskUiResponse['HumanTaskUiArn']
print(humanTaskUiArn)
create_workflow_definition_response = sagemaker_client.create_flow_definition(
 FlowDefinitionName= flowDefinitionName,
 RoleArn= role,
 HumanLoopConfig= {
 "WorkteamArn": WORKTEAM_ARN,
 "HumanTaskUiArn": humanTaskUiArn,
 "TaskCount": 1,
 "TaskDescription": "Make sure the labels are correct",
 "TaskTitle": "tabular data a2i demo"
 },
 OutputConfig={
 "S3OutputPath" : OUTPUT_PATH
 }
 )
flowDefinitionArn = create_workflow_definition_response['FlowDefinitionArn'] # let's save this ARN for future use

使用以下代码片段以启动人工循环:


ip_content = {"table": test_data.reset_index().drop(columns = ['index', 'label']).head().to_html(),
 'Pairs': item_list
 }

import json
humanLoopName = str(uuid.uuid4())

start_loop_response = a2i.start_human_loop(
 HumanLoopName=humanLoopName,
 FlowDefinitionArn=flowDefinitionArn,
 HumanLoopInput={
 "InputContent": json.dumps(ip_content)
 }
 )

在本文使用专项团队处理人工审核工作,因此工作人员可以在打开团队创建时接收到的链接,借此获取可视化 UI。

完成人工审核

以下截屏所示,为我们使用的工作UI。
image

上方的表中包含以 HTML 形式存在的 pandas 数据框,而 Predictions Table 表则是根据数据集内所有或部分行动态生成而来。Model Prediction 字段由基于此前测试数据集中相应行的模型推理所组成。在生成UI时,User Rating 意见(同意或不同意)、Your Prediction 以及 Change Reason 等字段皆为空白。

工作人员使用单选按钮以验证模型预测结果,并发布经过修改的预测结果。当然,工作人员也可以根据需要选择输入更改原因(如以上截屏所示),借此帮助数据科学团队更好地设计下游模型再训练方法。例如,如果工作人员将模型预测判断为误报并发布了原因(例如某项特征可能属于异常值),则数据科学家可以在模型重新训练期间删除此数据点,以防止模型对异常值进行过度拟合。

在工作人员对新的预测结果进行评分并提交答案之后,我们可以直接在 Amazon S3 中进行可视化输出,也可以直接通过 Amazon SageMaker notebook 环境中实现结果可视化。

查看人工审核后的结果

在提交审核之后,相关结果将被写入至我们通过人工审核工作流指定的 Amazon S3 内输出位置。以下内容,为此位置上以 JSON 文件格式输出的结果。

l 人工审核回应

l 指向 StartHumanLoop API 的输入内容

l 关联的元数据

大家可以使用此信息来跟踪 ML 输出结果,并将其与人工审核输出关联起来:

import re
import pprint

pp = pprint.PrettyPrinter(indent=4)
for resp in completed_human_loops:
 splitted_string = re.split('s3://' + BUCKET + '/', resp['HumanLoopOutput']['OutputS3Uri'])
 output_bucket_key = splitted_string[1]

 response = s3.get_object(Bucket=BUCKET, Key=output_bucket_key)
 content = response["Body"].read()
 json_output = json.loads(content)
 pp.pprint(json_output)
 print('n')

其中 humanAnswers 键负责提供人工审核员对于各项更改的说明信息。详见以下代码片段:

 'humanAnswers': [ { 'answerContent': { 'Change Reason': 'worst '
 'perimeter '
 'outlier',
 'True Prediction': '0',
 'predicted1': '1',
 'predicted2': '0',
 'predicted3': '0',
 'predicted4': '1',
 'predicted5': '1',
 'rating1': { 'agree': True,
 'disagree': False},
 'rating2': { 'agree': False,
 'disagree': True},
 'rating3': { 'agree': True,
 'disagree': False},
 'rating4': { 'agree': True,
 'disagree': False},
 'rating5': { 'agree': False,
 'disagree': True}},

至此,我们已经可以解析此 JSON 文档以提取相关输出结果,也可以在训练数据集中使用人工审核者提供的输出以重新训练模型,随时间推移不断改善模型推理性能。

资源清理

为避免产生不必要的后续成本,请在不再使用时删除相关资源,例如 Amazon SageMaker 终端节点、Notebook 实例以及模型工件。

总结

本文展示了两个用例,分别通过 Amazon A2I 将表格数据引入人工审核工作流中,且分别对应不可变静态表与动态表。当然,本文对于 Amazon A2I 功能的表述只能算是冰山一角。目前 Amazon A2I 已经在12个 AWS 区域内正式上线,关于更多详细信息,请参阅区域表

关于视频演示、Jupyter notebook 示例以及关于更多其他用例的详细信息,包括文档处理、内容审核、情感分析、文本翻译等,请参阅 Amazon A2I 资源

参考资料

[1] Dua, D. and Graff, C. (2019)。UCI 机器学习库 [http://archive.ics.uci.edu/ml]。加利福尼亚州尔湾市:加州大学信息与计算机科学学院。
image

阅读 1.7k

推荐阅读
AWS_AI开发社区
用户专栏

AWS_AI 开发者社区是专注于人工智能领域 IT 人士交流与互动的平台。在这里,你可以分享和获取一切有关人...

882 人关注
79 篇文章
专栏主页