AWS 人工智能服务的自然语言处理(三)
原文:
annas-archive.org/md5/3ab419d215a27f011904d779022ad3a5译者:飞龙
第十一章:第十一章:使用聊天机器人查询文档
想象一下,如果你能够与文档中的文本数据进行双向对话。假设你订阅了多本期刊,定期收到关于技术趋势的研究文章。这些文章可能涵盖多个行业和技术,但你只对某个特定行业和技术的洞察感兴趣。传统上,你会有一支团队去翻阅这些文档,解读、理解,并推荐你需要采取的方向。如果你可以仅通过拿起手机,与一个聊天机器人对话,获得你需要的答案,而这些答案就来自你的文档库,岂不是太棒了吗?这就是将自然语言处理(NLP)技术与聊天机器人结合的力量。你可以真正和你的文档“对话”,并得到回答。
在上一章中,我们讨论了企业如何依靠技术帮助其国际化扩展,但传统的人工翻译以本地化客户网站既费时又昂贵。因此,我们构建了一个利用机器学习(ML)翻译能力与Amazon Translate相结合的解决方案,高效应对网站本地化挑战。
在本章中,像之前一样,我们将回到我们最喜欢的银行公司,LiveRight Holdings,并帮助他们通过自然语言处理(NLP)和聊天机器人解决一个独特的使用案例。但在我们讨论挑战和解决方案之前,先来谈谈将对话界面(即聊天机器人)与基于文本的文档搜索结合的理念(稍后会详细讲解)。记得我们曾说过,NLP 可以帮助揭示看似无关的文档中的模式,就像阿里巴巴洞中的宝藏一样(第一章,商业环境中的 NLP 与 AWS AI 服务简介——我们知道,感觉像是很久以前的事情了)?如果你有一个像《阿拉丁神灯》中的神灯精灵,根据你的问题提供所需的洞察,岂不是很酷?当我们将 NLP 和聊天机器人结合起来时,就像是让神灯精灵随时按需从阿里巴巴的宝藏洞中分发宝藏。如果你还记得,我们之前确实讨论过如何通过 NLP 创建智能搜索索引,但本章中我们将讨论的解决方案更进一步,使得搜索更加用户友好。为了学习如何构建一个查询文档的聊天机器人,我们将通过以下几个部分进行讲解:
-
介绍聊天机器人使用案例
-
创建一个以Amazon S3 为数据源的Amazon Kendra 索引
-
构建Amazon Lex 聊天机器人
-
使用AWS CloudFormation 部署解决方案
技术要求
本章中,您需要拥有一个AWS 账户。请确保按照第二章《介绍 Amazon Textract》部分中指定的技术要求,创建您的 AWS 账户,并登录到AWS 管理控制台。如果您需要了解如何将对象上传到 Amazon S3 桶中,请参考创建 Amazon S3 桶、文件夹以及上传对象部分。在尝试构建查询文档的聊天机器人步骤之前,请完成这些任务。
在本章中,我们将通过 AWS 管理控制台完成所有任务。GitHub 仓库提供了解决方案所需的输入文档和 FAQ 列表,您可以在此查看:github.com/PacktPublishing/Natural-Language-Processing-with-AWS-AI-Services/tree/main/Chapter%2011。
请使用以下部分的指示来构建解决方案。
介绍聊天机器人用例
现在让我们讨论一下,使用具备自然语言处理(NLP)能力的聊天机器人如何为企业带来益处。通过举例说明总是有帮助的,因此我们回到我们虚构的银行公司LiveRight Holdings Private Limited。LiveRight 公司中的按揭产品研究(MPR)部门对按揭业务至关重要,因为他们的建议直接影响着 LiveRight 提供给客户的按揭产品、特性和选择。这对 LiveRight 的收入和盈利能力有直接影响,因为按揭产品占 LiveRight 年收入的 40%以上。MPR 团队每月都会逐步收到数百份研究文档,这些文档既来自基于订阅的行业分析师,也来自专业的独立研究员。通常,这些文档提供了关于买家在购买房屋时的需求、房地产经纪人的角色、房价对卖家的影响等方面的洞察、趋势报告和详细视角。这些文档被存储到一个 Amazon S3 桶中,该桶已经包含了成千上万的文档,并且还在增长。
MPR 团队的“日常生活”场景是阅读这些大量的文档,分析其内容,识别感兴趣的领域、趋势和指标,并对这些事实进行分类,最终,这些信息会在一天的集体会议活动中被团队共同收集和评估,与过去几个月的统计数据进行比较,最终将建议写下来并发送给高层管理人员,同时将这些信息输入机器学习模型以确定抵押贷款产品特征。文档通常在前一个月的月底或月初收到,团队需要整个月的时间来阅读、分析、分类、讨论并做出建议。LiveRight 的高层管理人员长期以来一直认为这一过程非常耗时且成本高昂,这种看法是正确的。作为一个以经济实用为荣的组织,他们希望通过自动化这一过程来节省时间并降低成本。在看到使用 AWS AI 服务中的 NLP 技术在其他用例中对他们的帮助后,他们联系了你,ML 企业架构师,寻求帮助重新设计这一流程并构建一个高效的解决方案。此外,高层管理人员希望能够利用 MPR 团队中非常有才华的研究人员进行新的创新,而不是让他们浪费时间在琐碎和重复的任务上。
你发现来自 LiveRight 的这个请求既具有挑战性又令人兴奋,因为它是一个完全为 NLP 和 AI 量身定制的用例。你立即决定,帮助 MPR 团队讨论并决定他们的建议的最佳方式是一个智能 AI 助手,它可以参与他们的会议——倾听他们的问题并为他们回答。在经过一些分析后,你决定使用 Amazon Lex(aws.amazon.com/lex/),这是一个完全托管的 AI 服务,通过机器学习模型来构建智能聊天机器人,能够进行语音和文本的互动,并具备持续学习的能力;以及 Amazon Kendra(aws.amazon.com/kendra/),这也是一个完全托管的机器学习驱动的企业搜索服务,利用 NLP 技术为你的文档创建智能索引,接受自然语言查询,并返回精确匹配上下文的响应。你查看了 Amazon Lex 定价(aws.amazon.com/lex/pricing/),发现对于美国东部(北弗吉尼亚)地区每月 8,000 个语音请求和 2,000 个文本请求与聊天机器人的交互,每月只需支付 33.50 美元。你再查看了 Amazon Kendra 定价(aws.amazon.com/kendra/pricing/),发现开发者版支持每天处理 10,000 个文档和 4,000 个查询,价格为每小时 1.125 美元或每月 810 美元。你决定在试点阶段使用开发者版,待用户验收后再升级到企业版。
注意
这些价格截至撰写时是正确的。请检查链接以获取最新数据。
现在您已经准备好构建解决方案了。如前所述,我们将完全使用 AWS 管理控制台(aws.amazon.com/console/)来步行这个解决方案。如果您没有访问 AWS 管理控制台,请按照本书第二章中介绍 Amazon Textract部分中技术要求部分的详细说明进行操作。
首先,在我们继续解决方案构建之前,让我们完成前提条件:
-
从我们的 GitHub 存储库下载样本家庭买家研究文档。从您的本地计算机打开一个互联网浏览器(最好是Google Chrome 版本 9.1及以上),并访问
github.com/PacktPublishing/Natural-Language-Processing-with-AWS-AI-Services/tree/main/Chapter%2011。 -
逐个点击文档名称下载每个四个文档。
-
在文档页面上,点击右侧的下载按钮将文档下载到您的计算机上。
-
按照本书第二章中创建 Amazon S3 桶、文件夹和上传对象部分的说明,将这些下载的文档上传到 Amazon S3 桶。在创建桶中的 Amazon S3 文件夹时,请使用以下文件夹/前缀路径 –
chapter11/kendra-faq/faqs.csv、chapter11/kendra/2019-NAR-HBS.pdf、chapter11/kendra/2020-generational-trends-report-03-05-2020.pdf、chapter11/kendra/Zillow-home-buyers-report.pdf。 -
现在,你已经准备好开始构建解决方案了。
在本节中,我们介绍了使用 NLP 的聊天机器人的需求以及与此解决方案相关的商业利益。在接下来的部分中,我们将逐步介绍解决方案的构建过程。
使用 Amazon S3 作为数据源创建 Amazon Kendra 索引
在本节中,我们将首先创建一个 Amazon Kendra 索引,并将我们在上一节中上传的样本研究文档的 S3 存储桶添加为 Amazon S3 数据源。
注意
在继续之前,请确保您已经执行了技术要求部分和介绍聊天机器人使用案例部分中提到的先决条件。
请执行以下步骤创建您的 Amazon Kendra 索引:
-
如果尚未完成,请按照本书第二章中介绍 Amazon Textract部分中技术要求部分的详细说明登录到您的AWS 管理控制台。
-
在页面顶部中央的服务搜索栏中输入
kendra并从列表中选择Amazon Kendra。当Amazon Kendra控制台打开时,点击创建索引,如图所示:图 11.1 – 创建亚马逊 Kendra 索引
-
在指定索引详细信息页面中,输入索引的名称,添加可选描述,从IAM 角色列表框中选择创建新角色(推荐),并输入角色名称,如下截图所示。然后点击下一步继续:
图 11.2 – 指定索引详细信息
-
在配置用户访问控制页面中保持默认选择,并点击下一步继续。
-
在指定配置页面中,保持默认选择,指向开发者版,然后点击创建。亚马逊 Kendra 将开始创建索引的工作。可能需要大约 15 到 30 分钟,因此您可以在此期间享用一些零食和咖啡/茶。
-
索引成功创建后,点击添加数据源按钮继续。
-
在向 Amazon Kendra 索引添加数据源连接器页面中,向下滚动并点击添加连接器,位于选择数据源连接器类型下的Amazon S3卡片中。
-
在指定数据源详细信息页面中,输入数据源名称并点击下一步。
-
在
chapter11/kendra中,点击添加按钮:图 11.3 – 配置同步设置
-
现在,向下滚动页面,找到IAM 角色信息,在IAM 角色列表框中选择创建新角色(推荐)并输入您选择的角色名称。在同步运行计划信息中,选择按需运行作为频率。点击下一步继续。
图 11.4 – 数据源同步设置 IAM 角色和运行计划
-
审核您的输入并点击添加数据源。亚马逊 Kendra 将首先传播 IAM 角色,然后创建数据源。
-
数据源创建后,点击立即同步按钮,开始为我们的文档建立索引,以便搜索。
-
同步大约需要 30 分钟(时间可以用来休息)。完成后,您可以查看同步运行历史。
-
现在,我们将向索引添加一些常见问题解答(FAQ),以便为搜索添加更多背景信息。从左侧窗格中的数据管理标题下选择常见问题解答选项,然后点击添加常见问题解答。
-
在介绍聊天机器人使用案例部分的前提步骤中输入
faqs.csv文件。在IAM 角色中,选择创建新角色(推荐)并输入您选择的角色名称。向下滚动并点击添加。 -
亚马逊 Kendra 将开始 FAQ 任务,几分钟后应该完成。
我们现在已完成使用 Amazon Kendra 设置智能搜索所需的步骤。在下一部分,我们将构建创建 Amazon Lex 聊天机器人的步骤。
构建 Amazon Lex 聊天机器人
在本节中,我们将执行构建 Amazon Lex 聊天机器人的步骤,并使用内置的意图(这是机器人基于用户请求执行的任务)将我们的聊天机器人与前一节中创建的 Amazon Kendra 索引集成。请按以下步骤执行:
-
在 AWS 管理控制台中,在页面顶部中央的服务搜索框中输入
lex,并从列表中选择Amazon Lex以进入 Amazon Lex 控制台。在 Amazon Lex 控制台的左侧窗格中,点击切换到新的 Lex V2 控制台链接,如下图所示:图 11.5 – 切换到新的 Lex V2 控制台
-
在 Lex V2 控制台页面上,点击右侧的创建机器人,如图所示:
图 11.6 – 创建机器人
-
在
HomeBuyerResearch中,为Bot 名称,在IAM 权限部分,选择创建具有基本 Amazon Lex 权限的角色作为运行时角色。图 11.7 – 配置机器人设置
-
向下滚动至
5,并为空闲会话超时选择分钟数,然后点击页面右下角的下一步。 -
在为机器人添加语言页面,保持选择语言为英语(美国),并在语音交互列表框中选择Joanna。点击页面右下角的完成。
-
当机器人创建完成后,Amazon Lex 将自动添加一个名为
NewIntent的意图来启动机器人构建过程。图 11.8 – Lex 添加的 "NewIntent"
-
向下滚动到页面底部的
新意图的发话内容,点击NewIntent,这是一个自定义意图(在构建机器人时是必需的),并通过提供一个在与机器人交互时不会使用的发话内容来使其不可解析。这样可以强制将解析转到我们的 Amazon Kendra 内置意图。 -
向下滚动并点击页面右下角的保存意图。
-
现在,让我们返回到意图列表。点击返回到意图列表,它位于Amazon Lex标题下的左上方。
-
在意图页面上,点击右侧的添加意图,并选择使用内置意图,如下图所示:
图 11.9 – 添加内置意图
-
在列表框中的
kendra中,选择AMAZON.KendraSearchIntent。图 11.10 – Amazon Kendra 为 Lex 提供的内置意图
-
在
ResearchBuyers中,以及在chapter11-houses-index中(如果你使用了书中提到的相同名称),点击添加。 -
向下滚动到消息字段中的
Here is what I found for your query:((x-amz-lex:kendra-search-response-answer-1)),点击保存意图。保存意图后,点击更多响应选项。 -
在消息字段中的
I found a FAQ question for you: ((x-amz-lex:kendra-search-response-question_answer-question-1)) and the answer is ((x-amz-lex:kendra-search-response-question_answer-answer-1)),点击更新响应。再次点击保存意图。图 11.11 – 添加文本消息组图 11.11 – 添加文本消息组
-
现在,滚动到页面顶部,点击蓝色导航链接中的语言:英语(美国)。
-
向下滚动并点击页面右下角的构建按钮。这大约需要几分钟时间,但不会超过。
-
当机器人完全构建完成后,点击页面底部构建按钮旁边的测试按钮。
-
在输入框中输入
Who is a first-time buyer?,然后按Enter键。 -
机器人使用我们添加到亚马逊 Kendra 索引中的文档中的答案进行响应:图 11.12 – 机器人响应查询,内容来自示例研究文档
图 11.12 – 机器人响应查询,内容来自示例研究文档
-
现在,滚动到页面顶部,点击蓝色导航链接中的版本。
-
在版本页面,点击右侧的创建版本按钮。
-
向下滚动到页面底部,点击创建按钮。
-
新版本已成功为我们的机器人创建。记下创建的版本号,我们在接下来的步骤中将需要它。
-
现在,在左侧面板中找到部署标题,点击别名,
-
点击
hbr-web-ui。向下滚动,选择在前一步创建的机器人版本,点击选择一个现有版本,然后点击页面右下角的创建按钮。注意
如果你是第一次创建版本,请选择会显示给你的版本 1。
-
创建别名后,请记下我们的机器人别名 ID。在下一节部署机器人时需要用到这个 ID。
-
同时,点击页面顶部蓝色导航链接中的机器人名称,并记下你的机器人 ID——我们在部署时也需要这个。
这就是构建我们 Amazon Lex 聊天机器人的全部内容。在下一部分,我们将使用 AWS CloudFormation (aws.amazon.com/cloudformation/),这是一项托管服务,允许我们将基础设施配置任务写成JSON或YAML模板代码,从而自动化我们在 AWS 上构建解决方案所需的资源部署。由 Oliver Atoa 和 Bob Strahan 撰写的 Amazon Lex 博客文章《为你的聊天机器人部署 Web 用户界面》提供了一个 AWS CloudFormation 模板示例,用于将 Amazon Lex 聊天机器人集成到网站中:aws.amazon.com/blogs/machine-learning/deploy-a-web-ui-for-your-chatbot/。
我们将使用此模板创建一个网站,并将聊天机器人嵌入为小部件。
使用 AWS CloudFormation 部署解决方案
在前面两个部分中,我们逐步展示了如何使用 Amazon Kendra 创建索引并将来自 Amazon S3 存储桶的文档作为数据源,以及如何构建 Amazon Lex 聊天机器人并通过内置意图将其与我们的 Amazon Kendra 索引集成。这完成了我们解决方案构建的大部分内容。在这一部分,我们将使用来自附带仓库的 AWS CloudFormation 模板示例,这个仓库是我们在上一部分中提到的博客文章:github.com/aws-samples/aws-lex-web-ui/tree/master/templates。
让我们开始吧:
-
点击
github.com/aws-samples/aws-lex-web-ui/tree/master/templates,并向下滚动到网页上的Launch部分,点击第一个Launch Stack按钮以启动CodeBuild 模式。图 11.13 – 启动 AWS CloudFormation 堆栈
-
该操作将打开 AWS CloudFormation 服务,进入 AWS 管理控制台,并带你到创建堆栈页面。点击下一步。
-
为堆栈名称和CodeBuildName输入一个你选择的名称,或者使用提供的示例。
-
向下滚动到名为
en_US的部分。图 11.14 – 创建堆栈,Lex V2 机器人配置参数
-
向下滚动到
true。这将强制用户注册Amazon Cognito (aws.amazon.com/cognito/),这是一个完全托管的用户身份验证和授权服务,适用于 Web 和移动应用程序。注册后,用户可以使用他们的凭证登录网站以访问聊天机器人。 -
向下滚动一点,提供一个CognitoIdentityPoolName的名称。
-
滚动到
You can ask me questions on home buyers. For example – what is important for home buyers?,该内容位于Say 'what is important for home buyers' to get started的WebAppConfBotInitialSpeech字段中。当点击麦克风图标时,机器人会通过语音提示用户这一信息。 -
向下滚动一点,找到
ResearchHomeBuyers。然后,点击下一步。 -
在此页面上,保持默认设置不变,点击页面底部的下一步。
-
向下滚动到功能部分,选择两个复选框以确认创建 IAM 资源,并且可能需要自动扩展的能力。点击创建堆栈。
-
创建我们所需的所有资源可能需要大约 15 分钟。有关将要创建的资源的详细信息,请参阅以下链接:
github.com/aws-samples/aws-lex-web-ui/blob/master/templates/README.md#cloudformation-resources。 -
当 CloudFormation 堆栈的状态更改为
Create_Complete时,我们所需的资源已经配置完毕。在启动我们的网站之前,我们需要对父网站进行修改,以确保它发送正确的语言表达给我们的聊天机器人。点击您的 CloudFormation 堆栈的输出标签,查看已配置资源的列表。复制名为WebAppBucket的键的值。这是用于托管您网站的 Amazon S3 存储桶的名称:图 11.15 – 托管我们网站的 S3 存储桶
-
现在,进入您的
S3,并从列表中点击parent.html。 -
在
parent.html中,点击parent.html并将其下载到您的计算机:图 11.16 – 下载 parent.html
-
在您喜欢的文本编辑器中打开
parent.html,并将 panel-heading 标签的值更改为Send "what is important for buyers" utterance to iframe,如以下截图所示。要找到该条目,请搜索Buy Flowers。图 11.17 – 更改 parent.html 中的 panel-heading 标签
-
继续搜索
Buy Flowers,并将sendUtterance函数的参数更改为'what is important for buyers?',如以下截图所示:图 11.18 – 更改发送语言表达函数输入
-
现在,返回您的 Amazon S3 控制台,打开
parent.html,点击上传,然后点击添加文件。 -
从您的本地计算机选择修改后的
parent.html,向下滚动并点击上传。 -
CloudFormation 堆栈配置的资源之一是 CloudFront 分发。点击 CloudFront,在列表中点击 CloudFront 以进入 Amazon CloudFront 控制台:
图 11.19 – 导航至 Amazon CloudFront 控制台
-
在 CloudFront 分发 页面中,检查 Origin 字段。您应该能在此看到一个条目,它的名称与您从 CloudFormation 堆栈的 Outputs 选项卡中复制的 WebAppBucket 值匹配。点击此条目的 ID。
-
在 CloudFront 分发的详细信息页面中,点击 Invalidations 选项卡以打开它。然后,点击 创建无效化 按钮。
图 11.20 – 为 CloudFront 分发创建无效化
-
在 Object Paths 字段中的
/处点击 无效化,如下截图所示。这个过程大约需要 5 分钟左右:图 11.21 – 无效化 CloudFront 分发
-
无效化完成后,返回 Amazon CloudFormation 控制台中的堆栈 Outputs 选项卡,点击 ParentPageUrl 值:
图 11.22 – 点击 ParentPageUrl 值
-
这将启动您配置的网站,并展示您的聊天机器人。但在使用聊天机器人之前,Amazon Cognito 会强制您登录到网站,如下所示。如果这是您第一次访问该网站,请点击 注册 按钮并按照提示进行注册:
图 11.23 – 注册或登录到您的网站
-
注册过程完成后,您将收到一封包含验证码的邮件。输入验证码即可登录:
图 11.24 – 输入验证码
-
登录后,您的网站及其作为小部件的聊天机器人将显示出来。点击 发送 按钮将第一次输入的语句发送给机器人。您可以输入后续问题:
图 11.25 – 与嵌入在主网站中的 Amazon Lex 聊天机器人小部件进行文本交互
-
点击聊天小部件中的麦克风按钮与机器人对话。机器人会用语音回应,如下图所示。接受浏览器的通知,允许它使用麦克风继续操作。
图 11.26 – 与您的聊天机器人进行语音交互
这就完成了本章的解决方案构建。请随时尝试这个解决方案并给我们反馈。你可以根据自己的需求轻松地定制我们在本章中构建的内容。有关如何利用 Amazon Kendra 和 Amazon Lex 满足你需求的更多想法,请参考进一步阅读部分。
总结
在本章中,我们使用 Amazon Kendra 构建了一个解决方案,用于自动搜索并从文档语料库中提取洞察,无需手动阅读文档、理解上下文、解释含义、识别跨文档与共同主题相关的内容等等。我们还展示了如何使用 Amazon Lex 设置一个智能的基于 AI 的聊天助手,该助手隐式集成了 Amazon Kendra 的智能搜索功能,提供了一个无缝的聊天和语音界面,用于(字面上)“与文档对话”。最后,我们使用 AWS CloudFormation 的最佳实践方法将我们的聊天机器人部署到父网站作为嵌入式小部件,并通过 Amazon CloudFront 内容分发网络进行了分发。
有趣的是,NLP 在医学领域有着多种应用,正如我们在下一章中将看到的那样,在那里我们将回顾 NLP 和 AI 技术如何帮助转变现代医疗索赔处理。我们将从讨论如何自动从医疗接收表单中提取数据开始,如何使用Amazon Comprehend Medical (aws.amazon.com/comprehend/medical/)理解临床数据,以及如何为医疗索赔的裁定设置无服务器的实时管道。如之前所述,我们将介绍使用案例,讨论如何设计架构,建立前提条件,并详细讲解构建解决方案所需的各种步骤。
进一步阅读
-
通过 Amazon Kendra 增强企业搜索,作者:Leonardo Gomez:
aws.amazon.com/blogs/machine-learning/enhancing-enterprise-search-with-amazon-kendra/ -
Citibot 的聊天机器人搜索引擎如何利用 AI 找到更多答案,作者:Francisco Zamora、Bratton Riley 和 Nicholas Burden:
aws.amazon.com/blogs/machine-learning/how-citibots-chatbot-search-engine-uses-ai-to-find-more-answers/ -
使用 Amazon Connect、Amazon Lex、Amazon Kendra 以及开源 QnABot 项目构建全渠道问答聊天机器人,作者:Bob Strahan 和 Michael Widell:
aws.amazon.com/blogs/machine-learning/building-a-multi-channel-qa-chatbot-with-amazon-connect-amazon-lex-amazon-kendra-and-the-open-source-qnabot-project/?nc1=b_rp
第十二章:第十二章:医疗行业中的 AI 和 NLP
在上一章中,我们讨论了如何使用 AWS AI 服务,通过Amazon Lex和Amazon Kendra为您的文档工作流设置聊天机器人。在这一章中,我们将讨论Amazon Textract和Amazon Comprehend Medical如何帮助数字化医疗索赔。我们将讨论医疗行业的索赔处理系统,以及为什么自动化医疗索赔如此重要。接着,我们将引导您如何使用 Amazon Textract 将这些纸质索赔数字化,并使用后处理进行验证。然后,我们将展示如何使用 Amazon Comprehend Medical API 从这些索赔中提取 NLP 洞察,例如判断个人是否患有糖尿病。
对于无效的索赔,我们将向您展示如何轻松设置通知,以提醒提交索赔的人重新提交正确数据,如邮政编码或索赔 ID。最后,我们将向您展示一些架构模式,帮助您使用 AWS Lambda 函数自动化所有流程。通过这种方式,您将创建一个端到端的无服务器解决方案,从而缩短索赔处理工作流的市场时间。这是因为您无需设置和管理服务器,也无需扩展以处理数百万个此类索赔。
本章将涵盖以下主题:
-
介绍自动化索赔处理的使用案例
-
理解如何从医疗入院表单中提取和验证数据
-
理解使用 Amazon Comprehend Medical 的临床数据
-
理解无效医疗表单处理及通知
-
理解如何为医疗索赔创建无服务器管道
技术要求
本章需要您访问一个 AWS 账户:
-
请确保按照第二章中的技术要求部分的说明,创建您的 AWS 账户。
-
在尝试提高文档处理工作流准确性部分的步骤之前,请登录 AWS 管理控制台。
我们解决方案的 Python 代码和示例数据集可以在github.com/PacktPublishing/Natural-Language-Processing-with-AWS-AI-Services/tree/main/Chapter%2012找到。请使用以下章节中的说明,并结合前面仓库中的代码来构建解决方案。
查看以下视频,了解代码的实际应用:bit.ly/3GrClSK。
介绍自动化索赔处理的使用案例
根据2018 CAHQ 指数报告(www.caqh.org/sites/default/files/explorations/index/report/2018-index-report.pdf),2018 年,医疗行业共提交了约 61 亿个医疗理赔,预计这一数字在未来几年将继续增长。
医疗支付公司不断寻找高效且具有成本效益的方式,以可扩展的方式处理如此大量的理赔。由于当前理赔处理的手工流程,处理这些理赔需要花费大量时间。因此,医疗公司正在寻找使用 AI 和机器学习方法来自动化和数字化这些理赔。一旦他们能够将这些理赔数字化,就能够轻松推动一些洞察力,比如改善整体人群健康。此外,分析这些理赔文件可能有助于你发现一些行为,帮助预防某些医疗状况的发生。同时,医疗支付方也在寻找符合法规的解决方案,如HIPAA 合规。对于美国以外的朋友,HIPAA 是美国医疗行业特定的合规法律。
现在,我们理解了为什么自动化理赔如此重要。接下来,我们将讨论如何帮助你使用 AWS AI 服务,如 Amazon Textract,来自动化这一流程,数字化理赔处理。你可以通过从这些扫描的理赔文件中提取文本,并使用自然语言处理(NLP)和 Amazon Comprehend Medical 来验证它们,从中获取一些患者健康洞察。
在这个用例中,我们的虚构公司LiveRight Holdings Private Limited与一家名为AwakenLife的医疗保险提供商合作,处理由他们的保险持有人提交的理赔。这些理赔大多数是扫描图像,他们的大部分时间和精力都花费在处理这些理赔上,因为其中一些是无效的。这给组织带来了损失。由于 LiveRight 公司已经在前几章中使用了 Amazon Textract 来自动化、数字化并进一步创新他们的文档处理工作流,他们推荐使用AwakenLife,这样他们就可以利用一些 AWS AI 服务来改善和自动化他们的整体理赔流程。在本章中,我们将设置一个简单的基于 AI 的工作流来验证 AwakenLife 的理赔,从而进一步减少他们的整体处理时间。
这个解决方案具有高度的成本效益和可扩展性,因为这些服务是无服务器的,并且可以根据你的需求扩展来处理文档。在本章中,我们将向你展示以下架构:
图 12.1 – 用于笔记本的医疗理赔处理架构
在前面的图表中,我们可以看到以下内容:
-
您的医疗接待表单可以是图像或 PDF 格式,并且会被发送到 Amazon Textract 进行数字化或文本提取。
-
Amazon Textract 从这些高度非结构化的医疗接待文档中提取文本。
-
您必须对 Amazon Textract 的响应进行 后处理,以验证索赔。对于本博客,我们使用邮政编码和索赔 ID 来确保索赔的有效性。您可以根据您的业务案例自定义这些验证规则。
-
一旦邮政编码和索赔 ID 被验证,合法的数据将被发送到 Amazon Comprehend Medical,以获得关于患者程序等的洞察和实体。
-
如果邮政编码和索赔 ID 无效,将向相关人员发送电子邮件,通知他们这是一个无效的索赔。
我们将使用 Jupyter 笔记本来演示之前的架构。一旦完成这部分内容,我们将介绍如何使用基于事件的 Lambda 函数自动化实现该架构。
在下一部分中,我们将讨论如何使用 Amazon Textract 从医疗接待表单中提取数据。
理解如何从医疗接待表单中提取和验证数据
在这一部分中,我们将展示如何使用 Amazon Textract 从医疗接待表单中提取关键值对或表单数据。然后,通过简单的逻辑,您将验证提取的值是否有效或无效。
如果您在之前的章节中没有这样做,您需要创建一个 Amazon SageMaker Jupyter 笔记本,并设置 Chapter 12 文件夹,打开 ch 12 automating claims processing.ipynb 笔记本。
注意:
确保笔记本中的 IAM 角色具备 AmazonSNSFullAccess、AmazonComprehendMedicalFullAccess 和 AmazonTextractFullAccess 权限。
现在,使用这个笔记本,我们将学习如何使用 Textract API 提取数据,并通过一个示例医疗接待表单使用一些后处理逻辑进行验证:
-
我们将使用以下示例医疗接待表单开始。运行以下代码块加载示例医疗表单,这是一份有效的索赔医疗表单:
documentName = "validmedicalform.png" display(Image(filename=documentName))您将看到以下医疗接待表单已经加载:
def calltextract(documentName): client = boto3.client(service_name='textract', region_name= 'us-east-1', endpoint_url='https://textract.us-east-1.amazonaws.com') with open(documentName, 'rb') as file: img_test = file.read() bytes_test = bytearray(img_test) print('Image loaded', documentName) response = client.analyze_document(Document={'Bytes': bytes_test}, FeatureTypes=['FORMS']) return response -
至此,我们已经定义了一个 Textract 函数。现在,我们将通过传递扫描的医疗接待表单来调用此函数,并获取 Textract 响应。运行以下单元格:
response= calltextract(documentName) print(response)如果 Textract 的响应成功,您将收到以下消息,并附有提取数据的 JSON 响应:
图 12.3 – 医疗表单的 Textract JSON 响应
前面的响应包含了大量信息,例如几何、页面以及文档元数据中的文本。
-
现在,我们将创建一个函数来解析从此 JSON 响应中提取的表单数据或键值文本响应。我们使用 Textract 解析器来解析此 JSON 响应。在这里,我们创建了一个方法,它接受一个 JSON 响应并使用 Textract 解析器解析表单键值并返回键值对:
from trp import Document def getformkeyvalue(response): doc = Document(response) key_map = {} for page in doc.pages: # Print fields for field in page.form.fields: if field is None or field.key is None or field.value is None: continue key_map[field.key.text] = field.value.text return key_map -
现在,我们将把 Textract 的 JSON 响应传递给
def getformkeyvalue(response)方法,以从 Textract JSON 响应中获取键值对或表单数据:get_form_keys = getformkeyvalue(response) print(get_form_keys)你将得到如下输出:
](tos-cn-i-73owjymdk6/c78c2cc36be54d608913c539a5bbdcfb)
图 12.4 – 从 JSON 响应解析的 Textract 表单数据
所有表单项都作为键值对提取。
-
现在,我们将使用一些定义好的业务规则检查这些键值对或表单项是否有效。对于本书来说,我们通过有效的邮政编码和索赔 ID 来检查表单的有效性。你也可以根据自己的业务需求修改验证代码。我们创建了一个方法,它接受键值对并检查从 Textract 提取的邮政编码或 ID 号码信息是否有效。如果有效,它将返回所需的 ID,如果无效,它将返回一条消息,说明索赔 ID 和邮政编码无效:
def validate(body): json_acceptable_string = body.replace("'", "\"") json_data = json.loads(json_acceptable_string) print(json_data) zip = json_data['ZIP CODE'] id = json_data['ID NUMBER'] if(not zip.strip().isdigit()): return False, id, "Zip code invalid" length = len(id.strip()) if(length != 12): return False, id, "Invalid claim Id" return True, id, "Ok" -
现在,我们将通过发送从
getformdata(response)方法提取的键值对来测试这种验证方法是否适用于有效的医疗表单:textract_json= json.dumps(get_form_keys,indent=2) res, formid, result = validate(textract_json) print(result) print(formid) -
由于这是有效的索赔,邮政编码和索赔 ID 都是有效的,因此此方法返回有效的响应(有效的响应):
](tos-cn-i-73owjymdk6/6b60b674e5c44129a2d4408763385129)
图 12.5 – 有效的索赔响应
正如你所看到的,我们得到了一个Ok响应,并附带有效的索赔 ID。
现在,回到架构,有两种情况可能发生:
-
如果表单有效或此方法的响应是
Ok,我们将把这些数据发送到 Comprehend Medical 以获得洞察,这将在下一节中讲解。 -
如果表单无效,我们将使用 Amazon Simple Notification Service(SNS)通知客户,该服务用于发送电子邮件或电话通知。我们将在最后一节中讨论这个内容,理解如何为医疗索赔创建无服务器管道。
在本节中,我们介绍了如何使用 Amazon Textract Analyze Document API 从医疗接收表单中提取表单值。我们还讨论了如何验证 Textract 响应。
由于响应对于医疗接收表单有效,在下一节中,我们将向你展示如何使用 Amazon Comprehend Medical 提取医疗洞察。
使用 Amazon Comprehend Medical 理解临床数据
在本节中,我们将讨论如何使用Amazon Comprehend Medical从有效的医疗接收表单中获取洞察。我们在第三章中介绍了 Amazon Comprehend 的功能,介绍 Amazon Comprehend。在本章中,我们将学习如何使用 Amazon Comprehend Medical Entity API 提取诸如患者诊断和个人健康信息(PHI)数据类型,如申诉 ID等医疗接收表单中的实体。让我们开始吧:
-
回到您的笔记本并运行以下单元格,使用 Comprehend Medical
boto3API:comprehend = boto3.client(service_name='comprehendmedical') -
现在,我们将使用
comprehend.detect_entities_v2API (docs.aws.amazon.com/comprehend/latest/dg/API_medical_DetectEntitiesV2.html) 来分析来自医疗接收表单的临床文本数据,并返回与医疗文本相关的实体,如类型或诊断。运行以下单元格查看我们从有效医疗接收表单中提取的实体:cm_json_data = comprehend.detect_entities_v2(Text=textract_json) print("\nMedical Entities\n========") for entity in cm_json_data["Entities"]: print("- {}".format(entity["Text"])) print (" Type: {}".format(entity["Type"])) print (" Category: {}".format(entity["Category"])) if(entity["Traits"]): print(" Traits:") for trait in entity["Traits"]: print (" - {}".format(trait["Name"])) print("\n")您将使用此 API 获得以下医疗洞察:
图 12.6 – 医疗实体
它能够将电话号码和医疗 ID 识别为个人健康信息(PHI)。如果您有合规要求,您可以轻松地屏蔽或删除这些实体类型,因为它们已经被该 API 正确识别。
-
现在我们已经提取了实体,我们将把这些提取的数据保存在 Amazon S3 中的 CSV 文件里。对于大规模的医疗接收表单处理,您会希望将所有这些洞察保存在 CSV 文件中,放入 S3 桶中,并使用分析服务进行分析,如我们在第八章中介绍的,利用 NLP 将您的媒体内容货币化。我们已经创建了一个函数,该函数接受 Comprehend Medical 的响应和来自医疗接收表单的验证 ID,并将其保存到 Amazon S3 中。运行以下代码:
def printtocsv(cm_json_data,formid): entities = cm_json_data['Entities'] with open(TEMP_FILE, 'w') as csvfile: # 'w' will truncate the file filewriter = csv.writer(csvfile, delimiter=',', quotechar='|', quoting=csv.QUOTE_MINIMAL) filewriter.writerow([ 'ID','Category', 'Type', 'Text']) for entity in entities: filewriter.writerow([formid, entity['Category'], entity['Type'], entity['Text']]) filename = "procedureresult/" + formid + ".csv" S3Uploader.upload(TEMP_FILE, 's3://{}/{}'.format(bucket, prefix)) -
现在,我们将通过传递 Comprehend Medical Entity API 的 JSON 响应和来自验证逻辑的
formid,调用printtocsv(cm_json_data,formid)方法:printtocsv(cm_json_data,formid)您将获得以下响应:
"successfully parsed:procedureresult/a-184054-6661.csv"
在本节中,我们介绍了如何使用 Amazon Comprehend Medical API 提取来自 Amazon Textract 的有效申诉中的医疗洞察或实体。在下一节中,我们将使用 Amazon Textract 提取一个无效申诉表单的数据,并对这些数据进行后处理以检查其有效性。如果无效,我们将向您展示如何设置 SNS,通过电子邮件通知相关方。
了解无效医疗表单处理及通知
在本节中,我们将讲解当 Textract 后处理识别为无效时,如何按照图 12.1中指定的架构进行操作。我们将通过 Amazon SNS 向相关方发送消息。现在让我们回到笔记本:
-
在笔记本中,我们将通过运行以下代码开始加载扫描的医疗入院表单:
InvalidDocument = "invalidmedicalform.png" display(Image(filename=InvalidDocument))你将得到以下示例医疗表单,我们将检查其中的无效用例:
图 12.7 – 医疗入院无效索赔表单
在此表单中,邮政编码和身份证号码输入错误。
-
现在,我们将调用之前章节中创建的
calltextract(document)函数,并传入该文档以使用 Amazon Textract Sync API 提取文本或数据。为此,请运行以下代码:response = calltextract(InvalidDocument) -
在此之后,我们将调用在前面章节中定义的
getformdata(response)方法,该方法以 Textract 的响应作为输入,并返回表单的键值数据:get_form_keys = getformkeyvalue(response) print(get_form_keys)你将得到以下输出:
图 12.8 – 使用 Textract 提取的表单数据
在这里,我们获取了所有的键值对或表单数据。
-
现在,我们将通过将提取的键值对,如
邮政编码和身份证号码,作为输入传递给前面章节中定义的validate(body)方法来检查其有效性。如果内容有效,该方法返回 true;如果提交的邮政编码和身份证号码无效,则返回 false:textract_json= json.dumps(get_form_keys,indent=2) res, formid, result = validate(textract_json) print(result) print(formid) print(res)你将得到以下响应:
图 12.9 – 无效索赔响应
有效的方法返回一个无效的索赔和
false,以及无效的索赔 ID。 -
现在,我们想通知用户此索赔无效。为此,我们将引导你如何通过 Amazon SNS 控制台设置Amazon SNS。请访问此链接创建一个主题,在该主题中发布无效消息:
console.aws.amazon.com/sns/v3/home?region=us-east-1#/create-topic。 -
对于
invalid-claims-notify,如以下截图所示:图 12.10 – 在 SNS AWS 控制台创建主题
确保选择标准主题类型。
-
向下滚动并点击创建主题按钮。
-
创建主题后,我们必须添加订阅者或将要订阅此主题以接收通知的人,方法是访问
console.aws.amazon.com/sns/v3/home?region=us-east-1#/create-subscription。 -
从下拉菜单中选择你的主题 ARN,设置协议为电子邮件,并在终端框中输入你的电子邮件 ID,如以下截图所示:
图 12.11 – 通过电子邮件订阅主题
向下滚动并点击创建订阅。
-
一封电子邮件将发送到你刚刚用于订阅的地址。请检查你的邮箱或垃圾邮件,查看来自 SNS 的电子邮件,邮件主题为 AWS 通知 - 订阅确认,点击 确认订阅。
注意:
确认订阅非常重要,否则你将无法收到通知。
-
现在,返回
console.aws.amazon.com/sns/v3/home?region=us-east-1#/topics复制invalid-claims-notify:图 12.12 – 从 AWS 控制台复制主题的 ARN
-
复制此 ARN 后,返回到笔记本,并将其粘贴到以下笔记本单元格中,以加载 SNS
boto3客户端。在这里,输入一个主题:sns = boto3.client('sns') topicARN="<Enter your topic arn>" -
现在,我们将把无效信息转换为负载,并发布到此主题:
snsbody = "Content:" + str(textract_json) + "Reason:" + str(result) print(snsbody) -
接下来,我们将使用
sns.publishPythonboto3API (boto3.amazonaws.com/v1/documentation/api/latest/reference/services/sns.html#SNS.Client.publish),将无效电子邮件信息发送到已注册的电子邮件地址:try: response = sns.publish( TargetArn = topicARN, Message= snsbody ) print(response) except Exception as e: print("Failed while doing validation") print(e.message)你将收到如下响应:
图 12.13 – 将无效索赔信息推送到主题
-
检查你订阅时使用的电子邮件地址,查看是否有通知无效医疗索赔的电子邮件:
图 12.14 – 发送的电子邮件通知
你可以随时选择退出你创建的主题。
在本节中,我们讲解了如何使用 Amazon Textract 处理医疗索赔,检查无效医疗索赔,并通知相关方。接下来,我们将学习如何为医疗索赔创建一个无服务器管道。
理解如何为医疗索赔创建无服务器管道
在前面的章节中,我们通过使用 Amazon Textract Sync API、Amazon Comprehend Medical Detect Entities Sync API 和 Amazon SNS 发送无效索赔,讲解了架构的构建模块。我们为此工作流定义了函数,并调用了文本提取和验证函数,展示了有效和无效医疗索赔表单的用例或工作流。这些函数可以移入 Lambda 代码中,并与 S3 事件通知 一起被触发,用于创建一个可扩展的医疗索赔处理管道。我们可以通过以下架构来实现:
图 12.15 – 使用 AWS Lambda 自动化扩展架构
我们通过一个 Jupyter 笔记本,展示了使用单一接收表单处理医疗理赔的各个代码组件。我们创建了 Python 函数来提取数据、验证数据、收集洞察,并将这些洞察转换为 CSV 文件。为了处理数百万这样的文档,我们将学习如何将代码函数转换为 AWS Lambda 函数,利用前面的架构图创建一个端到端的自动化无服务器架构。我们将使用的医疗理赔表单已由AwakenLife Ltd的付款方上传到 Amazon S3 存储桶:
-
Amazon S3 声明上传会触发一个 Amazon S3 事件通知,进而触发 lambda 函数。
-
在这个 lambda 中,你可以调用我们在理解如何从医疗接收表单中提取和验证数据部分定义的
textract函数,并通过传递该图像作为输入来调用 Amazon Textract。 -
你会收到一个文本响应。这些提取的文本可以被发送到我们在前一节中定义的
validation函数。 -
对于有效的理赔,验证过的数据将发送到 Amazon Comprehend Medical 以提取洞察。提取的洞察将被返回给 AWS Lambda。
-
你可以将我们在使用 Amazon Comprehend Medical 理解临床数据部分定义的
printtocsv(cm_json_data,formid)函数代码移到这个 lambda 函数中,将提取的洞察转换为 CSV 文件,并将其保存到 Amazon S3。 -
对于无效的理赔,你可以使用 SNS 通知相关方。
我们可以通过几行代码,在大规模处理医疗理赔文档时使用扩展性和流程化的方式。这种架构可以快速实现自动化,并以CloudFormation 模板的形式进行部署,从而让你能够设置基础设施即代码(IaC)。如果你有兴趣,我们已经在进一步阅读部分提供了一个类似的可扩展实现,以博客的形式呈现。
在本节中,我们讲解了如何使用我们在前面各节中定义的代码,并将其移至 AWS Lambda 部分,以构建一个使用逐步架构的端到端自动化工作流。现在,让我们总结一下这一章。
总结
在本章中,我们介绍了医疗理赔处理的使用案例。然后,我们讨论了如何使用 AWS AI 服务,如 Amazon Textract 来从这些扫描的医疗表单中提取表单数据。接着,我们讨论了如何根据您的业务规则对提取的文本进行一些后处理,以验证其表单数据。一旦表单数据经过验证,我们向您展示了如何使用 Amazon Comprehend Medical 来提取医疗见解,正如在第三章,介绍 Amazon Comprehend中所涵盖的那样。一旦您获得了医疗见解,这些数据可以转换为 CSV 文件并保存在 Amazon S3 中。完成这些步骤后,您可以使用Amazon Athena或Amazon QuickSight来分析这些数据以进行人口健康分析。我们还讨论了如何通过显示如何快速通过 AWS 控制台配置 Amazon SNS 并添加订阅者来处理无效理赔。您可以通过电子邮件通知您的订阅者提交的无效医疗索赔。
最后,我们向您展示了如何使用 AWS Lambda 架构一个无服务器可扩展解决方案,以调用这些 Textract Sync 和 Amazon Comprehend Medical Sync API。这确保了您在 Amazon S3 中上传的理赔文档具有端到端的自动化工作架构。
在下一章中,我们将介绍如何使用Amazon 增强 AI和人工协作流程来提高现有文档处理工作流程的准确性。我们还将深入探讨为什么需要人工协作流程以及如何帮助提高现有 AI 预测准确性的方面。
进一步阅读
要了解本章涵盖的主题的更多信息,请查看以下资源:
- 使用 Amazon Textract 和 Amazon Comprehend Medical 自动化理赔审批工作流,作者为 Sonali Sahu 和 Ujjwal Ratan(
aws.amazon.com/blogs/industries/automating-claims-adjudication-workflows-using-amazon-textract-and-amazon-comprehend-medical/)
第三部分:提高生产中的 NLP 模型
在本节中,我们将深入探讨如何在文档处理工作流中为不同目的包含人工环节的策略,并介绍如何根据企业流量最佳地自动扩展你的 NLP 推理。
本节包括以下章节:
-
第十三章,提高文档处理工作流的准确性
-
第十四章,审计命名实体识别工作流
-
第十五章,对文档进行分类并为主动学习设置人工环节
-
第十六章,提高 PDF 批处理的准确性
-
第十七章,从手写内容中可视化洞察
-
第十八章,构建安全、可靠和高效的 NLP 解决方案
第十三章:第十三章:改善文档处理工作流的准确性
在上一章中,我们讨论了 AWS AI 服务,如Amazon Textract和Amazon Comprehend Medical,如何帮助快速自动化医疗工作流。在本章中,我们将讨论为什么在文档处理工作流中需要引入人工干预,并且如何通过设置人类环节(HITL)流程和Amazon 增强型 AI(Amazon A2I)来提高现有文档处理工作流的准确性,尤其是在使用Amazon Textract时。
Amazon A2I 是一种托管服务,它使构建需要人工审阅机器学习(ML)预测的工作流变得简单。在本章中,我们将讨论以下主题:
-
设置 HITL 流程在文档处理中的必要性
-
了解使用 Amazon A2I 实现 HITL 工作流的好处
-
在您的文档处理管道中添加人工审阅
技术要求
本章需要您拥有一个AWS 账户。请确保按照第二章**《介绍 Amazon Textract》中指定的技术要求部分中的说明创建您的 AWS 账户,并在尝试进行改善文档处理工作流的准确性的步骤之前,先登录到AWS 管理控制台。
我们解决方案的Python代码和示例数据集可以在以下链接找到:github.com/PacktPublishing/Natural-Language-Processing-with-AWS-AI-Services/tree/main/Chapter%2013。
查看以下视频,观看代码演示:bit.ly/3jBxBQq。
请按照以下各节中的说明,并结合代码库中的代码来构建解决方案。
设置 HITL 流程在文档处理中的必要性
在前几章中,我们已经讨论了如何使用 Amazon Textract 和 Amazon Comprehend 自动化现有的文档处理工作流,借助 AWS AI 服务。我们涵盖了一些关键应用场景,如使用 Comprehend 分析 SEC 备案报告,使用 Textract 从任何文档中提取文本或快速数字化任何文档。我们还谈到了这些 AI 服务如何为每个预测的文本、单词、行或实体提供置信度分数。现在,客户常常问的问题是如何改进这些预测,并确保它们的准确性。在大多数 AI 系统中,要么是 AI 完成自动化过程,要么只是人工或手动流程。
理想的场景是人类与 AI 协同工作,以便由人类审查这些 AI 系统预测的结果,确保其高度准确。这适用于我们在文档处理工作流中处理高度关键性信息的场景,例如处理贷款申请、发票处理、抵押贷款处理或法律文档审核等。在所有这些场景中,您都希望有人类来验证或审查机器学习或 AI 系统预测的贷款金额或发票金额是否准确,因为如果不准确,一个零可能改变您的生活!这可能导致公司损失数百万。此外,在低置信度预测的情况下,您还希望让人类审查员检查 AI 预测的信息。例如,在索赔处理的情况下,如果您的机器学习系统预测索赔的置信度较低,您会希望根据人工审核来决定是拒绝还是批准该索赔。人类与 AI/ML 的协同工作有助于建立对该过程的信任,同时也减少了整体文档处理解决方案的上市时间。
本节我们讲解了为何需要在现有文档处理工作流中设置人类审核循环——也就是,它有助于提高准确性并与 AI 系统建立信任。在下一节中,我们将讨论在设置 HITL 工作流时使用 Amazon A2I 的一些关键好处。
看到使用 Amazon A2I 进行 HITL 工作流的好处
Amazon A2I 是一项托管服务,使构建和管理与任何机器学习应用相关的人类审查变得更加简单。它直接与 Amazon Textract 和 Amazon Rekognition 集成,以设置适用于内容审核或文档处理等用例的人类工作流。您还可以使用任何 Sagemaker 模型创建自定义工作流。使用 Amazon A2I 的一些好处如下:
-
它提供了 70 多个 UI 模板,帮助您快速入门,设置人类审查的用户界面。请查看这里:
github.com/aws-samples/amazon-a2i-sample-task-uis。 -
它缩短了 AI 系统的上市时间,因为您知道有人工审核作为后盾来捕捉低置信度评分。
-
它为您提供了选择劳动力的选项。我们所说的 劳动力,是指谁将审查创建的人类循环任务。A2I 提供了三种选择——私有劳动力、Amazon Mechanical Turk 和第三方供应商。Amazon Mechanical Turk 是一个全球分布的劳动力选项,供您使用。如果您有敏感数据,可以选择将自己的员工加入并使用私有劳动力选项。在本章中,我们将展示如何创建私有劳动力并在 Amazon A2I 中使用它。
我们已经讨论了一些好处,现在让我们深入了解 Amazon A2I 如何与任何 AWS AI 服务、您的自定义模型或通过 Sagemaker 部署的模型协同工作,下面是相关架构:
图 13.1 – Amazon A2I 架构
让我们通过逐步分析每个步骤来理解图示:
-
您的客户端应用程序将数据或文档发送到您的 AWS AI 服务或任何自定义模型。
-
AWS AI 服务,例如 Amazon Textract,或任何自定义机器学习模型,会进行预测。
-
您可以与 ML 模型一起创建标准或阈值条件,以触发 Amazon A2I 的人工流程。在之前的架构中,阈值是高置信度预测,结果会立即返回给客户端应用程序。此阈值可以根据您的业务需求和用例进行设置,例如,检测到 99% 及以上的发票金额可以视为高置信度,因为它是高度关键的,要求非常准确。在提取某些实体(例如地点)时,您可以将 90% 视为高置信度水平,低于该水平时触发人工审核流程。
-
低置信度预测,即低于您定义的阈值的预测,可以发送进行人工审核,人工审核者或您的工作人员将在由 Amazon A2I 管理的用户界面(UI)中查看。低置信度数据将在该 UI 中展示给人工审核者,他们将对低置信度预测进行审查,并进行增强、修正或验证。
-
人工审核结果会保存在 Amazon S3 中,包含 AI 的预测结果以及人工修改或增强的部分。此数据可以视为真实数据,如果您使用自定义模型,它可以用来重新训练模型。您可以通过从增强数据集重新训练来自定义模型来提高其准确性。请参阅进一步阅读部分,了解有关如何实现这一点的博客参考。
从 Amazon S3,您修正或人工增强/验证后的 AI/ML 预测结果可以发送到客户端应用程序。
注意
使用 Amazon Textract,您只能增强或验证您的预测。当前不支持模型重新训练功能,因为 Amazon Textract 不支持自定义模型。然而,使用 Amazon Comprehend 的自定义分类和自定义实体,您可以使用 Amazon A2I 重新训练您的自定义模型并提高准确性。
在本节中,我们介绍了使用 Amazon A2I 的好处,并展示了它如何改善 AI/ML 系统的准确性。在接下来的部分,我们将指导您如何通过使用 Amazon Textract 和 Amazon A2I 设置文档处理工作流中的人工智能(HITL)流程。
向您的文档处理管道添加人工审核
我们已经介绍了 A2I 如何与任何 AWS AI 服务配合使用架构。在本节中,我们将专门讨论 Amazon A2I 如何与 Amazon Textract 集成,从而使您能够通过 HITL 自动化现有的文档工作流。我们还将展示如何使用 AWS 控制台设置人工审查工作流。
让我们首先来了解 Amazon A2I 如何与 Amazon Textract 协同工作:
图 13.2 – Amazon A2I 与 Amazon Textract 协同工作
您扫描的文档会发送到 Amazon Textract。Amazon Textract 会从文档中提取文本、键值对和表格。现在,对于这些提取的文本、键值对和表格,您还会获得置信度分数。您可以设置一个阈值,当达到该阈值时,Amazon A2I 会触发创建人工审查循环。您可以为 Amazon Textract 设置三个方面的阈值:
-
对于键值对检测中缺失的任何键,例如,如果在您审查的表单中邮寄地址是一个重要的键,但 AI 预测结果中缺失了该项。
-
您可以定义一个预测阈值,以便将其视为高置信度。
-
您可以发送质量保证(QA)审计的预测结果。
注意
Amazon Textract 和 Amazon A2I 在 API 中有原生集成,专门用于键值对或表单数据提取,如果您希望为 Amazon Textract 检测到的文本或表格数据设置人工审查,可以使用该集成。
您可以使用自定义的 A2I 用户界面模板,并通过 starthumanloop A2I API 设置循环,而不是使用 Textract API。当 Amazon A2I 启动人工审查 API 时,我们将添加如何设置自定义循环的示例(请参阅进一步阅读部分):docs.aws.amazon.com/sagemaker/latest/dg/a2i-start-human-loop.html#a2i-instructions-starthumanloop。
让我们回到我们虚构的公司案例。该银行 LiveRight 想要数字化其支票处理系统。当前系统是手动审查支票金额和日期,这既耗时又容易出错。我们将展示 LiveRight 如何使用 Amazon Textract 和 Amazon A2I 来自动化其当前的支票处理系统。我们将使用这份示例支票文档:
图 13.3 – 示例支票
我们将使用这张支票来验证美元金额和日期,确保在向收款人发放之前准确无误。为此,我们将按照以下步骤操作:
-
创建一个 Amazon S3 存储桶
-
在 AWS 控制台中创建私人工作团队
-
在 AWS 控制台中创建人工审查工作流
-
通过调用 Amazon Textract API 将文档发送到 Amazon Textract 和 Amazon A2I
-
在 A2I 控制台中完成对文档的人工审查
-
在您的 S3 存储桶中查看结果
所以,让我们开始吧!
创建一个 Amazon S3 存储桶
首先,我们将讨论如何创建一个 Amazon S3 桶并上传示例文档,以便进行 Textract A2I 处理。正如我们在图 13.1的架构中所述,Amazon A2I 需要一个 Amazon S3 桶来存储人工注释结果。我们还将启用设置 A2I 循环所需的跨源资源共享(CORS)配置。
该配置允许 A2I 浏览器权限从此 S3 桶中下载资源。为此,请按照以下步骤操作:
-
转到 Amazon S3 链接:
s3.console.aws.amazon.com/s3/bucket/create?region=us-east-1。然后,按照第二章中“介绍 Amazon Textract”的说明,创建一个名为
a2i-demos的桶。 -
创建桶后,将以下链接中的示例检查文件上传到桶:
github.com/PacktPublishing/Natural-Language-Processing-with-AWS-AI-Services/blob/main/Chapter%2013/samplecheck.PNG。 -
上传示例检查文件后,转到Amazon S3 桶 | 权限,然后向下滚动到CORS,然后复制并粘贴以下 CORS 配置:
[ { "AllowedHeaders": [], "AllowedMethods": [ "GET" ], "AllowedOrigins": [ "*" ], "ExposeHeaders": [] } ]你的 CORS 配置应该如下所示:
图 13.4 – 我们的 S3 A2I 输出桶的 CORS 配置
本节介绍了如何创建 S3 桶、上传示例检查文件并设置 CORS 配置。接下来,我们将设置私人工作团队。
在 AWS 控制台中创建私人工作团队
在本节中,我们将向你展示如何创建一个私人工作团队并使用你的电子邮件将自己添加为工作者:
-
转到以下链接并选择私人:
console.aws.amazon.com/sagemaker/groundtruth?region=us-east-1#/labeling-workforces。 -
点击
demo-team作为团队名称,向下滚动到添加工作者,输入你自己的有效电子邮件地址作为电子邮件地址,并在组织名称字段中输入你自己的组织:图 13.5 – 创建私人团队并添加工作者
-
向下滚动并点击创建私人团队。
添加工作者到你创建的私人团队后,你将收到一封电子邮件。该邮件包含一个链接,可让你登录到 A2I 任务 UI 门户,并提供你的用户名和密码。
本节介绍了如何创建私人工作团队。接下来,让我们继续设置人工审核工作流。
在 AWS 控制台中创建人工审核工作流
在本节中,我们将展示如何使用 Amazon Textract 创建人工审核工作流。你需要在前面的章节中创建的 Amazon S3 存储桶和私人工作组,并且需要一个 UI 来显示审核和设置触发人工审核环节的阈值条件:
-
访问此链接以创建人工审核工作流:
console.aws.amazon.com/a2i/home?region=us-east-1#/create-human-review-workflows。在
Textract-check中的s3://a2i-demos/> 。对于IAM 角色,点击创建新角色并选择任意 S3 存储桶。你的设置应如下所示:图 13.6 – 使用 A2I 创建流程定义
-
向下滚动并在任务类型中选择Textract 键值对提取。
-
要触发人类审核,你可以选择至少一个条件或所有三个条件。对于缺失的
$和0到90的置信度阈值,如下图所示:图 13.7 – 设置阈值以触发 Textract 的 A2I 循环
-
现在,点击第二个条件的复选框,审核所有表单键的置信度分数在指定范围内,并输入
0到90。我们设置了三个触发条件中的两个条件,以便 Textract A2I 触发审核。只有在前述条件满足时,才会创建人类审核环节——也就是说,如果缺少任何键,比如美元金额和日期,或者任何表单键的置信度分数低于 90%。
-
在
textract-check-ui中。这是 Textract 表单与 A2I 集成的默认 UI。你可以使用自己的自定义 UI 并通过 API 将其添加,我们将在下一章进行讲解。 -
在
label the data。 -
向下滚动到工作者并选择私人,然后点击你刚刚创建的私人团队:
图 13.8 – 在人工审核工作流设置中选择你的私人团队
-
点击创建。这将创建一个人工流程定义。复制此流程定义的 ARN,我们将在满足此流程定义中定义的条件时,使用它来调用 Textract API 中的人类审核环节。
在本节中,我们展示了如何为人工审核环节创建流程定义。在下一节中,我们将展示如何在 Textract Analyze 文档 API 中触发此流程定义,同时传递文档。
通过调用 Amazon Textract API 将文档发送到 Amazon Textract 和 Amazon A2I
在本节中,我们将展示如何在 Textract Analyze 文档 API 中使用表单触发你刚刚创建的 A2I 流程定义。
如果你在前面的章节中没有进行此操作,首先需要创建一个Chapter 13文件夹,并打开chapter13 Improving accuracy of document processing .ipynb笔记本:
注意
确保笔记本中的 IAM 角色具有 AmazonTextractFullAccess 权限(console.aws.amazon.com/iam/home?#/policies/arn:aws:iam::aws:policy/AmazonTextractFullAccess$jsonEditor)和 AmazonAugmentedAIFullAccess 权限(console.aws.amazon.com/iam/home?#/policies/arn%3Aaws%3Aiam%3A%3Aaws%3Apolicy%2FAmazonAugmentedAIFullAccess)。
-
要开始,请转到这个笔记本并在以下笔记本单元格中输入你创建的 S3 桶名称:
bucket="<your s3 bucket name>" -
在
humanLoopConfig中,粘贴从先前设置中复制的流程定义 ARN:humanLoopConfig = { 'FlowDefinitionArn':"<enter flow definition arn created> ", 'HumanLoopName':"textract-10", 'DataAttributes': { 'ContentClassifiers': [ 'FreeOfPersonallyIdentifiableInformation' ]} } -
运行以下笔记本单元格,启动 HITL 配置,通过传递包含我们在控制台中创建的流程定义的
humanloopconfig json,以便使用 A2I Analyze 文档 API:response = textract.analyze_document( Document={'S3Object': {'Bucket': bucket,'Name': "samplecheck.PNG"}}, FeatureTypes=["FORMS"], HumanLoopConfig=humanLoopConfig ) -
运行此命令后,你将得到一个响应,其中包含HumanLoopActivationConditionsEvaluationResults,如以下截图所示:
图 13.9 – Textract Analyze 文档 API 与 A2I 设置的 JSON 响应输出
-
转到你创建的私有工作团队:
console.aws.amazon.com/sagemaker/groundtruth?region=us-east-1#/labeling-workforces将工作团队的 ARN 复制并粘贴到笔记本单元格中,如下所示:
WORKTEAM_ARN= "enter your private workteam arn" -
运行以下代码块以导航到你的工作团队或 A2I 控制台:
workteamName = WORKTEAM_ARN[WORKTEAM_ARN.rfind('/') + 1:] -
你将获得一个链接。点击该链接,并使用在创建工作团队时收到的用户名和密码登录(通过你的电子邮件 ID)。你将看到你的 A2I 任务,如下图所示。点击开始工作:
图 13.10 – 亚马逊 A2I 控制台屏幕,显示工作任务
-
你将被重定向到调用 Textract A2I 循环时创建的任务:
图 13.11 – A2I 控制台,显示从示例检查中 Textract 检测到的键值对
-
你可以在这个 UI 门户的左侧看到原始样本检查,右侧显示提取的键值对。可以验证数据并在需要时输入更改。确保**$金额和日期正确,然后点击提交**。当你点击某个特定的键值时,可以看到 Textract 检测到的输出被映射到原始文档上(边框框映射):
图 13.12 – 在 A2I 控制台中查看和修正 Textract 响应
-
增强和验证数值后,点击提交,你的输出将保存在你创建的同一个 S3 存储桶中。运行以下笔记本单元格以从 S3 获取 JSON 结果并查看注释结果:
for resp in completed_human_loops: splitted_string = re.split('s3://' + bucket + '/', resp['HumanLoopOutput']['OutputS3Uri']) output_bucket_key = splitted_string[1] print(output_bucket_key) 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')你将在以下截图中看到带有人类注释答案的输出:
图 13.13 – 人工修正的 A2I JSON 输出
本节内容为你提供了如何调用 Textract Analyze 文档 API 的笔记本操作指南,配置 HITL 以检测键值对或表单。
摘要
本章内容介绍了如何在使用 Amazon Textract 自动化文档工作流时提高现有文档处理工作流的准确性。我们介绍了 Amazon A2I 及其如何帮助提高文本预测的准确性,并且可以与 Amazon Textract 集成以设置人工审查工作流。我们还讨论了如何使用 A2I 和定制模型进行模型再训练以提高准确性,下一章将深入讲解这一部分内容。
为了进一步展示 A2I 的实际应用,我们还提供了一段 10 分钟的YouTube视频教程,由《深入阅读》部分提到的作者之一讲解。
深入阅读
-
使用 Amazon Textract 与 Amazon A2I 处理关键文档 由 Anuj Gupta, Talia Chopra 和 Pranav Sachdeva 编写:
aws.amazon.com/blogs/machine-learning/using-amazon-textract-with-amazon-augmented-ai-for-processing-critical-documents// -
了解如何在文档处理流程中添加人工审查 由 Mona Mona 编写:
www.youtube.com/watch?v=U2J_pq17POA
第十四章:第十四章:审计命名实体识别工作流
在前一章中,我们介绍了使用Amazon Augmented AI(Amazon A2I)来提高从文档中提取结果准确性的方案。我们看到,Amazon A2I 可以添加到文档处理工作流中,以审核模型预测的准确性。这使我们能够在 LiveRight 的检查处理系统中包含人工审核。
本章将通过将Amazon Comprehend 用于基于文本的洞察扩展前述方法,从而演示如何为您的自定义命名实体识别用例设置审计工作流的端到端过程。我们根据集体经验和在职业生涯中观察到的使用趋势,整理了这个解决方案。我们预计在本章过程中将进行实际操作,但我们已经准备好了所有需要的代码示例。
通过机器学习(ML),企业可以建立自动化文档处理解决方案,经过训练后能够识别并提取文档中的自定义实体。这有助于从文本语料库中获得独特的洞察力,从而推动战略决策。然而,首先需要应对一些挑战。通常,企业会接收到大量格式不同、内容各异的文档,且文档可能是多语言的。而且,随着企业的发展,文档的类型和数量也在不断变化,很快就会进入一种维护负担的状态,需要不断调整各种模板、格式和规则,以确保它们与操作需求的使用方式同步。此外,还必须确保基础设施能够扩展以支持处理需求。
为了解决这些挑战,我们将展示如何利用Amazon Textract的现成机器学习功能,借助迁移学习创建一个自定义实体识别模型,并通过使用 A2I 审核预测结果,结合人工审核循环。我们在第十三章《提高文档处理工作流准确性》中详细介绍了 Amazon A2I。在本章中,我们将按照以下几个部分展开:
-
贷款申请认证
-
构建贷款认证解决方案
技术要求
对于本章,您需要访问AWS 账户,可以通过aws.amazon.com/console/进行访问。有关如何注册 AWS 账户并登录到AWS Management Console的详细说明,请参考第二章《介绍 Amazon Textract》中的注册 AWS 账户子部分。
本章讨论的解决方案的Python代码和示例数据集可以在以下链接找到:github.com/PacktPublishing/Natural-Language-Processing-with-AWS-AI-Services/tree/main/Chapter%2014。
查看以下视频以查看代码在bit.ly/3GoBh1B中的运行情况。
认证贷款申请
每天,金融机构收到大量的贷款申请。虽然主要的机构已经转向完全数字化处理,但世界各地仍有许多银行和机构依赖纸质文档。为了说明我们的例子,让我们回到我们的虚构银行公司LiveRight Holdings Private Limited,并审查此用例的要求:
-
LiveRight 向其主要是中小型企业和个人消费者的客户提供多种借贷产品。为了申请贷款,消费者填写基于纸张的贷款/抵押贷款申请表格,由专家团队验证申请的真实性(称为真实性检查过程)。如果被确认为有效申请人,LiveRight 的贷款处理人员将要求消费者提交支持文件以进行预批准资格。
-
LiveRight 每天从潜在客户处收到 8,000 至 10,000 份贷款申请。这些申请每晚从公司各分支机构转发至总部的文档入口中心。今天,他们的真实性检查过程需要团队大约 2 到 4 周的时间扫描所有申请,并确定是否足够好以转发给贷款处理人员,甚至在预批准阶段也造成了显著的延迟。这引起了许多客户的不满,他们正在将业务转移到其他地方。LiveRight 已经聘请您自动化真实性检查流程,并希望在解决方案实施的头三个月内将处理时间缩短至 24 小时以内。
作为项目的企业架构师,您决定使用 Amazon Textract 来利用其预训练的 ML 模型进行文本提取,使用 Amazon Comprehend 的自定义实体识别器功能逐步创建自己的实体识别器,用于贷款申请检查,无需构建复杂的自然语言处理(NLP)算法,以及使用 A2I 设置人工审查工作流程,监视实体识别器的预测,并向识别器发送反馈,以改善其检测独特用例的实体能力。
您计划在前 2 到 3 个月内提供私有人工工作流,然后禁用它,此时文档处理工作流将完全自动化。当人工团队检查并更新实体标签时,您需要确定真实性检查决策,决策结果为批准、总结批准或拒绝。该决策以及贷款申请中的相关内容应存储在Amazon DynamoDB(一项完全托管的低延迟NoSQL数据库服务)表中,以供贷款处理人员访问内容并启用预审批资格。我们将构建的解决方案组件如下图所示:
图 14.1 – 贷款审批文档处理解决方案架构
我们将使用Amazon SageMaker Jupyter notebook来逐步执行代码并查看结果,从而引导我们走完整个解决方案流程。该解决方案的构建包括以下任务:
-
作为第一步,我们将根据 GitHub 仓库中提供的训练数据集创建 Amazon Comprehend 自定义实体识别器。
-
接下来,我们将创建一个私有标签团队,并添加一名团队成员,负责使用 Amazon A2I 服务来审查 Amazon Comprehend 自定义实体识别器的预测结果。我们将使用 Amazon SageMaker 控制台中的标签团队功能来创建私有团队。有关详细信息,请参考此链接:
docs.aws.amazon.com/sagemaker/latest/dg/sms-workforce-private.html。 -
我们通过检查在 GitHub 仓库中提供的示例贷款申请来开始解决方案工作流程。我们在笔记本中展示贷款申请的图片并查看其内容。
-
然后,我们使用 Amazon Textract 从输入文档中提取键值对。
-
然后,我们从键值对创建一个推理请求字符串,并准备将其发送到 Amazon Comprehend 自定义实体检测。
-
接下来,我们设置一个 Amazon Comprehend 实时终端节点,并调用它来检测我们的推理请求字符串中的实体。
-
我们将使用实体识别任务 UI 模板设置 Amazon A2I 人工审查循环,并将自定义实体检测的结果发送到 Amazon A2I 人工循环。
-
以私有工作者身份登录后,我们将审查检测到的实体,并根据需要修改标签。
-
接下来,我们将检查是否发生了新的实体检测事件,或者是否修改了现有的实体检测,更新实体列表,并将其发送回 Amazon Comprehend 进行实体检测模型的再训练。
-
基于人工审查循环的输出,我们还将为贷款申请做出决定,并将此信息上传到DynamoDB 表中,以便后续处理。
现在我们已经了解了练习的背景并讨论了预定的流程,让我们开始构建解决方案。
构建贷款认证解决方案
在前面的部分,我们介绍了贷款申请审批的用例,讲解了我们将要构建的解决方案架构,并简要地介绍了解决方案组件和工作流程步骤。在本节中,我们将直接开始执行任务,构建我们的解决方案。但首先,我们需要处理一些先决条件。
设置以解决用例
如果您在之前的章节中尚未完成,您首先需要创建一个 Jupyter notebook,并为该 notebook 角色设置身份与访问管理(IAM)权限,以便访问我们将在本笔记本中使用的 AWS 服务。之后,您需要克隆 GitHub 仓库(github.com/PacktPublishing/Natural-Language-Processing-with-AWS-AI-Services),创建一个Amazon S3 存储桶(aws.amazon.com/s3/),并在笔记本中提供存储桶名称以开始执行。在我们可以执行笔记本单元格之前,请按照以下步骤完成这些任务:
注意:
请确保您已完成技术要求部分提到的任务。
-
要创建您的 Jupyter Notebook 实例,请按照第二章中设置您的 AWS 环境部分的创建 Amazon SageMaker Jupyter Notebook 实例一节的说明操作,介绍 Amazon Textract。
创建 Amazon SageMaker Jupyter 笔记本时的 IAM 角色权限
在创建笔记本时接受默认的 IAM 角色,以便访问任何 S3 存储桶。
-
一旦您创建了笔记本实例并且其状态为服务中,点击操作菜单中的打开 Jupyter,进入笔记本实例。
-
这将带您进入笔记本实例的主页文件夹。
-
点击新建,并选择终端。
-
在
cd SageMaker中输入,然后输入git clonegithub.com/PacktPublishing/Natural-Language-Processing-with-AWS-AI-Services。 -
现在,退出终端窗口,返回到
Natural-Language-Processing-with-AWS-AI-Services。点击该文件夹以显示章节文件夹,再点击Chapter 14。点击该文件夹打开。您应该能看到名为chapter14-auditing-workflows-named-entity-detection-forGitHub.ipynb的笔记本。 -
点击打开该笔记本。
按照本笔记本中本节下几小节对应的步骤,逐一执行每个单元格。请阅读每个笔记本单元格前提供的描述。
额外的 IAM 先决条件
为了训练 Comprehend 自定义实体识别器,设置实时端点,我们必须启用额外的策略,并更新我们的 SageMaker 笔记本角色的信任关系。请参考第二章中《设置 AWS 环境》章节里的更改 IAM 权限和信任关系以支持 Amazon SageMaker Notebook 执行角色部分,了解如何执行以下步骤的详细说明:
-
请将
TextractFullAccess、ComprehendFullAccess和AmazonAugmentedAIFullAccess策略附加到你的 Amazon SageMaker Notebook IAM 角色。 -
向你的 SageMaker 笔记本执行角色添加
IAM:PassRole权限作为内联策略:{ "Version": "2012-10-17", "Statement": [ { "Action": [ "iam:PassRole" ], "Effect": "Allow", "Resource": "<your sagemaker notebook execution role ARN"> } ] } -
最后,更新信任关系:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": [ "sagemaker.amazonaws.com", "s3.amazonaws.com", "comprehend.amazonaws.com" ] }, "Action": "sts:AssumeRole" } ] }
现在我们已经设置好了笔记本并配置了 IAM 角色来运行示范笔记本,在接下来的部分,我们将训练一个 Amazon Comprehend 实体识别器。
训练 Amazon Comprehend 自定义实体识别器
让我们开始训练一个自定义实体识别器,检测本解决方案特有的实体。Amazon Comprehend 提供了我们在上一章学习过的预训练实体识别功能。对于本解决方案,我们将使用 Amazon Comprehend 的自定义实体识别功能,它允许你使用增量训练训练一个适应自定义需求的识别器。我们所需要做的就是提供一个我们希望它识别的实体列表,以及包含文本行的原始数据集,这些文本行构成了将被识别为实体的上下文。打开笔记本并按照以下步骤执行:
-
执行步骤 0 - 导入库下的单元,确保我们为笔记本准备好了所需的库。请注意,在此单元中,你将获取到用于笔记本的 Amazon SageMaker 执行角色,以及 SageMaker 会话。请确保你创建了一个 Amazon S3 存储桶(
docs.aws.amazon.com/AmazonS3/latest/userguide/create-bucket-overview.html),并在下面的行中提供存储桶名称:bucket = '<bucket-name>' -
执行
boto3处理的单元,以便在 Amazon Comprehend 下运行:comprehend = boto3.client('comprehend')b) 然后,定义 S3 前缀的变量并将训练数据集和实体列表上传到 S3 存储桶:
s3_raw_key = prefix + "/train/raw_txt.csv" s3_entity_key = prefix + "/train/entitylist.csv" s3.upload_file('train/raw_txt.csv',bucket,s3_raw_key) s3.upload_file('train/entitylist.csv',bucket,s3_entity_key)c) 继续执行笔记本中的其余单元,声明包含我们输入文档的完整 S3 URI的变量,定义实体识别器的输入对象,最后调用 Comprehend API 来创建自定义实体识别器。这将启动训练任务:
import datetime cer_name = "loan-app-recognizer"+str(datetime.datetime.now().strftime("%s")) cer_response = comprehend.create_entity_recognizer( RecognizerName = cer_name, DataAccessRoleArn = role, InputDataConfig = cer_input_object, LanguageCode = "en" )d) 打印自定义实体识别器训练任务的结果:
import pprint pp = pprint.PrettyPrinter(indent=4) response = comprehend.describe_entity_recognizer( EntityRecognizerArn=cer_response['EntityRecognizerArn'] ) pp.pprint(response) -
定期访问 Amazon Comprehend AWS 控制台 (
console.aws.amazon.com/comprehend/v2/home?region=us-east-1#entity-recognition) 检查训练作业的状态。训练过程大约需要 15 到 30 分钟。可以趁此时间喝杯咖啡或小吃一下。
创建用于人工环节的私有团队
请参阅笔记本中的 第 2 步 (github.com/PacktPublishing/Natural-Language-Processing-with-AWS-AI-Services/blob/main/Chapter%2014/chapter14-auditing-workflows-named-entity-detection-forGitHub.ipynb),以获取我们现在要执行的指令。
在此步骤中,我们将使用 Amazon SageMaker 标注工作团队控制台创建一个私有团队,并将自己添加为该私有团队的工作人员。这样做是为了在我们进入此解决方案中的 Amazon A2I 步骤时,能够登录到标注任务的用户界面。请执行以下任务:
-
如果尚未登录 AWS 管理控制台,请登录(更多详细信息,请参考本章开头的 技术要求 部分),在 服务 搜索栏中输入
amazon sagemaker,然后进入 Amazon SageMaker 控制台。进入后,在 UI 左侧点击 Ground Truth,再点击 Labeling workforces。在此页面,选择顶部标签中的 Private,然后点击 Create private team。图 14.2 – SageMaker 标注工作团队
-
在 Team name 字段中输入您的私有团队名称,并在 Add workers 部分保持默认选择 Create a new Amazon Cognito user group。向下滚动并点击 Create private team。
-
现在您将返回到
nlp-doc-team,应该可以在arn:aws:sagemaker:region-name-123456:workteam/private-crowd/team-name下看到它。请从屏幕上复制 ARN 并在笔记本单元格中提供:WORKTEAM_ARN= '<workteam-arn>' -
接下来,向下滚动到前一页面,进入
no-reply@verificationemail.com。按照指示完成注册过程。图 14.3 – 邀请新工作人员
-
接下来,通过点击 nlp-doc-team,再点击 Add workers to team,将自己添加到私有团队中。从列表中选择您的电子邮件地址,然后点击 Add workers to team。
图 14.4 – 向团队添加工作人员
现在我们已经添加了私有团队,让我们通过使用 Amazon Textract 提取内容来审阅我们的贷款申请。
使用 Amazon Textract 提取样本文档内容
在此步骤中,我们将回顾示例贷款申请,然后使用 Amazon Textract 提取我们解决方案所关注的关键值对或表单数据,创建推理请求 CSV 文件,并将其作为输入传递给我们的 Comprehend 自定义实体识别器以检测实体。请通过笔记本逐步执行,并运行单元格以完成此步骤所需的任务:
-
通过执行笔记本单元格中的代码来查看输入文档,如下所示:
documentName = "input/sample-loan-application.png" display(Image(filename=documentName)) -
现在让我们将此图像加载到我们的 S3 存储桶中:
s3.upload_file(documentName,bucket,prefix+'/'+documentName) -
我们将从此文档中提取关键值对数据,转换并创建一个用于推理的请求字符串,使用 Amazon Textract 的AnalyzeDocument API。此 API 接受图像文件(PNG 或 JPEG)作为输入。如果要使用 PDF 文件或处理多个文档,可以使用StartDocumentAnalysis API:
docs.aws.amazon.com/textract/latest/dg/API_StartDocumentAnalysis.html。 -
我们将使用
amazon-textract-response-parser库来处理来自 Textract 的 JSON 响应。通过输入以下命令进行安装:!pip install amazon-textract-response-parser -
现在,让我们使用 Textract 的
boto3Python SDK 来检索文档内容,如下所示:textract = boto3.client('textract') response = textract.analyze_document(Document={'S3Object': { 'Bucket': bucket, 'Name': prefix+'/'+documentName }}, FeatureTypes=['FORMS']) -
我们现在将提取我们解决方案所需的关键值对。我们将不使用复选框字段,仅使用那些有值的字段。同时,我们将在接下来的步骤中筛选出我们实际需要的字段:
from trp import Document doc = Document(response) df = pd.DataFrame() # Iterate over elements in the document x = 0 for page in doc.pages: for field in page.form.fields: if field.key is not None and field.value is not None: if field.value.text not in ('SELECTED','NOT_SELECTED'): df.at[x,'key'] = field.key.text df.at[x,'value'] = field.value.text x+=1 df -
现在,我们已经将 Textract 的结果加载到p****andas DataFrame中(
pandas.pydata.org/docs/reference/api/pandas.DataFrame.html),接下来我们将运行一系列操作,从贷款申请中筛选出我们感兴趣的列。请执行笔记本中Extract contents for sending to Comprehend CER部分下的所有单元格。最终,我们应该会看到如下所示的过滤字段列表:
图 14.5 – 我们将用于 Comprehend 实体识别的最终字段列表
现在,让我们讨论如何使用 Amazon Comprehend 自定义实体识别器来检测实体。
使用 Amazon Comprehend 自定义实体识别器检测实体
现在我们已经从贷款申请中获得所需的内容,让我们构造一个字符串,该字符串将成为我们向最初训练的 Comprehend 自定义实体识别器发送的推理请求(笔记本中的第 1 步)。在检测实体之前,我们需要创建一个实时端点,并将其与我们的实体识别器关联。当你以批处理模式部署此解决方案或用于处理多个文档时,将使用 Amazon Comprehend StartEntitiesDetection API:docs.aws.amazon.com/comprehend/latest/dg/API_StartEntitiesDetectionJob.html。
请按照本节中的说明执行笔记本中的第 4 步单元:github.com/PacktPublishing/Natural-Language-Processing-with-AWS-AI-Services/blob/main/Chapter%2014/chapter14-auditing-workflows-named-entity-detection-forGitHub.ipynb:
-
我们现在将创建一个请求字符串,该字符串将发送到 Amazon Comprehend 自定义实体识别器模型,用于检测我们训练过的实体。这一字符串包含了我们在上一步骤中使用 Amazon Textract 从贷款申请文档中提取的数据。我们将转置 pandas DataFrame,添加一个文档编号列,并用它来准备推理请求字符串:
df_T.columns = df_T.columns.str.rstrip() df_T['doc'] = 1 df_T for idx, row in df_T.iterrows(): entry = 'Country'+':'+str(row['Country']).strip()+" "+'Years'+':'+str(row['Years']).strip()+" "+'Cell Phone'+':'+str(row['Cell Phone']).strip()+" "+'Name'+':'+str(row['Name']).strip()+" "+'Social Security Number'+':'+str(row['Social Security Number']).strip()+" "+'TOTAL $'+':'+str(row['TOTAL $']).strip()+" "+'Date of Birth'+':'+str(row['Date of Birth']).strip() -
接下来,让我们为 Comprehend 创建一个实时端点:
custom_recognizer_arn=cer_response['EntityRecognizerArn'] endpoint_response = comprehend.create_endpoint( EndpointName='nlp-chapter4-cer-endpoint', ModelArn=custom_recognizer_arn, DesiredInferenceUnits=2, DataAccessRoleArn=role ) endpoint_response['EndpointArn'] -
我们看到端点 Arn 如下所示:
arn:aws:comprehend:us-east-1:<aws-account-nr>:entity-recognizer-endpoint/nlp-chapter4-cer-endpoint -
通过导航到 Amazon Comprehend 控制台,进入左侧菜单中的 自定义实体识别,点击你的识别器,然后向下滚动验证实时端点是否成功创建来检查端点的状态。如果端点未激活,笔记本中下一个单元的代码将失败。端点准备好可能需要约15 分钟:图 14.6 – 等待端点准备就绪
图 14.6 – 等待端点准备就绪
-
当端点准备就绪时,执行笔记本单元中的代码,将推理请求发送到自定义实体识别器,如下所示:
response = comprehend.detect_entities(Text=entry, LanguageCode='en', EndpointArn=endpoint_response['EndpointArn'] ) print(response) -
我们看到的输出如下所示。此显示表明我们的 Comprehend 实体识别已识别出所有代表有效人的属性:
{'Entities': [{'Score': 0.9999999403953552, 'Type': 'PERSON', 'Text': 'Years:18', 'BeginOffset': 11, 'EndOffset': 19}, {'Score': 0.9999998211860657, 'Type': 'PERSON', 'Text': 'Cell Phone:(555 ) 0200 1234', 'BeginOffset': 20, 'EndOffset': 47}, {'Score': 1.0, 'Type': 'PERSON', 'Text': 'Name:Kwaku Mensah', 'BeginOffset': 48, 'EndOffset': 65}, {'Score': 1.0, 'Type': 'PERSON', 'Text': 'Social Security Number:123 - 45 - 6789', 'BeginOffset': 66, 'EndOffset': 104}, {'Score': 1.0, 'Type': 'PERSON', 'Text': 'TOTAL $:8000.00/month', 'BeginOffset': 105, 'EndOffset': 126}, {'Score': 1.0, 'Type': 'PERSON', 'Text': 'Date of Birth:01 / 01 / 1953', 'BeginOffset': 127, 'EndOffset': 155}], 'ResponseMetadata': {'RequestId': 'ecbd75fd-22bc-4dca-9aa0-73f58f6784e4', 'HTTPStatusCode': 200, 'HTTPHeaders': {'x-amzn-requestid': 'ecbd75fd-22bc-4dca-9aa0-73f58f6784e4', 'content-type': 'application/x-amz-json-1.1', 'content-length': '620', 'date': 'Tue, 06 Jul 2021 22:26:11 GMT'}, 'RetryAttempts': 0}} -
第 4 步中的最后一个任务是准备一个
human_loop_input列表,以便与我们将在下一步中创建的 Amazon A2I 人工工作流一起使用:import json human_loop_input = [] data = {} ent = response['Entities'] existing_entities = [] if ent != None and len(ent) > 0: for entity in ent: current_entity = {} current_entity['label'] = entity['Type'] current_entity['text'] = entity['Text'] current_entity['startOffset'] = entity['BeginOffset'] current_entity['endOffset'] = entity['EndOffset'] existing_entities.append(current_entity) data['ORIGINAL_TEXT'] = entry data['ENTITIES'] = existing_entities human_loop_input.append(data) print(human_loop_input) 126}, {'label': 'PERSON', 'text': 'Date of Birth:01 / 01 / 1953', 'startOffset': 127, 'endOffset': 155}]}]
在本节中,我们能够使用 Amazon Comprehend 实体识别器检测实体。在下一节中,我们将介绍如何使用 Amazon A2I 审查预测并对预测实体与实际实体之间的差异进行修改。
设置 Amazon A2I 人工工作流循环
有关这里讨论的代码块,请参阅笔记本中的步骤 5:github.com/PacktPublishing/Natural-Language-Processing-with-AWS-AI-Services/blob/main/Chapter%2014/chapter14-auditing-workflows-named-entity-detection-forGitHub.ipynb。
现在,我们已经从 Comprehend 自定义实体识别器中获取了检测到的实体,是时候使用我们在步骤 2中创建的私人团队设置人工工作流,并将结果发送到亚马逊 A2I 人工循环进行审查,以及根据需要进行修改/增强。随后,我们将更新最初用于训练 Comprehend 自定义实体识别器的entitylist.csv文件,以便根据人工反馈准备重新训练:
-
我们首先初始化一些接下来任务所需的变量:
timestamp = time.strftime("%Y-%m-%d-%H-%M-%S", time.gmtime()) # Amazon SageMaker client sagemaker = boto3.client('sagemaker') # Amazon Augment AI (A2I) client a2i = boto3.client('sagemaker-a2i-runtime') # Flow definition name flowDefinition = 'fd-nlp-chapter14-' + timestamp # Task UI name - this value is unique per account and region. You can also provide your own value here. taskUIName = 'ui-nlp-chapter14-' + timestamp # Flow definition outputs OUTPUT_PATH = f's3://' + bucket + '/' + prefix + '/a2i-results' -
现在,我们将通过执行笔记本中的下一个单元格来创建人工任务的用户界面(参见笔记本中的步骤 5)。我们从亚马逊 A2I 示例任务 UI GitHub 仓库(
github.com/aws-samples/amazon-a2i-sample-task-uis)选择了命名实体识别任务模板,并根据我们的需求进行了自定义。 -
基于模板创建任务 UI:
def create_task_ui(): ''' Creates a Human Task UI resource. Returns: struct: HumanTaskUiArn ''' response = sagemaker.create_human_task_ui( HumanTaskUiName=taskUIName, UiTemplate={'Content': template}) return response # Create task UI humanTaskUiResponse = create_task_ui() humanTaskUiArn = humanTaskUiResponse['HumanTaskUiArn'] print(humanTaskUiArn) -
我们得到如下所示的输出:
arn:aws:sagemaker:us-east-1:<aws-account-nr>:human-task-ui/ui-nlp-chapter14-<timestamp> -
执行笔记本中的接下来几个单元格,以创建亚马逊 A2I 流程定义,该定义管理任务分配给工作团队的编排以及输出数据的收集。我们现在准备启动人工工作流循环。执行笔记本中的下一个代码块以启动人工循环。
-
通过执行笔记本中下一个单元格的代码来检查您的人工循环状态——它应该是
InProgress:completed_human_loops = [] a2i_resp = a2i.describe_human_loop(HumanLoopName=humanLoopName) print(f'HumanLoop Name: {humanLoopName}') print(f'HumanLoop Status: {a2i_resp["HumanLoopStatus"]}') print(f'HumanLoop Output Destination: {a2i_resp["HumanLoopOutput"]}') print('\n') if a2i_resp["HumanLoopStatus"] == "Completed": completed_human_loops.append(resp) -
我们得到如下所示的输出:
HumanLoop Name: 0fe076a4-b6eb-49ea-83bf-78f953a71c89 HumanLoop Status: InProgress HumanLoop Output Destination: {'OutputS3Uri': 's3://<your-bucket-name>/chapter4/a2i-results/fd-nlp-chapter4-2021-07-06-22-32-21/2021/07/06/22/33/08/<hashnr>/output.json'
在下一节中,我们将演示您的私人审查员如何登录到控制台并审查亚马逊 Comprehend 检测到的实体。
审查和修改检测到的实体
现在,我们将登录到亚马逊 A2I 任务 UI,审查、修改并重新标注从 Comprehend 自定义实体识别器中检测到的实体。根据本节讨论的指示执行笔记本中的单元格:
-
让我们登录到工作门户以审查预测并根据需要修改它们。执行以下代码以获取我们的任务 UI 的 URL:
workteamName = WORKTEAM_ARN[WORKTEAM_ARN.rfind('/') + 1:] print("Navigate to the private worker portal and do the tasks. Make sure you've invited yourself to your workteam!") print('https://' + sagemaker.describe_workteam(WorkteamName=workteamName)['Workteam']['SubDomain']) -
登录后,您将看到一个贷款申请审核任务。选择它并点击开始工作:
图 14.7 – 亚马逊 A2I 任务列表
-
您应该能够看到亚马逊 A2I 标签 UI,其中显示了由 Comprehend 自定义实体识别高亮的实体列表及其标签,如下图所示:
图 14.8 – Amazon A2I 标签界面准备好进行人工审核
-
现在,从右侧的标签中选择GHOST标签,然后将其分配给 UI 中未标记的Country:US条目,并点击提交。图 14.9 – 向检测到的实体添加/修改标签并点击提交
图 14.9 – 向检测到的实体添加/修改标签并点击提交
-
继续执行笔记本中的单元格,再次检查人工环路的状态(这应该显示
entitylist.csv文件的状态,并触发我们 Comprehend 自定义实体识别器的再训练。让我们验证是否存在新实体:retrain='N' el = open('train/entitylist.csv','r').read() for annotated_entity in a2i_entities: if original_text[annotated_entity['startOffset']:annotated_entity['endOffset']] not in el: retrain='Y' word = '\n'+original_text[annotated_entity['startOffset']:annotated_entity['endOffset']]+','+annotated_entity['label'].upper() print("Updating Entity List with: " + word) open('train/entitylist.csv','a').write(word) if retrain == 'Y': print("Entity list updated, model to be retrained") -
我们看到如下代码块显示的输出。尽管 Comprehend 将
Years和Cell Phone识别为PERSON实体,但它并未出现在原始的entitylist.csv文件中,因此它将与这些值一起更新,并且 Comprehend 实体识别将重新训练:Updating Entity List with: Country:US,GHOST Updating Entity List with: Years:18,PERSON Updating Entity List with: Cell Phone:(555 ) 0200 1234,PERSON Entity list updated, model to be retrained
此响应会自动保存为 Amazon S3 存储桶中的 JSON 文件,格式为标签。在下一部分,我们将使用这些修改或审核过的标签来重新训练我们的自定义实体识别器模型。
重新训练 Comprehend 自定义实体识别器
我们现在将重新训练我们的 Comprehend 自定义实体识别器。要执行的单元格与我们最初训练识别器时所做的类似:
-
在声明变量后,我们执行以下代码块以启动训练:
Import datetime cer_name = "retrain-loan-recognizer"+str(datetime.datetime.now().strftime("%s")) cer_response = comprehend.create_entity_recognizer( RecognizerName = cer_name, DataAccessRoleArn = role, InputDataConfig = cer_input_object, LanguageCode = "en" ) -
我们看到输出显示,表示重新训练任务已经提交。为了清晰起见,响应中的元数据已被移除:
{ 'EntityRecognizerProperties': { 'DataAccessRoleArn': 'arn:aws:iam::<aws-account-nr>:role/service-role/<execution-role>', 'EntityRecognizerArn': 'arn:aws:comprehend:us-east-1:<aws-account-nr>:entity-recognizer/retrain-loan-recognizer1625612436', 'InputDataConfig': { 'DataFormat': 'COMPREHEND_CSV', 'Documents': { 'S3Uri': 's3://<s3-bucket>/chapter4/train/raw_txt.csv'}, 'EntityList': { 'S3Uri': 's3://<s3-bucket>/chapter4/train/entitylist.csv'}, 'EntityTypes': [ { 'Type': 'PERSON'}, { 'Type': 'GHOST'}]}, 'LanguageCode': 'en', 'Status': 'SUBMITTED', 'SubmitTime': datetime.datetime(2021, 7, 6, 23, 0, 36, 759000, tzinfo=tzlocal())}} -
与之前一样,转到 Amazon Comprehend 控制台,检查实体识别器的状态,并验证状态是否已更改为已训练。
-
请重复笔记本中的步骤 3到步骤 5,测试重新训练后的识别器。
现在,让我们执行步骤,将认证检查的结果存储,以便下游应用程序访问。
存储下游处理的决策
现在我们了解了如何设置审计工作流,让我们执行必要的步骤,将实体检测的结果持久化,以便将其发送到下游应用程序。如果大多数或所有实体都是GHOST类型,我们将发送拒绝决策;如果大多数是PERSON类型,我们将发送总结批准;如果全部都是PERSON,我们将发送批准;如果它们分布均匀,我们将发送拒绝决策:
-
首先,让我们检查从 A2I 中检测到的
PERSON或GHOST类型的实体数量。执行笔记本中步骤 8的第一个单元格。我们得到的输出如下:[{'endOffset': 10, 'label': 'GHOST', 'startOffset': 0}, {'endOffset': 19, 'label': 'PERSON', 'startOffset': 11}, {'endOffset': 47, 'label': 'PERSON', 'startOffset': 20}, {'endOffset': 65, 'label': 'PERSON', 'startOffset': 48}, {'endOffset': 104, 'label': 'PERSON', 'startOffset': 66}, {'endOffset': 126, 'label': 'PERSON', 'startOffset': 105}, {'endOffset': 155, 'label': 'PERSON', 'startOffset': 127}] -
让我们应用之前的规则来决定该贷款申请的结果:
from collections import Counter docstatus = '' ghost = float(Counter(labellist)['GHOST']) person = float(Counter(labellist)['PERSON']) if ghost >= len(labellist)*.5: docstatus = 'REJECT' elif min(len(labellist)*.5, len(labellist)*.8) < person < max(len(labellist)*.5, len(labellist)*.8): docstatus = 'SUMMARY APPROVE' elif person > len(labellist)*.8: docstatus = 'APPROVE' print(docstatus) -
我们得到的输出是
APPROVE。 -
将决策存储在 Amazon DynamoDB 表中(提醒:这是一个托管的数据库服务,用于存储和访问具有极低延迟的键值对)。贷款处理器可以使用这些数据开始预资格审查过程。在笔记本中执行下一个单元格来创建 DynamoDB 表。
-
现在,执行笔记本中的下一个单元格,将贷款申请的内容和决策插入到表中。我们看到插入到 DynamoDB 表中的值如下:
图 14.10 – DynamoDB 中的贷款真实性检查状态
这就结束了解决方案构建。请参考进一步阅读部分,获取更多关于此用例的解决方法示例,以及使用 AWS Lambda 和 CloudFormation 构建类似解决方案的代码示例。
总结
在本章中,我们学习了如何构建一个用于命名实体识别的审计工作流,以解决许多组织在文档处理方面面临的现实挑战,使用的工具包括 Amazon Textract、Amazon Comprehend 和 Amazon A2I。我们回顾了贷款认证的用例,以验证文档在传递给贷款处理器之前的有效性。我们考虑了一种架构,依据的条件包括将验证时间从 2 到 4 周减少到 24 小时,这个过程将在解决方案实施后的前三个月内完成。我们假设你是这项项目的解决方案架构师,并回顾了解决方案组件的概述以及图 4.1中的架构图示。
接着,我们逐步讲解了解决方案构建的先决条件,设置了一个 Amazon SageMaker Notebook 实例,克隆了我们的 GitHub 仓库,并根据本章的说明开始执行笔记本中的代码。我们涵盖了如何训练 Amazon Comprehend 的自定义实体识别器,如何使用 Amazon SageMaker 标注工作队伍建立我们的私人工作团队,如何使用 Amazon Textract 提取贷款申请中的相关内容,将其发送到 Comprehend 自定义实体识别器进行实体检测,将检测结果转发到 Amazon A2I 人工审核循环,使用 UI 完成人工任务步骤,审查审核结果,更新实体列表以重新训练自定义实体识别器,最后将文档内容和贷款验证决策存储到 Amazon DynamoDB 表中以供后续处理。
在下一章中,我们将构建一个为 NLP 量身定制的经典用例——即文本分类的主动学习工作流。我们将使用 Amazon Comprehend custom 训练一个文本分类模型,用于将文档标记为不同类别,利用 Amazon A2I 审查预测结果,并根据 Amazon A2I 人工审阅反馈重新训练分类器。我们将展示该解决方案如何通过反馈循环在提高分类准确性方面不断发展智能化。
深入阅读
-
使用 AWS 构建端到端智能文档处理解决方案,作者:Purnesh Tripathi:
aws.amazon.com/blogs/machine-learning/building-an-end-to-end-intelligent-document-processing-solution-using-aws/ -
使用 Amazon SageMaker Ground Truth、Amazon Comprehend 和 Amazon A2I 设置 NLP 基础的实体识别模型的人工审阅,作者:Mona Mona 和 Prem Ranga:
aws.amazon.com/blogs/machine-learning/setting-up-human-review-of-your-nlp-based-entity-recognition-models-with-amazon-sagemaker-ground-truth-amazon-comprehend-and-amazon-a2i/ -
宣布 Amazon Comprehend custom 实体识别模型改进和更低的标注限制,作者:Prem Ranga、Chethan Krishna 和 Mona Mona:
aws.amazon.com/blogs/machine-learning/announcing-model-improvements-and-lower-annotation-limits-for-amazon-comprehend-custom-entity-recognition/
第十五章:第十五章:文档分类及设置人类参与的主动学习
在上一章中,我们介绍了如何使用Amazon Comprehend 自定义实体从文档中提取业务实体,并展示了如何结合 Amazon 增强型 AI(A2I)使用人工参与来增强或改进实体预测。最后,我们展示了如何通过使用增强数据集对 Comprehend 自定义实体模型进行重新训练,以利用 Amazon A2I 提高准确性。
在本章中,我们将讨论如何使用Amazon Comprehend 自定义分类来分类文档,并介绍如何通过 Amazon A2I 设置主动学习反馈,以优化你的自定义分类模型。
本章将涵盖以下主题:
-
使用带有人工参与的 Comprehend 自定义分类进行主动学习
-
构建文档分类工作流
技术要求
本章需要访问 AWS 账户。请确保按照 技术要求 部分中的说明,通过 第二章,介绍 Amazon Textract,创建你的 AWS 账户,并登录 AWS 管理控制台,然后再执行本章中的步骤。
设置带有人工反馈环节的 Comprehend 自定义分类解决方案的 Python 代码和示例数据集请参考以下链接:github.com/PacktPublishing/Natural-Language-Processing-with-AWS-AI-Services/tree/main/Chapter%2015。
请查看以下视频,观看代码演示:bit.ly/3BiOjKt。
请按照以下各节中的说明,并结合代码库中的代码来构建解决方案。
使用带有人工参与的 Comprehend 自定义分类进行主动学习
Amazon Comprehend 提供了使用 Amazon Comprehend AutoML 分类数据的能力,并允许你使用自定义训练数据集。利用 Amazon Comprehend 自定义分类功能,你可以轻松完成很多任务,因为它要求用于训练 Comprehend AutoML 模型的文档较少。这意味着你花费更少时间在标注数据集上,而不用担心设置基础设施或选择正确的算法。
你可以使用 Amazon Comprehend 自定义分类处理各种用例,例如根据类型对文档进行分类、对新闻文章进行分类,或根据类型对电影进行分类。
虚构公司LiveRight pvt ltd希望在分析文档内容之前,先对客户提交的文档进行分类,例如判断提交的文档是身份证明还是银行对账单。此外,如果你使用分类模型来根据提交的文档类型对文档进行分类,你也希望基于 Amazon Comprehend 自定义分类模型预测的置信度分数,在实时中提高预测结果的准确性。这时,结合亚马逊增强型人工智能(Amazon Augmented AI)的人机协作将发挥作用。
我们在第十三章《提高文档处理工作流的准确性》中介绍了 Amazon A2I。在本章中,我们将带你了解一些参考架构,说明如何使用 Amazon Comprehend 轻松设置自定义分类模型,并与 Amazon A2I 建立反馈回路,以便对你的 Comprehend 自定义模型进行主动学习。
首先,我们将带你了解如何训练一个自定义分类模型,并创建一个实时端点,用于近实时地推断或分类文档。
图 15.1 – Comprehend 自定义分类训练工作流
该架构包括以下步骤:
-
训练文档,如银行对账单或工资单,被上传到 Amazon S3。
-
Amazon Textract 从这些文档中提取文本,然后进行一些后处理,创建一个标签化的训练文件,用于 Comprehend 自定义分类训练。
-
使用训练文件,创建一个 Amazon Comprehend 作业来分类文档,如银行对账单或工资单。
-
训练完成后,你可以选择使用 Amazon Comprehend 执行批量推断,将一批文档分类,或者创建实时端点。在这个架构中,我们展示了如何设置实时端点来分类文档类型。
我们将在解决用例设置部分通过 Jupyter Notebook 和几行 Python 代码,带你了解前述概念架构的实现。
现在,我们有了一个近乎实时的文档分类端点。我们将展示如何使用这个 Amazon Comprehend 自定义分类端点设置人机协作,并通过以下架构建立模型重训练或主动学习循环,以提高模型的准确性:
图 15.2 – 通过模型重训练实现实时分类
在这个架构中,我们将带你完成以下步骤:
-
客户端应用程序将文档发送给 Amazon Textract。
-
Amazon Textract实时提取数据或文本,并将提取的数据传递到 Amazon Comprehend 实时分类端点。
-
Amazon Comprehend 自定义分类端点将对该文档类型进行分类。
-
该分类端点配置了 Amazon A2I 人工环节。如果分类预测的置信度高,根据您的业务阈值(您可以配置该阈值),则高置信度预测会直接发送到客户端应用程序。
-
对于低置信度的预测,例如任何低于 95% 置信度的预测,预测的得分为低置信度。这时会创建一个人工环节,将这些预测发送给人工审核。请参考第三章,介绍 Amazon Comprehend,了解什么是置信度分数以及 Comprehend 的自定义功能。
-
人工标注者修正或增加的数据会以JSON文件的形式保存在 Amazon S3 存储桶中。
-
然后,这些数据与原始训练数据集结合,并使用人工反馈对 Amazon Comprehend 自定义模型进行重新训练,以实现主动学习。
我们将带您完成第 1 至第 6 步,使用 Jupyter Notebook 在设置用例部分。您可以自由地将增强的分类标签与原始数据集结合,尝试重新训练以加深理解。您还可以使用步骤函数和 Lambda 函数自动化此架构。我们将在进一步阅读部分与您分享帮助您使用 Lambda 函数设置此架构的博客。
在本节中,我们介绍了模型训练和重新训练或主动学习的架构。接下来,让我们进入下一节,通过代码来展示这些概念。
构建文档分类工作流
在本节中,我们将直接开始执行任务来构建我们的解决方案。但首先,我们需要处理一些前提条件。
设置以解决用例
如果您在前面的章节中还没有完成此操作,您需要先创建一个 Amazon SageMaker Jupyter 笔记本,并设置 Chapter 15 文件夹,打开 chapter15 classify documents with human in the loop.ipynb 笔记本。
现在,让我们进入下一节,向您展示如何设置库并使用此笔记本将训练数据上传到 Amazon S3。
设置并上传样本文档到 Amazon S3
在此步骤中,我们将按照说明设置一个 S3 存储桶并上传文档:
-
转到笔记本并运行以下
boto 3单元格进行设置。 -
继续到下一个单元格,输入一个存储桶名称,以在您的帐户中创建一个 S3 存储桶。在执行此单元格之前,请确保在
data_bucket中添加当前月份和日期(格式为MMDD),如下面的代码块所示:data_bucket = "doc-processing-bucket-MMDD" region = boto3.session.Session().region_name os.environ["BUCKET"] = data_bucket os.environ["REGION"] = region if region=='us-east-1': !aws s3api create-bucket --bucket $BUCKET else: !aws s3api create-bucket --bucket $BUCKET --create-bucket-configuration LocationConstraint=$REGION -
现在运行以下单元格,将本地笔记本中的样本银行对账单或工资单图像上传或复制为训练文件,上传到您刚刚创建的 S3 存储桶:
!aws s3 cp documents/train s3://{data_bucket}/train –recursive -
现在运行笔记本中的接下来的两个单元,以列出我们刚刚复制到 Amazon S3 中的训练图像。我们创建了一个名为
get_s3_bucket_items的函数。我们从 S3 获取图像对象,并将其保存为 Textract 处理的图像,供后续步骤使用。请参考笔记本执行这些步骤。 -
运行以下步骤,定义一个路径或本地目录结构,以存储从 Amazon Textract 提取的数据:
word_prefix=os.getcwd()+'/SAMPLE8/WORDS/' box_prefix=os.getcwd()+'/SAMPLE8/BBOX/'
我们已经介绍了如何创建 S3 存储桶并加载训练数据。接下来,让我们进入提取文本的下一部分。
使用 Amazon Textract 从示例文档中提取文本
转到笔记本并运行步骤 2:使用 Amazon Textract 从示例文档中提取文本中的代码,定义一个函数,使用 Amazon Textract 从 Amazon S3 中的示例图像提取数据。我们正在使用 DetectDocumentText 同步 API 进行提取;你也可以使用异步 API或Textract 批量 API来执行数据提取。请参考第四章,自动化文档处理工作流,深入了解这些 API:
def data_retriever_from_path(path):
mapping={}
for i in names:
if os.path.isdir(path+i):
mapping[i] = sorted(os.listdir(path+i))
label_compre = []
text_compre = []
for i, j in mapping.items():
for k in j:
label_compre.append(i)
text_compre.append(open(path+i+"/"+k, encoding="utf-8").read().replace('\n',' '))
return label_compre, text_compre
这个函数接受图片的路径并返回图片中的文本和标签。
让我们通过运行笔记本中的以下单元,调用这个函数并传入扫描文档的图像:
tic = time.time()
pool = mp.Pool(mp.cpu_count())
pool.map(textract_store_train_LM, [table for table in images ])
print("--- %s seconds for extracting ---" % (time.time() - tic))
pool.close()
上述函数提取数据并将其保存在你在设置并上传示例文档步骤中定义的本地目录结构中。以下是输出结果:
图 15.3 – Textract 输出
现在,我们已经提取了文本和相关标签,例如0代表银行对账单,1代表工资单。接下来,让我们进入 Comprehend 训练的下一部分。
创建 Amazon Comprehend 分类训练任务
在前一步中,我们已经从 Amazon S3 中的扫描文档样本提取了数据和标签。接下来,让我们了解如何使用步骤 3:创建 Amazon Comprehend 分类训练任务在笔记本中设置 Comprehend 分类训练任务:
-
我们首先创建一个函数,将提取的数据和标签映射到 pandas DataFrame,以便在下一步将其转换为 CSV 训练文件。运行以下代码来定义该函数,它接受提取的数据位置并返回其中的标签和文本:
def data_retriever_from_path(path): mapping={} for i in names: if os.path.isdir(path+i): mapping[i] = sorted(os.listdir(path+i)) # label or class or target list label_compre = [] # text file data list text_compre = [] # unpacking and iterating through dictionary for i, j in mapping.items(): # iterating through list of files for each class for k in j: # appending labels/class/target label_compre.append(i) # reading the file and appending to data list text_compre.append(open(path+i+"/"+k, encoding="utf-8").read().replace('\n',' ')) return label_compre, text_compre -
现在,我们将通过运行以下代码调用之前定义的函数:
label_compre, text_compre=[],[] path=word_prefix+'train/' label_compre_train, text_compre_train=data_retriever_from_path(path) label_compre.append(label_compre_train) text_compre.append(text_compre_train) if type(label_compre[0]) is list: label_compre=[item for sublist in label_compre for item in sublist] #print(label_compre) text_compre=[item for sublist in text_compre for item in sublist] #print(text_compre) data_compre= pd.DataFrame() data_compre["label"] =label_compre data_compre["document"] = text_compre data_compre你将获得一个包含标签和文档的 pandas DataFrame,内容如下所示:
图 15.4 – 带标签的训练 DataFrame
-
现在,我们将把这个 DataFrame 保存为 CSV 文件,并使用 S3 上传到 Amazon S3。将
boto3API 对象作为 Amazon Comprehend 训练文件进行训练:csv_compre=io.StringIO() data_compre.to_csv(csv_compre,index=False, header=False) key='comprehend_train_data.csv' input_bucket=data_bucket output_bucket= data_bucket response2 = s3.put_object( Body=csv_compre.getvalue(), Bucket=input_bucket, Key=key) -
现在,访问 Amazon Comprehend 控制台链接(console.aws.amazon.com/comprehend/… Train Classifier。
-
在
doc-classifier中,选择1,然后向下滚动选择csv 文件。重要提示
我们可以为 Amazon Comprehend 自定义模型添加版本。要了解更多关于此功能的信息,请参考此链接:
docs.aws.amazon.com/comprehend/latest/dg/model-versioning.html。图 15.5 – Amazon Comprehend 自定义分类 UI
-
对于训练数据位置,浏览到
doc-processing-bucket-MMDDS3 桶,该桶位于s3://doc-processing-bucket-MMDD/comprehend_train_data.csv。 -
对于
Autosplit,这意味着 Amazon Comprehend 会自动为您拆分测试数据。您也可以选择通过提供自己的测试数据集来调整模型。 -
对于输出数据,请输入
s3://doc-processing-bucket-MMDDS3 桶。 -
对于访问权限,在 NameSuffix 中选择
classifydoc。图 15.6 – Amazon Comprehend 自定义分类 IAM 设置
-
向下滚动并点击 Train Classifier 按钮开始训练。
重要提示
此训练将花费 30 分钟完成,因为本章中我们有大量文档需要训练。您可以利用这段时间设置一个私人工作队伍,为设置人类参与环节做准备,正如我们在第十三章中所做的,提高文档处理工作流的准确性。
一旦您的任务完成,继续进行下一步。
创建 Amazon Comprehend 实时端点并测试示例文档
在本节中,我们将展示如何在AWS 管理控制台中使用训练后的模型创建实时端点。Comprehend 使用推理单元(IU)来分析每秒钟可以实时分析多少个字符。IU 是端点吞吐量的度量。您可以随时调整端点的 IU。创建端点后,我们将展示如何使用 Jupyter Notebook 调用此端点来测试一个示例银行对账单:
-
访问此链接,console.aws.amazon.com/comprehend/… 创建端点。
-
输入
classify-doc作为端点名称,设置我们在上一步中训练的doc-classifier,并将推理单元设置为 1。图 15.7 – Amazon Comprehend 创建实时端点 UI
-
向下滚动并选择 I Acknowledge,然后点击 创建端点。
在笔记本的清理部分删除此端点,以避免产生费用。
-
现在,复制下一张截图中显示的ARN,然后前往 Jupyter Notebook 链接:
图 15.8 – Comprehend 自定义分类终端节点 ARN
-
在笔记本中,按如下方式将之前复制的终端节点 ARN 输入到笔记本单元格中:
ENDPOINT_ARN='your endpoint arn paste here' -
现在,我们将使用一个示例测试文档或任何未在训练中使用的薪资单进行实时分类。运行以下代码来查看示例薪资单:
documentName = "paystubsample.png" display(Image(filename=documentName))你将获得以下输出:
图 15.9 – 示例薪资单文档
-
在使用 Textract 从此示例文档提取文本部分运行接下来的两个单元格,以提取此示例文档中的文本。
-
运行以下单元格,它调用 Comprehend 的 ClassifyDocument API。此方法将提取的文本和自定义分类终端节点传递给 API,并返回一个响应:
response = comprehend.classify_document( Text= page_string, EndpointArn=ENDPOINT_ARN ) print(response)你将得到以下响应:
图 15.10 – ClassifyDocument 响应
根据响应,模型终端节点已经将文档分类为薪资单,置信度为 99%。我们已经测试了这个终端节点,现在让我们进入下一部分,设置人工环路。
使用实时终端节点和人工环路设置主动学习,结合 Comprehend
在本节中,我们将向你展示如何与 Comprehend 分类终端节点进行自定义集成,你可以使用 A2I StartHumanLoop API 调用此集成。你可以将任何类型的 AI/ML 预测响应传递给此 API 来触发人工环路。在第十三章中,提高文档处理工作流的准确性,我们通过将人工环路工作流 ARN 传递给 AnalyzeDocument API,向你展示了与 Textract Analyze 文档 API 的原生集成。设置自定义工作流包括以下步骤:
-
创建一个工作任务模板。
-
创建一个人工审核工作流。
-
创建并启动 A2I 人工环路。
-
检查人工环路状态并开始标注。
要开始,你需要创建一个私人工作团队,并在 Jupyter Notebook 中的环境设置步骤中复制私人 ARN:
-
要创建一个私人工作团队,请参考第十三章中的在 AWS 控制台创建私人工作团队部分,提高文档处理工作流的准确性:
REGION = 'enter your region' WORKTEAM_ARN= "enter your private workforce arn " BUCKET = data_bucket ENDPOINT_ARN= ENDPOINT_ARN role = sagemaker.get_execution_role() region = boto3.session.Session().region_name prefix = "custom-classify" + str(uuid.uuid1()) -
运行下一个单元并转到
创建工作任务模板。这是工作人员在标注时将要查看的 UI。我们将在 UI 中显示预测结果和原始文档数据。我们已经为此用例使用了一个预构建的分类模板(github.com/aws-samples/amazon-a2i-sample-task-uis/blob/master/text/document-classification.liquid.html)。运行笔记本单元来定义 HTML 模板。重要提示
你可以根据希望向标注者展示的数据类型,创建自定义的 UI HTML 模板。例如,你可以在右侧显示实际文档,在左侧高亮显示实体,使用自定义 UI。
-
我们在前一步中定义或选择了 HTML 模板,在此模板中,我们将通过运行以下代码,使用
create_human_task_uiAPI 创建一个 UI 任务:def create_task_ui(): response = sagemaker.create_human_task_ui( HumanTaskUiName=taskUIName, UiTemplate={'Content': template}) return response -
运行下一个单元来调用前一步中定义的创建 UI 任务的函数。你将获得一个
human task arn响应。 -
现在,我们将定义一个人工审核工作流。这个人工审核工作流需要你创建的私人劳动力、你创建的 UI 模板任务,以及你希望将人工审核输出保存到的数据桶。我们将使用
sagemaker.create_flow_definitionAPI,通过运行以下代码创建一个工作流定义或人工审核工作流:create_workflow_definition_response = sagemaker.create_flow_definition( FlowDefinitionName= flowDefinitionName, RoleArn= role, HumanLoopConfig= { "WorkteamArn": WORKTEAM_ARN, "HumanTaskUiArn": humanTaskUiArn, "TaskCount": 1, "TaskDescription": "Read the instructions", "TaskTitle": "Classify the text" }, OutputConfig={ "S3OutputPath" : "s3://"+BUCKET+"/output" } flowDefinitionArn = create_workflow_definition_response['FlowDefinitionArn'] -
现在,我们将从 Comprehend 自定义分类器端点获取工资单示例数据的响应,并解析此响应以设置人工循环:
response = comprehend.classify_document( Text= page_string, EndpointArn=ENDPOINT_ARN ) print(response) p = response['Classes'][0]['Name'] score = response['Classes'][0]['Score'] #print(f»S:{sentence}, Score:{score}») response = {} response['utterance']=page_string response['prediction']=p response['confidence'] = score print(response) -
现在,使用这个前面的 JSON 响应,我们将设置一个信心阈值。这个
StartHumanloopAPI 需要前一步创建的工作流 ARN 或流定义 ARN 以及 Comprehend 分类的 JSON 响应,以创建人工循环。我们将根据信心评分阈值触发这个循环,如下一个代码块所示:human_loops_started = [] CONFIDENCE_SCORE_THRESHOLD = .90 if(response['confidence'] > CONFIDENCE_SCORE_THRESHOLD): humanLoopName = str(uuid.uuid4()) human_loop_input = {} human_loop_input['taskObject'] = response['utterance'] start_loop_response = a2i_runtime_client.start_human_loop( HumanLoopName=humanLoopName, FlowDefinitionArn=flowDefinitionArn, HumanLoopInput={ "InputContent": json.dumps(human_loop_input) } ) print(human_loop_input) human_loops_started.append(humanLoopName) print(f'Score is less than the threshold of {CONFIDENCE_SCORE_THRESHOLD}') print(f'Starting human loop with name: {humanLoopName} \n') else: print('No human loop created. \n')重要提示
前面的条件说明,任何大于 90%信心的模型端点输出将触发一个循环。这个阈值仅用于演示目的,实际使用时需要更改,例如,低于 90%时触发人工循环。
-
现在,运行以下代码以获取私人工作团队的链接,开始标注工作:
workteamName = WORKTEAM_ARN[WORKTEAM_ARN.rfind('/') + 1:] print("Navigate to the private worker portal and do the tasks. Make sure you've invited yourself to your workteam!") print('https://' + sagemaker.describe_workteam(WorkteamName=workteamName)['Workteam']['SubDomain'])你将获得以下 A2I 门户的链接:
图 15.11 – 亚马逊 A2I 登录控制台
-
选择任务标题并点击开始工作;你将被重定向到分类任务 UI。
图 15.12 – 亚马逊 A2I 示例分类任务 UI
查看前一截图左侧的数据,并通过选择工资单类别进行分类,然后点击提交。
-
提交此分类任务作为人工审查后,返回笔记本并运行以下代码,获取已完成的任务:
completed_human_loops = [] resp = a2i_runtime_client.describe_human_loop(HumanLoopName=humanLoopName) -
现在,我们将审查从已完成的人工审查中获得的结果,这些结果会自动存储为 JSON 文件在 Amazon S3 中,你可以通过运行以下代码来查看:
for resp in completed_human_loops: splitted_string = re.split('s3://' + data_bucket + '/', resp['HumanLoopOutput']['OutputS3Uri']) output_bucket_key = splitted_string[1] response = s3.get_object(Bucket=data_bucket, Key=output_bucket_key) content = response["Body"].read() json_output = json.loads(content) pp.pprint(json_output)你将收到以下响应:
图 5.13 – 人工审查的 JSON 响应
利用这些数据,你可以扩展或丰富用于训练的现有数据集。试着将这些数据与我们创建的 Comprehend 训练数据结合,尝试重新训练你的模型以提高准确率。我们将在进一步阅读部分中提供一些博客链接,帮助你完成这一步。
重要提示
请删除我们在此笔记本中创建的模型和 Comprehend 端点。
总结
在这一章中,我们通过参考架构和代码演示讲解了两件事。首先,我们讲解了如何使用 Amazon Textract 从各种类型的文档中提取数据,如工资单、银行对账单或身份证。然后,我们学习了如何进行一些后处理操作,以创建用于 Amazon Comprehend 自定义分类训练的标签化训练文件。
我们向你展示了,即使只有 36 份银行对账单和 24 份工资单作为训练样本,你也可以通过使用 Amazon Comprehend 的迁移学习能力和 AutoML 进行文档或文本分类,获得非常好的准确率。显然,随着数据量的增加,准确率会提高。
接着,你学习了如何在 AWS 管理控制台中设置训练任务,以及如何在 AWS 管理控制台中设置实时分类端点。
其次,你学习了如何使用实时分类端点设置“人类在环”系统,以审查/验证和确认模型所分类的内容。我们还讨论了如何通过将这些数据与现有的训练数据一起添加,来重新训练现有的模型,并设置一个重新训练或主动学习循环。请参阅进一步阅读部分,了解如何使用 Lambda 函数自动化此工作流。
在下一章中,我们将讨论如何利用 Amazon Textract 和“人类在环”系统提高PDF 批量处理的准确性。敬请期待!
进一步阅读
-
Amazon Comprehend 自定义分类模型的主动学习工作流 - 第二部分,Shanthan Kesharaju, Joyson Neville Lewis 和 Mona Mona (
aws.amazon.com/blogs/machine-learning/active-learning-workflow-for-amazon-comprehend-custom-classification-part-2/)%20) -
创建和使用自定义分类器(*
docs.aws.amazon.com/comprehend/latest/dg/getting-started-document-classification.html)
第十六章:第十六章:提高 PDF 批处理的准确性
恭喜你走到了这本书的这一阶段!此时,你已经是一个能够利用 NLP 和 AI 的力量,构建实际应用以带来实际业务效益的高级开发者。你可能没有意识到,但我们到目前为止讨论的主题——以及我们接下来要继续讨论的内容——解决了一些最受欢迎、最具需求的商业挑战,这是我们帮助客户解决的问题之一。智能文档处理(IDP)是目前非常热门的需求,几乎在每个行业中都有广泛应用。我们从第十三章《提高文档处理工作流的准确性》开始阅读,了解了Amazon A2I(aws.amazon.com/augmented-ai/)在简化和提高 ML 工作流中人工审阅的准确性方面所发挥的关键作用,从而在过程中启用了主动学习。
在本章中,我们将解决一个已经存在了一段时间、普遍存在、但组织在高效处理上仍然面临困难的操作需求。这就是所谓的PDF 批处理。可以将其视为设置一个自动化文档处理工作流(类似于我们在前几章中构建的工作流),但它增加了批量处理 PDF 文档的灵活性,并结合智能技术,能够自动将文档中某些文本段落路由给人工审阅,原因是由于低置信度检测引起的无法辨认或错误的文本。
到现在为止,由于你在实施先进的 AI 解决方案方面的辛勤努力,LiveRight Holdings的盈利已经飙升。这个增长使得 LiveRight 开始将几个子公司独立出来,成为各自独立的组织,董事会决定这三家公司将在中期公开上市。你已经晋升为 LiveRight 的首席运营架构师,CIO 将任务交给你,要求你构建必要的组件,以便将三家公司作为公开交易公司注册到证券交易委员会(SEC)。
在本章中,我们将讨论以下主题:
-
介绍 PDF 批处理使用案例
-
构建解决方案
技术要求
本章内容需要你访问一个 AWS 账户,你可以通过访问aws.amazon.com/console/来获取。有关如何注册 AWS 账户并登录到AWS 管理控制台的详细说明,请参考第二章《介绍 Amazon Textract》中的注册 AWS 账户子章节。
本章节中讨论的解决方案的 Python 代码和示例数据集可以在本书的 GitHub 仓库中找到:github.com/PacktPublishing/Natural-Language-Processing-with-AWS-AI-Services/tree/main/Chapter%2016。
请查看以下视频,了解代码如何运行:bit.ly/3nobrCo。
引入 PDF 批处理处理用例
要确定架构的样子,你需要与财务部门沟通,了解如何将公司注册到美国证券交易委员会(SEC)的流程。根据该流程,财务部门将使用 SEC 的注册模板生成 PDF 文件,该模板也被称为Form S20(www.sec.gov/files/forms-20.pdf)。该流程还包括创建所有支持文档,并将这些文档与注册信息一同通过 API 调用发送给 SEC。LiveRight 的Partner Integration团队已经与 SEC 达成了合作协议,他们需要将表单数据存储在Amazon DynamoDB(aws.amazon.com/dynamodb/)表中,供他们用于创建向 SEC API 发送消息的调用。
然而,在将数据提供给 Partner Integration 团队之前,财务团队提到,他们需要审核一部分在 PDF 文档中检测到的文本行,特别是那些可能由于文档质量问题而未正确解析的文本。
通过这些信息,你意识到需要在文档处理解决方案中添加一个批处理组件。这将使得能够批量检测 PDF 文档中的文本,并将那些低于置信度阈值的文本行引导至人工审核环节,由财务团队成员进行审核。你决定使用Amazon Textract提供的异步文档文本检测 API,借助其预训练的机器学习模型从 PDF 文档中提取文本,使用Amazon A2I设置人工工作流,审核和修改那些置信度低于 95%的文本,同时利用 Amazon DynamoDB 存储原始检测到的文本以及修正后的内容,供 Partner Integration 团队使用。
我们将使用 Amazon SageMaker Jupyter 笔记本构建我们的解决方案,这将允许我们在逐步执行代码时查看代码和结果。我们将执行以下任务:
-
作为第一步,我们将使用 Amazon SageMaker 控制台创建一个私有标签工作队伍进行人工审核。更多详情,请参考
docs.aws.amazon.com/sagemaker/latest/dg/sms-workforce-private.html。 -
我们将通过检查从 GitHub 仓库克隆的本章示例注册表单来启动解决方案工作流。我们将使用 Amazon Textract 启动一个异步文本检测任务。
-
然后,我们将获取文本检测任务的结果,从文档中选择特定行,并检查检测置信度分数。
-
我们将使用表格任务 UI 模板设置一个 Amazon A2I 人工审查循环,并将每个文档中的文本行发送到人工循环中。
-
以私人工作者身份登录后,我们将处理分配的审查任务,对所有文档中检测置信度较低的文本行进行修改。
-
我们将把检测到并修正的文本行上传到 DynamoDB 表中,以便进行后续处理。
现在我们已经了解了本次练习的背景并过了一遍我们的流程,接下来让我们开始构建解决方案。
构建解决方案
在上一节中,我们介绍了我们的用例——将公司注册提交给 SEC 进行公开交易,涵盖了我们将要构建的解决方案的架构,并简要介绍了解决方案组件和工作流步骤。在这一节中,我们将直接进入正题,开始执行构建解决方案的任务。但首先,我们需要处理一些先决条件。
为解决方案构建做准备
如果你在之前的章节中没有做过,你需要创建一个 Amazon SageMaker Jupyter 笔记本,并设置身份与访问管理(IAM)权限,允许该笔记本角色访问我们将在本笔记本中使用的 AWS 服务。之后,你还需要克隆本书的 GitHub 仓库(github.com/PacktPublishing/Natural-Language-Processing-with-AWS-AI-Services),创建一个 Amazon S3(aws.amazon.com/s3/)存储桶,并在笔记本中提供存储桶的名称以开始执行。
注意
请确保你已经完成了技术要求部分中提到的任务。
请按照以下步骤完成这些任务,然后我们就可以执行笔记本中的单元格了:
-
按照第二章中设置 AWS 环境部分的创建 Amazon SageMaker Jupyter 笔记本实例子节中的说明,创建你的 Jupyter 笔记本实例。
创建 Amazon SageMaker Jupyter 笔记本时的 IAM 角色权限
在创建笔记本时接受默认的 IAM 角色,以允许访问任何 S3 存储桶。
-
一旦你创建了笔记本实例并且其状态为InService,点击笔记本实例的操作菜单中的打开 Jupyter。
-
这将带你到笔记本实例的首页文件夹。
-
点击 New 并选择 Terminal。
-
在终端窗口中,输入
cd SageMaker然后git clone https://github.com/PacktPublishing/Natural-Language-Processing-with-AWS-AI-Services。 -
现在,退出终端窗口,返回到主文件夹,您将看到一个名为
Natural-Language-Processing-with-AWS-AI-Services的文件夹。点击该文件夹以显示章节文件夹,并点击Chapter 16。 -
通过点击打开该文件夹,您应该看到一个名为
Improve-accuracy-of-pdf-processing-with-Amazon-Textract-and-Amazon-A2I-forGitHub.ipynb的笔记本。 -
点击打开此笔记本。
-
按照本笔记本中与本节接下来的子标题相对应的步骤,逐个执行每个单元格。请阅读添加到每个笔记本单元格中的描述。
接下来,我们将介绍一些额外的 IAM 前提条件。
额外的 IAM 前提条件
我们需要为我们的 SageMaker Notebook 角色启用额外的策略。请参阅 第二章 中的 更改 IAM 权限和信任关系以执行 Amazon SageMaker Notebook 角色 子章节,介绍 Amazon Textract 部分,了解如何执行以下步骤的详细说明:
-
如果尚未执行,请将
TextractFullAccess和AmazonAugmentedAIFullAccess策略附加到您的 Amazon SageMaker Notebook IAM 角色。 -
将
iam:PassRole权限作为内联策略添加到您的 SageMaker Notebook 执行角色中:{ "Version": "2012-10-17", "Statement": [ { "Action": [ "iam:PassRole" ], "Effect": "Allow", "Resource": "<your sagemaker notebook execution role ARN"> } ] }
现在,我们已经设置好了笔记本并配置了运行演练笔记本的 IAM 角色,接下来我们将创建私有标注工作队。
为人工循环创建一个私有团队
请参考笔记本中的 Step 0(github.com/PacktPublishing/Natural-Language-Processing-with-AWS-AI-Services/blob/main/Chapter%2016/Improve-accuracy-of-pdf-processing-with-Amazon-Textract-and-Amazon-A2I-forGitHub.ipynb),以了解我们现在将执行的指令。在本节中,我们将使用 Amazon SageMaker 标注工作队控制台创建一个私有团队,并将我们自己作为工人添加到私有团队中。这是为了确保在此解决方案中的 Amazon A2I 步骤时,我们能够登录到标注任务 UI。请执行以下步骤:
-
如果您尚未登录 AWS 管理控制台(请参阅本章开头的 技术要求 部分以了解更多详细信息),请在 Services 搜索栏中输入 Amazon SageMaker 并进入 Amazon SageMaker 控制台。进入控制台后,在 UI 左侧,点击 Ground Truth,然后选择 Labelling workforces。在屏幕上,选择顶部的 Private 标签并点击 Create private team。
-
在团队名称字段中输入您的私人团队名称,并保持创建一个新的 Amazon Cognito 用户组为默认选择,保持在添加工作人员部分。向下滚动并点击创建私人团队。
-
您将返回到
nlp-doc-team团队,并应在arn:aws:sagemaker:region-name-123456:workteam/private-crowd/team-name下可见。请复制此 ARN 并在笔记本的步骤 1 – 单元格 1中提供它:WORKTEAM_ARN= '<your-private-workteam-arn>' -
接下来,向下滚动到前一个屏幕,进入
no-reply@verificationemail.com。按照提供的说明完成注册过程。 -
现在,点击nlp-doc-team,然后点击向团队添加工作人员,将自己添加到私人团队中。从列表中选择您的电子邮件地址并点击向团队添加工作人员。
现在我们已经添加了私人团队,接下来创建一个 Amazon S3 存储桶。
创建一个 Amazon S3 存储桶
请按照 第二章中设置您的 AWS 环境部分的创建一个 Amazon S3 存储桶、文件夹并上传对象小节中的说明,创建您的 Amazon S3 存储桶。如果您在前面的章节中创建了 S3 存储桶,请重复使用该存储桶。本章仅需创建 S3 存储桶。我们将在笔记本中直接创建文件夹并上传对象:
-
获取存储桶名称后,请在笔记本中的步骤 1 – 单元格 1中输入它:
bucket = "<S3-bucket-name>" -
通过点击笔记本 UI 顶部菜单中的步骤 1 – 单元格 1的运行按钮来执行。这样将导入我们需要的库,初始化变量,并为下一组步骤准备好内核。
-
最后,在笔记本中执行步骤 1 – 单元格 2,将注册文档上传到我们的 S3 存储桶:
s3_client = boto3.client('s3') for secfile in os.listdir(): if secfile.endswith('pdf'): response = s3_client.upload_file(secfile, bucket, prefix+'/'+secfile) print("Uploaded {} to S3 bucket {} in folder {}".format(secfile, bucket, prefix))
现在我们已经创建了 S3 存储桶,导入了所需的库,并将文档上传到 S3 存储桶,接下来使用Amazon Textract提取内容。
使用 Amazon Textract 提取注册文档的内容
本节对应于笔记本中的步骤 2和步骤 3(github.com/PacktPublishing/Natural-Language-Processing-with-AWS-AI-Services/blob/main/Chapter%2016/Improve-accuracy-of-pdf-processing-with-Amazon-Textract-and-Amazon-A2I-forGitHub.ipynb)。在本节中,我们将使用 Amazon Textract 提交一个异步文本检测作业。作业完成后,我们将获得文本检测的结果,并将其加载到pandas DataFrame中(pandas.pydata.org/docs/reference/api/pandas.DataFrame.html),选择我们需要的文本行并审查结果。请使用上述笔记本按照这些步骤执行单元格,以完成所需的任务:
-
执行步骤 2 – 单元格 1来定义存储桶句柄,并声明一个字典,用于存储每个文档的 Textract 作业 ID:
input_bucket = s3.Bucket(bucket) jobids = {} -
执行
NotificationChannel属性作为 TextractStartDocumentTextDetectionAPI 的输入(docs.aws.amazon.com/textract/latest/dg/API_StartDocumentTextDetection.html),以指示作业完成时,消息将发送到的 Amazon SNS(aws.amazon.com/sns)主题。您可以设置 AWS Lambda 来订阅该主题,并在收到消息后调用 TextractGetDocumentTextDetectionAPI(docs.aws.amazon.com/textract/latest/dg/API_GetDocumentTextDetection.html)以检索提取的文本。我们将在笔记本中执行该 API,在步骤 3 – 单元格 1中。 -
最后,执行步骤 2 – 单元格 3来打印每个文档的作业 ID:
for j in jobids: print("Textract detection Job ID for {} is {}".format(j,str(jobids[j]))) -
现在,我们必须进入笔记本中的步骤 3。在这里,我们将定义帮助类来解析来自 Textract 的 JSON 响应。然后,我们将需要的文本行加载到字典中,在后续步骤中使用。点击笔记本中的运行以执行步骤 3 – 单元格 1。
-
执行
df_indoc:text_extractor = TextExtractor() indoc = {} df_indoc = pd.DataFrame(columns = ['DocName','LineNr','DetectedText','Confidence', 'CorrectedText', 'Comments']) for x in jobids: pages = text_extractor.extract_text(jobids[x]) contdict =pages[1]['Content'] for row in range(1,(int(len(contdict)/2))+1): df_indoc.loc[len(df_indoc.index)] = [x, row, contdict['Text'+str(row)], round(contdict['Confidence'+str(row)],1),'',''] -
执行步骤 3 – 单元格 3以定义筛选条件,指定在审查注册文件时哪些文本行对我们重要。最后,执行步骤 3 – 单元格 4以创建一个新的 DataFrame,其中只包含我们感兴趣的文本行:
df_newdoc = pd.DataFrame(columns = ['DocName','LineNr','DetectedText','Confidence','CorrectedText','Comments']) for idx, row in df_indoc.iterrows(): if str(row['LineNr']) in bounding_dict['lines'].split(':'): df_newdoc.loc[len(df_newdoc.index)] = [row['DocName'],row['LineNr'], row['DetectedText'], row['Confidence'], row['CorrectedText'],row['Comments']] df_newdoc -
DataFrame 的结果显示在下面的屏幕截图中。这里高亮显示了一些低置信度条目:
图 16.1 – 来自 SEC 注册文件的文本行
注意
由于这些文本条目是故意在 PDF 文档中引入的,以触发低置信度的预测,因此它们显示为乱码。
现在我们已经将注册文件中需要的文本数字化,让我们开始设置使用 Amazon A2I 的人工审核工作流。
设置一个 Amazon A2I 人工工作流循环
对于这里讨论的代码块,请参考笔记本中的步骤 4、步骤 5和步骤 6(github.com/PacktPublishing/Natural-Language-Processing-with-AWS-AI-Services/blob/main/Chapter%2016/Improve-accuracy-of-pdf-processing-with-Amazon-Textract-and-Amazon-A2I-forGitHub.ipynb)。现在是时候使用我们在步骤 0中创建的私人团队设置一个人工工作流,并将结果发送到Amazon A2I人工循环进行审核和修改,如有必要:
-
让我们从初始化一些我们在接下来任务中需要的变量开始。请执行笔记本中的步骤 4 – 单元格 1。
-
执行步骤 4 – 单元格 2,在笔记本中定义我们将用于人工审核活动的任务 UI 模板。我们从 Amazon A2I 样本任务 UI 的 GitHub 仓库中选择了适用于表格数据的任务模板(
github.com/aws-samples/amazon-a2i-sample-task-uis),并根据我们的需求进行了定制。 -
执行步骤 4 – 单元格 3,根据模板创建任务 UI:
def create_task_ui(): response = sagemaker.create_human_task_ui( HumanTaskUiName=taskUIName, UiTemplate={'Content': template}) return response # Create task UI humanTaskUiResponse = create_task_ui() humanTaskUiArn = humanTaskUiResponse['HumanTaskUiArn'] print(humanTaskUiArn) -
我们将获得以下输出:
arn:aws:sagemaker:us-east-1:<aws-account-nr>:human-task-ui /ui-pdf-docs-<timestamp> -
现在,执行笔记本中的步骤 5 – 单元格 1,创建一个Amazon A2I 流定义,以协调任务与工作队伍,并收集输出数据:
create_workflow_definition_response = sagemaker_client.create_flow_definition( FlowDefinitionName=flowDefinitionName, RoleArn=role, HumanLoopConfig= { "WorkteamArn": WORKTEAM_ARN, "HumanTaskUiArn": humanTaskUiArn, "TaskCount": 1, "TaskDescription": "Review the contents and correct values as indicated", "TaskTitle": "SEC Registration Form Review" }, OutputConfig={ "S3OutputPath" : OUTPUT_PATH } ) flowDefinitionArn = create_workflow_definition_response['FlowDefinitionArn'] # let's save this ARN for future use -
执行步骤 5 – 单元格 2,启动人工工作流循环:
for x in range(60): describeFlowDefinitionResponse = sagemaker_client.describe_flow_definition(FlowDefinitionName=flowDefinitionName) print(describeFlowDefinitionResponse ['FlowDefinitionStatus']) if (describeFlowDefinitionResponse ['FlowDefinitionStatus'] == 'Active'): print("Flow Definition is active") break time.sleep(2) -
我们将获得以下结果:
Initializing Active Flow Definition is active -
执行步骤 6 – 单元格 1,将注册文件第一页的扫描图像上传到我们的 S3 存储桶。我们将在 Amazon A2I 任务 UI 中引用这些图像:
reg_images = {} for image in os.listdir(): if image.endswith('png'): reg_images[image.split('_')[0]] = S3Uploader.upload(image, 's3://{}/{}'.format(bucket, prefix)) -
执行步骤 6 – 单元格 2,为我们用例中的所有三份注册文件启动人工循环。在此单元格中,我们将为每个人工循环创建一个随机名称,选择每份文件中低于 95%置信度阈值的特定行,并将这些输入发送到 Amazon A2I 的StartHumanLoop API 调用(
docs.aws.amazon.com/augmented-ai/2019-11-07/APIReference/API_StartHumanLoop.html):humanLoopName = {} docs = df_newdoc.DocName.unique() # confidence threshold confidence_threshold = 95 for doc in docs: doc_list = [] humanLoopName[doc] = str(uuid.uuid4()) for idx, line in df_newdoc.iterrows(): # Send only those lines whose confidence score is less than threshold if line['DocName'] == doc and line['Confidence'] <= confidence_threshold: doc_list.append({'linenr': line['LineNr'], 'detectedtext': line['DetectedText'], 'confidence':line['Confidence']}) ip_content = {"document": doc_list, 'image': reg_images[doc.split('.')[0]] } start_loop_response = a2i.start_human_loop( HumanLoopName=humanLoopName[doc], FlowDefinitionArn=flowDefinitionArn, HumanLoopInput={ "InputContent": json.dumps(ip_content) } ) -
执行步骤 6 – 单元格 3,检查我们人工循环的状态;状态应为进行中:
completed_human_loops = [] for doc in humanLoopName: resp = a2i.describe_human_loop(HumanLoopName=humanLoopName[doc]) print(f'HumanLoop Name: {humanLoopName[doc]}') print(f'HumanLoop Status: {resp["HumanLoopStatus"]}') print(f'HumanLoop Output Destination: {resp["HumanLoopOutput"]}') print('\n') -
现在,我们将登录到 Amazon A2I 任务 UI,审查并修改文本行。让我们登录到工作人员门户,审查预测并根据需要进行修改。执行步骤 6 – 单元格 4,获取我们的任务 UI 的 URL:
workteamName = WORKTEAM_ARN[WORKTEAM_ARN.rfind('/') + 1:] print("Navigate to the private worker portal and do the tasks. Make sure you've invited yourself to your workteam!") print('https://' + sagemaker.describe_workteam(WorkteamName=workteamName)['Workteam']['SubDomain']) -
使用你在步骤 0中设置的凭据登录任务 UI,凭据是在创建标注工作队时设置的。你会看到一个名为SEC 注册表单审核的任务。选择它并点击开始工作。
-
原始注册表单的第一页将显示:
图 16.2 – 任务 UI 显示带有难以辨认文本的注册表单图像
-
向下滚动页面,找到一个表格,显示 Textract 检测到的内容、文本行的置信度分数、一个单选按钮用于检查我们是否认为检测到的文本是正确还是错误、一个输入区域用于修改检测到的文本,还有一个评论字段。修改表格后,点击页面左下角的提交按钮:
图 16.3 – Amazon A2I 中的文档修改页面
-
现在,任务 UI 将刷新,显示我们提交给 Amazon A2I 进行人工审核的三个文档中的下一个文档。重复前述两步,审查图像,滚动表格以进行修改,并点击提交。你还需要为最后一个文档重复此过程。
-
完成所有三个文档的更改并提交任务后,返回笔记本,执行步骤 6 – 单元格 5以检查人工审核环节的状态。所有三个人工审核环节的状态将为已完成。
-
最后,执行笔记本中的步骤 6 – 单元格 7,以获取人工审核员所做的更改,并将其添加到我们的 DataFrame 中。检查 DataFrame 时,我们将看到以下结果:
图 16.4 – A2I 人工审核结果已更新
在本节中,我们通过使用 Amazon Textract 异步 API 从多个 PDF 文档中提取文本,涵盖了此解决方案的大部分处理需求。之后,我们使用 Amazon A2I 设置了一个人工审核环节,审查并修正低置信度的文本检测结果。作为我们解决方案的最后一步,我们将保存我们的活动结果。
为下游处理存储结果
现在我们已经了解如何设置审核工作流,接下来让我们将结果持久化,以便下游应用程序使用。我们将在本节中执行笔记本中的步骤 7:
-
执行步骤 7 – 单元格 1来创建一个Amazon DynamoDB表,这是一个用于存储和访问键值对的托管数据库服务,具有非常低的延迟。
-
执行步骤 7 – 单元格 2来将我们的 DataFrame 内容上传到 DynamoDB 表:
for idx, row in df_newdoc.iterrows(): table.put_item( Item={ 'row_nr': idx, 'doc_name': str(row['DocName']) , 'line_nr': str(row['LineNr']), 'detected_line': str(row['DetectedText']), 'confidence': str(row['Confidence']), 'corrected_line': str(row['CorrectedText']), 'change_comments': str(row['Comments']) } ) print("Items were successfully created in DynamoDB table") -
值将被插入到 DynamoDB 表中,如下所示:
图 16.5 – 在 DynamoDB 中纠正的注册文档条目
解决方案构建到此结束。请参考 进一步阅读 部分,以获取使用 AWS Lambda 和 CloudFormation 构建类似解决方案的代码示例。
总结
在本章中,我们继续构建先进的 NLP 解决方案,以应对现实世界的需求。我们重点讨论了异步处理 PDF 文档,并通过使用 Amazon Textract 和 Amazon A2I 审查和修改低置信度检测结果来提高其准确性。
我们了解了如何为需要提取文本的公司注册到 SEC 使用案例,然后验证并修改文档中的特定文本行,以便在提交给合作伙伴集成团队进行提交到 SEC 之前进行处理。我们考虑了一个为扩展性和易于设置而构建的架构。我们假设你是负责监督该项目的首席架构师,然后我们在 介绍 PDF 批处理使用案例 部分概述了解决方案组件。
接下来,我们讨论了解决方案构建的先决条件,设置了一个 Amazon SageMaker Notebook 实例,克隆了我们的 GitHub 仓库,并根据本章提供的说明开始执行 Notebook 中的代码。我们涉及了使用 Amazon SageMaker 标注工作队伍设置私有工作团队,使用 Amazon Textract 以批处理模式从 PDF 文档中提取相关内容,将检测结果转发到 Amazon A2I 人工审核循环,使用 UI 完成人工任务步骤,审查结果,并将文档内容及其修改存储到 Amazon DynamoDB 表中,以便后续处理。
在下一章中,我们将讨论 Amazon Textract 的另一个有趣功能——手写检测,以及如何设置解决方案来检测手写内容,以供审查、修改和使用。
进一步阅读
请参考以下资源以获取更多信息:
-
通过 Amazon Textract、Amazon Comprehend 和 Amazon Lex 从发票中提取对话性见解,作者:Mona Mona、Prem Ranga 和 Saida Chanda(
aws.amazon.com/blogs/machine-learning/deriving-conversational-insights-from-invoices-with-amazon-textract-amazon-comprehend-and-amazon-lex/)。 -
Amazon Textract 异步操作文档(
docs.aws.amazon.com/textract/latest/dg/async.html)。