亚马逊AWS官方博客

使用 Amazon Comprehend 和 Amazon Relational Database Service 构建文本分析解决方案

直到现在,从大量非结构化或半结构化内容中提取价值一直都很困难,并且需要机器学习 (ML) 方面的背景。Amazon Comprehend 消除了这些进入障碍,让数据工程师和开发人员可以轻松访问丰富、持续训练的自然语言处理服务。

您可以通过将来自 Amazon Comprehend 的分析与关系业务信息相结合来构建完整的分析解决方案,从而生成有价值的趋势分析。例如,您可以了解在讨论您的品牌、产品或服务的文章中,最常提及哪些竞争产品。客户还可以将客户反馈舆情与客户资料信息结合起来,以便在推出新产品时更好地了解哪些类型的客户会以特定方式做出反应。

S3 中所收集和存储的各种非结构化和半结构化内容(例如社交媒体帖子、新闻文章和日常客户反馈等)快速增长,从而创造了绝佳的机会,让您可以在分析内容时获得宝贵的见解。Amazon Comprehend 能够与 Amazon Relational Database Service (RDS) 无缝配合使用。在本博文中,我们将向您展示如何从数据库开始构建富文本分析视图,而无需学习任何有关用于自然语言处理模型的机器学习的知识。为此,我们将利用 Amazon Comprehend,并配合使用 Amazon Aurora-MySQL 和 AWS Lambda。它们与 Aurora 中的一组触发器相集成,这些触发器在插入数据时触发,用以确定舆情并将其存储回数据库。随后,可以将其与数据库中的其他数据结合使用,以帮助更快地获得深入见解。同样的模式也可以用来集成其他应用程序级的 ML 服务,例如 Amazon Translate,用于翻译内容本身。

重要说明 – 何时不应使用此模式:该模式不适用于具有高速率插入调用(每秒插入的行数超过几十行)的工作负载。我们仅推荐将其用于临时操作,因为这些触发器不是异步的。在 insert 语句后面放置一个 Lambda 函数调用即可为每个此类语句增加几十毫秒的时间。对于高流量的数据源,您应该使用 poll-aggregate-push 方法从主 insert 写入路径中删除 Lambda 调用。

架构

下图显示了我们将在本博客中设置的流程:


图中的箭头显示了以下步骤:

  1. 连接到 phpMyAdmin,这是一个基于 Web 的 MySQL 管理工具。
    重要说明:为了便于读者使用,我们使用 phpMyAdmin。如果您未在 Apache 中启用 SSL/TLS,我们不建议使用 phpMyAdmin。否则,您的数据库管理员密码和其他数据会不安全地在互联网上进行传输。
  2. 将新记录插入 Aurora MySQL 数据库。
  3. 设置为在 INSERT 上触发的触发器会调用 Lambda 函数。
  4. Lambda 函数调用 Amazon Comprehend 来确定文本的舆情。
  5. 舆情将与表中的行一起存储。

立即设置

在 AWS 管理控制台中,启动 CloudFormation 模板。

注意:不要忘记选择密钥对(您的名称会有所不同)。 另外请记下数据库密码。

等到脚本结束。通常大约需要 15 分钟来完成整个堆栈的设置。假设密钥对路径正确无误,AWS CloudFormation 脚本的输出将显示 SSH 命令应有的形式:

设置数据库配置

设置端口转发,以便命中本地 http 端口并通过 SSH 进行连接。

有关更多详情,您可以单击此处:

https://aws.amazon.com/premiumsupport/knowledge-center/connect-ec2-linux-windows/

  1. 设置端口转发后,连接到 phpMyAdmin:
    http://localhost:8080/phpMyAdmin/
  2. 接下来,登录到 phpMyAdmin。从 CloudFormation 脚本配置中使用数据库用户名/密码:
  3. 在顶部导航窗口中选择 SQL:
  4. 现在让我们来创建审核表。粘贴以下内容并选择“Go”(开始):
    CREATE TABLE comprehend_demo.ReviewInfo(
    ReviewId NUMERIC PRIMARY KEY ,
    ReviewText TEXT NOT NULL ,
    sentiment VARCHAR( 30 ) NOT NULL
    )
    

    这用于在我们的关系数据库中展示审核信息,但它可以是需要在其上执行 NLP 的其他文本字段。

  5. 现在我们将创建触发器,在新数据传入时调用存储过程。再次选择顶部的 SQL,粘贴以下内容并选择“Go”(开始):
    DROP TRIGGER IF EXISTS comprehend_demo.TR_Lambda;
    DELIMITER ;;
    CREATE TRIGGER comprehend_demo.TR_Lambda
      AFTER INSERT ON comprehend_demo.ReviewInfo
      FOR EACH ROW
    BEGIN
      SELECT  NEW.ReviewId , NEW.ReviewText
      INTO @ReviewId , @ReviewText;
    
      CALL  Aurora_To_Lambda(@ReviewId , @ReviewText);
        
    END
    ;;
    DELIMITER ;
  6. 最后,我们将创建存储过程。请务必替换后面的 Lambda 函数名称:
    注意:您可以在 CloudFormation 脚本的 OUTPUT 中找到 Lambda ARN。它就是标记为“ComprehendLambdaArn”的输出。

    DROP PROCEDURE IF EXISTS comprehend_demo.Aurora_To_Lambda;
    DELIMITER ;;
    CREATE PROCEDURE comprehend_demo.Aurora_To_Lambda (IN ReviewId NUMERIC, IN ReviewText TEXT) LANGUAGE SQL 
    BEGIN
      CALL mysql.lambda_async('COMPREHEND_LAMBDA_ARN', 
         CONCAT('{ "ReviewId" : "', ReviewId, 
                '", "ReviewText" : "', ReviewText,'"}')
         );
    END
    ;;
    DELIMITER ;

为集群设置 IAM

CloudFormation 脚本会自动设置数据库集群参数组中的参数,但在本练习中,我们会以手动方式将 IAM 权限附加到集群。

  1. 在 RDS 控制台中转到您的集群:
    https://console.aws.amazon.com/rds/home?region=us-east-1#dbclusters
  2. 选择您的集群(根据您的 CloudFormation 脚本,名称可能有所不同),并选择 Cluster actions(集群操作)下的 Manage IAM roles(管理 IAM 角色)
  3. 然后选择 CloudFormation 创建的 IAM 角色,并将其应用于集群:

测试集成

  1. 返回 phpMyAdmin 窗口,再次选择 SQL 选项并粘贴入以下内容:
    insert into comprehend_demo.ReviewInfo (ReviewId, ReviewText) values (1, 'I love this integration');

  2. 现在选择 comprehend_demo.Tables.ReviewInfo 下的表。您会注意到,我们并未输入舆情,但已经有一条舆情填充到其中。这是通过 Amazon Comprehend 自动确定的。

输入更多示例条目

现在在 SQL 窗口中运行以下命令。粘贴全部内容并选择“Go”(开始):

insert into comprehend_demo.ReviewInfo (ReviewId, ReviewText) values (2, 'I ran through this blog in a hour');
insert into comprehend_demo.ReviewInfo (ReviewId, ReviewText) values (3, 'This is great');
insert into comprehend_demo.ReviewInfo (ReviewId, ReviewText) values (4, 'I had issues with VPC limits');
insert into comprehend_demo.ReviewInfo (ReviewId, ReviewText) values (5, 'This blog post is on the AI/ML blog');
insert into comprehend_demo.ReviewInfo (ReviewId, ReviewText) values (6, 'really fantastic');
insert into comprehend_demo.ReviewInfo (ReviewId, ReviewText) values (7, 'uh, not getting it');
insert into comprehend_demo.ReviewInfo (ReviewId, ReviewText) values (8, 'I hated this run through');

目前,我们已经使用 AWS Lambda 和触发器将 Amazon Comprehend 集成到我们的 Aurora 数据集中。

了解背后的原理

在本节中,我们将了解 Lambda 函数的功能。首先,您会注意到代码总共只有 16 行,包括所有的导入语句在内。

Lambda 函数从我们上面创建的存储过程内的 Aurora 数据库中调用。具体来说,以下行会导致它被调用:

  CALL mysql.lambda_async('COMPREHEND_LAMBDA_ARN', 
     CONCAT('{ "ReviewId" : "', ReviewId, 
            '", "ReviewText" : "', ReviewText,'"}')

您会注意到,此过程将获取 ID 和文本,并创建一个传递给 AWS Lambda 的简单 JSON 对象。这是一个异步调用,因为我们使用的是 lambda_async 方法而不是 lambda_sync。

注意:从 Amazon Aurora 版本 1.16 开始,存储过程 mysql.lambda_async 已弃用。如果使用 Aurora 版本 1.16 或更高版本,我们强烈建议您改用本机 Lambda 函数。有关更多信息,请参阅使用本机函数调用 Lambda 函数

在 Lambda 中,系统会传入以下内容:

{“ReviewID”:1, “ReviewText”: “I love this integration”}

我们使用 Python 实现了 Lambda 函数,该函数使用 Boto3 库来调用 Amazon Comprehend。

仅需要这四行代码就能调用 Amazon Comprehend,在文本上执行 NLP,并提取舆情:

comprehend = boto3.client(service_name='comprehend')
jsonresponse= json.dumps(comprehend.detect_sentiment(Text=event['ReviewText'], LanguageCode='en'), sort_keys=True, indent=4)
json_object = json.loads(jsonresponse)
sentiment=json_object["Sentiment"]

该函数从 Amazon Comprehend 服务获取舆情后,该函数仅会获取信息,并将其存储回数据库。  这可以通过以下额外的几行代码来完成:

db = pymysql.connect(host=os.environ['host'],user=os.environ['user'],passwd=os.environ['password'],db=os.environ['db'], autocommit=True)
add_order = ("UPDATE ReviewInfo SET Sentiment=%s WHERE ReviewId=%s;")
db.cursor().execute(add_order, (sentiment,event['ReviewId']))

替代选项

使用触发器来调用 Lambda 不适用于超高速的插入工作负载(每秒超过十几项插入)。我们通常建议进行 AWS Lambda 集成以支持临时操作,因为触发器不是异步的。在 INSERT 语句后面放置一个 Lambda 调用即可为每个此类语句增加几十毫秒的时间。对于高流量的数据源,您或许应该使用 poll-aggregate-push 方法从主 INSERT 写入路径中删除 Lambda 调用。

清除

完成解决方案测试后,删除 CloudFormation 堆栈可使其停止计费。  只需删除 CloudFormation 堆栈即可清理在本博文中创建的所有内容。

有关如何删除 CloudFormation 堆栈的详细说明,请参阅以下说明:https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-console-delete-stack.html

请注意,在极少数情况下,如果 ENI 仍分配给 Lambda 函数并且删除超时,则 VPC 删除将失败。只需等待大约 15 分钟,然后重新删除即可。如果发生这种情况,所有会产生费用的内容也都会被删除。

费用是多少?

如果您在 us-east-1 AWS 区域运行此示例一小时,费用将低于 0.50 USD。  所利用的大部分服务实际上都属于免费套餐,但在成本最高的假设情景下,我们提供了以下计算:

项目 单位 费用
用于 phpMyAdmin t2.medium 的 EC2 1 小时,每小时 0.0464 0.0464 USD
用于 phpMyAdmin 的 EBS 8 GB gp2,每月每 GB 预置存储量 0.10 USD(按秒钟计费) 0.00109589041 USD
Aurora MySQL 计算 db.t2.small,每小时 0.041 USD 0.041 USD
Aurora MySQL 存储 每月每 GB 0.10 USD 0.10 USD
Aurora MySQL IO 每 100 万个请求 0.20 USD 0.20 USD
Lambda 请求 8 个请求,每个请求 0.0000002 USD。 0.0000016 USD
Lambda 计算时间 1 秒 * 8 个调用,每 100 毫秒 0.000000208 0.00001664 USD
预计总额: 约 0.38 USD

结论

通过这种简单的方法,以文本形式存储的反馈可通过先进的 Amazon AI 服务自动进行翻译和/或充实。  我们演示了这种利用舆情调用的方式,但可以轻松将这种方法扩展到提取主题、关键短语、翻译和其他许多功能。

示例代码的已知限制:

目前,在创建 JSON 消息时,本博文中的存储过程无法转义字符串值中的预留字符。如果在调用中需要此功能,可以对其进行修改。


作者简介

Ben Snively 是 AWS 公共部门的一位专业解决方案架构师。他与政府机构、非营利组织和教育行业客户合作开展大数据/分析和 AI/ML 项目,帮助客户利用 AWS 构建解决方案。

Natasha Alexeeva 是一名 AWS 高级业务发展经理,专门研究人工智能和机器学习。她的专长领域包括健康和生命科学行业。 她喜欢为有兴趣探索人工智能强大功能的 AWS 客户构建 POC。