写点什么

使用 R 和 Amazon Web Services 进行文档分析

  • 2020-04-05
  • 本文字数:4353 字

    阅读完需:约 14 分钟

使用 R 和 Amazon Web Services 进行文档分析

在我们以前的博文中,我们讨论了 R 的基本知识和 AWS 上 R 的常见工作负载对。在这个两篇系列文章的第二篇中,我们将更加深入的探讨如何使用 AWS 服务构建文档处理应用程序。我们将介绍如何将 AWS 与 R 结合使用来创建数据管道,以便从 PDF 中提取数据供以后处理。


在本示例中,我们从 Amazon Simple Storage Service (Amazon S3) 中存储的 PDF 开始,使用 Amazon Textract 提取文本和表格形式的信息,然后将数据上传到 PostgreSQL Amazon Relational Database Service (Amazon RDS) 数据库。我们将使用 Paws AWS 开发工具包从 R 运行时中访问所有这些服务。下图显示了它的工作原理。



对研究人员来说,很难从 PDF 和图像中提取大量有价值的数据来进行分析。例如,SEC Form 10-K 年度财务报告、报纸文章的扫描件、历史文档、FOIA 回应等等。分析它们中的数据在逻辑上是不切实际的,但现在,使用更好的机器学习技术,我们可以开始将它们用作研究的数据源。


在本文的示例中,我们使用的是联邦储备银行制作的包含美国经济历史预测的 PDF 文档,称为 Greenbook 预测(或 Greenbook 数据集)。这些 PDF 由文本组成,中间穿插着表格和图形,额外增加了难度。Greenbook 预测由费城联邦储备银行提供


在本文中,我们假设您已经有包含 PDF 和 Amazon RDS 数据库的现有 S3 存储桶。虽然您可以从 R 内创建这些 AWS 资源,但我们还是建议您使用专为预置基础设施而设计的工具,例如 AWS CloudFormationAWS 管理控制台或 Terraform。


我们还假设您已经配置本地凭证来访问 Amazon Textract。您可以通过导入环境变量并将它们存储在凭证文件中,或者在 EC2 实例或者附加了具有适当权限的 AWS Identity and Access Management (IAM) 角色的容器中运行 R 来实现此配置。如果没有,您必须明确提供凭证;您可以在以前的文章中查看相关文档,并在 Paws 文档中查看明确的说明。

提取文本和表格

众所周知,从 PDF 中提取数据很难。最早的 Greenbook 预测 PDF 是 20 世纪 60 年代编制的原始报告页面的图片。较新的报告使用 PDF 版面语言,但即便如此,PDF 中也没有底层结构,只有位于页面上各个点的字符。


为了从这些 PDF 中获取有用的数据,用户必须使用光学字符识别将文本图片转换为字符(需要时),然后根据这些字符在页面上的位置推断句子、段落和语篇结构。Greenbook 预测中还包含表格。在此,我们需要识别表格的位置,然后根据页面上的单词或数字的位置和间隔来重建表格的行和列。


为执行此操作,我们使用 AWS 托管的 AI 服务 Amazon Textract 从图片和 PDF 中获取数据。借助适用于 R 的 Paws 开发工具包,我们可以使用操作 start_document_text_detection 获取 PDF 文档的文本,并且可使用操作 start_document_analysis 获取文档的表格和表单。


这些操作属于异步操作,这表示,它们将初始化文本检测和文档分析作业,从而返回特定作业的标识符,我们可以对此标识符进行轮询以检查完成状态。作业完成后,我们可以通过传入作业 ID,分别使用第二个操作 get_document_text_detectionget_document_analysis 检索结果。


我们使用以下代码获取单个文档的表格数据。我们告知 Amazon Textract 文档在 S3 存储桶中的位置,Amazon Textract 则会将即将开始的文档分析作业的 ID 返回给我们。然后 Textract 在后台读取文件并执行分析。同时,我们可以继续检查作业是否完成,然后在作业完成后,立即获取结果。


Bash


textract <- paws::textract()
analyze_document <- function(bucket, file) {
# Start analyzing the PDF. resp <- textract$start_document_analysis( DocumentLocation = list( S3Object = list(Bucket = bucket, Name = file) ), FeatureTypes = "TABLES" )
# Check that the analysis is done and get the result. count <- 0 while (count < 30 && (!exists("result") || result$JobStatus == "IN_PROGRESS")) { Sys.sleep(1) result <- textract$get_document_analysis( JobId = resp$JobId ) count <- count + 1 } return(result)}
analysis <- analyze_document("my-bucket", "GS-1966-01-11.pdf")
复制代码


这是一个简化的示例;事实上,我们可能会同时开始所有的文档分析作业,然后再收集所有结果,因为作业可能并行运行。此外,分析结果可能会太大,无法一次性全部发送,您可能需要单独获取额外的部分;文本结尾处提供的完整的源代码列表可处理此情况。


我们从 Textract 文档分析作业中重获的结果将分为多个数据块。对于包含表格的文档,有些数据块为 TABLE 数据块,表的单元格在 CELL 数据块中,而单元格的内容在 WORD 数据块中。您可以在 Textract 表格文档中阅读关于它们的运行方式的更多信息。


现在,我们需要将 Textract 结果转换为我们可以更轻松使用的形状。首先,我们来看看原始形式的表格,及如何通过 Textract 将该表格返回给我们。下面是 1966 年 1 月文档第三部分的表格。



下面是 Textract 分析返回的三个示例数据库:


1.这是此表格的数据块;您可以在下面看到,它的 BlockTypeTABLE,它来自第 3 页(在页面元素中),且在关系下拥有 256 个子数据库(单元格)。


Bash


# List of 13# $ BlockType      : chr "TABLE"# $ Confidence     : num 100# $ Text           : chr(0) # $ RowIndex       : int(0) # $ ColumnIndex    : int(0) # $ RowSpan        : int(0) # $ ColumnSpan     : int(0) # $ Geometry       :List of 2# .. <not shown># $ Id             : chr "c6841638-d3e0-414b-af12-b94ed34aac8a"# $ Relationships  :List of 1# ..$ :List of 2# .. ..$ Type: chr "CHILD"# .. ..$ Ids : chr [1:256] "e1866e80-0ef0-4bdd-a6fd-9508bb833c03" ...# $ EntityTypes    : list()# $ SelectionStatus: chr(0) # $ Page           : int 3
复制代码


2.这是表格第 1 行第 2 列的单元格,如 RowIndexColumnIndex 元素所示。此单元格有一个子数据块。


Bash


# List of 13# $ BlockType      : chr "CELL"# $ Confidence     : num 100# $ Text           : chr(0) # $ RowIndex       : int 1# $ ColumnIndex    : int 2# $ RowSpan        : int 1# $ ColumnSpan     : int 1# $ Geometry       :List of 2# .. <not shown># $ Id             : chr "132b0343-0172-4ddd-bf30-12f133f0f31d"# $ Relationships  :List of 1# ..$ :List of 2# .. ..$ Type: chr "CHILD"# .. ..$ Ids : chr "5734871f-5a7f-460e-a5f5-dd42bbc57a27"# ...
复制代码


3.最后是上述单元格中的单词数据块,其中包含文本 Year。``


Bash


# List of 13# $ BlockType      : chr "WORD"# $ Confidence     : num 99.8# $ Text           : chr "Year"# ...
复制代码


要重建表格,我们使用每个单元格的行和列编号合并表格中的所有单元格。下面的代码可执行此操作;它将返回文档中所有表格的列表,每个都以矩阵形式。该代码通过以下操作实现这一点:


  1. 逐个迭代每个表格的单元格

  2. 从单词数据块中提取每个单元格的内容

  3. 将单元格内容插入内存表矩阵中的适当行和列


Bash


get_tables <- function(analysis) {  tables <- list()  blocks <- analysis$Blocks  names(blocks) <- sapply(blocks, function(x) x$Id)
for (block in blocks) {
if (block$BlockType == "TABLE") { cells <- get_children(block, blocks) rows <- max(sapply(cells, function(x) x$RowIndex)) cols <- max(sapply(cells, function(x) x$ColumnIndex)) table <- matrix(nrow = rows, ncol = cols)
# 1.Go through a table's cells one-by-one for (cell in cells) {
# 2.Get the cell's contents words <- get_children(cell, blocks) text <- paste(sapply(words, function(x) x$Text), collapse = " ")
# 3.Insert the cell contents into the matrix row <- cell$RowIndex col <- cell$ColumnIndex table[row, col] <- text } tables <- c(tables, list(table)) } } return(tables)}
tables <- get_tables(analysis)
复制代码


请注意,上面的函数get_children 可获取数据块的子数据库;为了简洁起见,此处予以省略,但显示在本文结尾提供的源代码列表中。


此代码产生类似以下内容的矩阵,这非常好:



要在我们的所有 PDF 上运行这个相同过程,我们只需要从 S3 中获取 PDF 列表,我们可以使用 S3 list_objects 操作获取此列表。然后,我们可以循环处理所有可用的 PDF,并使 Textract 通过多个并行处理作业获取其文本和表格。

将数据上传到数据库

现在,我们已经处理好表格,接下来将它们上传到我们的 PostgreSQL 数据库中,以便稍后进行进一步的下游分析。


在 RDS 上运行的适当配置的 PostgreSQL 服务器支持通过 IAM 进行身份验证,从而无需存储密码。如果我们使用具有适当权限的 IAM 用户或角色,我们可以使用 IAM 身份验证令牌从 R 连接到我们的 PostgreSQL 数据库。Paws 软件包也支持此功能;在 AWS 开源计划的支持下开发的功能。


我们使用 build_auth_token 生成的令牌从 Paws 软件包连接到我们的数据库。


Bash


# Connect to the database using an IAM authentication token.rds <- paws::rds()token <- rds$build_auth_token("myhost:5432", "us-east-1", "david")con <- DBI::dbConnect(    RPostgres::Postgres(),    host = "myhost", port = 5432, dbname = "mydb",    user = "david", password = token)
复制代码


在此连接下,我们将结果上传到数据库中的表格。由于我们从文档中获取的表格不一定都拥有相同的形状,我们将它们上传为 JSON 数据。PostgreSQL 的其中一项功能为,它在本地允许我们将任何形状的数据存储在 JSON 列中。


Bash


# Create rows for each table to insert into the database.database_rows <- data.frame(  document = "GS-1966-01-11.pdf",  table_num = 1:length(tables),  data = sapply(tables, jsonlite::toJSON))
# Store the tables in the database.DBI::dbAppendTable(con, name = "tables", value = database_rows)
复制代码


现在,数据已在数据库中,我们可以轻松访问它,以便今后进行分析。

后续步骤

在此实现中,由于 R 默认为单线程,一次将处理一个文档(按顺序)。在较为复杂的实现中,我们可以使用 parallelfutures 软件包来并行处理这些文档,或者无需等待每个文档处理完成。由于复杂性增加,我们避免在本文中展示此情况。对于希望增加自动化的人,可以将 S3 文件上传设置为调用下游计算服务(Lambda、ECS)的事件触发器,这些计算服务可以执行此处引用的代码。


本文转载自 AWS 技术博客。


原文链接:https://amazonaws-china.com/cn/blogs/china/using-r-with-amazon-web-services-for-document-analysis/


2020-04-05 08:00562

评论

发布
暂无评论
发现更多内容

JimuBI 积木大屏 v1.9.3 发布,免费可视化大屏

JEECG低代码

大屏设计器 免费大屏 开源大屏

AI智能体在自动化测试中的应用

测吧(北京)科技有限公司

测试

AIP智能体平台:打造高效的超大型文本处理解决方案

大东(AIP内容运营专员)

人工智能

基于javaPoet的缓存key优化实践

京东科技开发者

清华大学AutoDroid-V2,软件测试行业将如何发展

测吧(北京)科技有限公司

测试

清华大学AutoDroid-V2,软件测试行业将如何发展

测试人

软件测试

速来体验!基于有道子曰的翻译大模型2.0正式上线

有道技术团队

人工智能

京东广告生成式召回基于 NVIDIA TensorRT-LLM 的推理加速实践

京东科技开发者

【YashanDB知识库】lYAS-02143 invalid username/password, login denied

YashanDB

数据库 yashandb

【YashanDB知识库】YAS-04115 "SELECT" expected but missing

YashanDB

数据库 yashandb

【YashanDB知识库】yasql执行报错

YashanDB

数据库 yashandb

中药熬制机械加工MES系统

万界星空科技

mes 制造业工厂 机械加工mes 中药加工 中药罐机械加工

“数据飞轮” 理念焕新,助力 2025 企业数智化发展

字节跳动数据平台

【YashanDB知识库】load data一次导入多个文件的数据时报错

YashanDB

数据库 yashandb

焱融存储增速 No.1丨业界顶级性能领跑 AI 存储赛道

焱融科技

人工智能 IDC AI存储 焱融存储

低代码,帮你解决80%重复开发工作!

秃头小帅oi

Java定时任务大盘点:发工资也能“指日可待”

京东科技开发者

函数计算助您 7 分钟极速部署开源对话大模型

阿里巴巴云原生

阿里云 云原生

一款好的低代码开发平台应该是什么样?

伤感汤姆布利柏

等级保护建设方案,密评资料整理合集(Word原件)

金陵老街

等保 等级保护 密码测评 密评

道旅科技借助云消息队列 Kafka 版加速旅游大数据创新发展

阿里巴巴云原生

kafka 阿里云 云原生

推荐4款基于.NET开源、功能强大的CMS建站系统

不在线第一只蜗牛

开源

腾讯二面:Redis与MySQL双写一致性如何保证?

王中阳Go

MySQL 高可用 面试问题 redis 底层原理

CAP:Serverless + AI 让应用开发更简单

阿里巴巴云原生

阿里云 云原生 CAP

探秘淘宝商品SKU信息API接口

科普小能手

数据挖掘 数据分析 淘宝 电商 API 接口

MortiseAI : AI 驱动的工程生产力, 面向 AGI 编程之路

MortiseAI@HugoHu

开发工具 大模型 AI智能体 大模型应用 #AI编程

一篇解决编译原理大作业,基于Flex、Bison设计编译器(含语法分析树和符号表)

EquatorCoco

Linux 算法

如何选择工作机会和offer

老张

面试 求职 职业生涯规划

Triton-Lang在Transformer优化加速中的实践 | 得物技术

得物技术

人工智能 算法

为什么货币政策紧缩但经济持续火爆?

TechubNews

经济形势 货币政策

淘宝天猫API接口深度探索:商品详情与关键词搜索商品列表的高效应用与实战代码

代码忍者

淘宝API接口

使用 R 和 Amazon Web Services 进行文档分析_文化 & 方法_亚马逊云科技 (Amazon Web Services)_InfoQ精选文章