QCon北京|3天沉浸式学习,跳出信息茧房。 了解详情
写点什么

使用 Amazon Textract 和 Amazon Comprehend Medical 实现无服务器化的医疗文档分析(一)

  • 2020-01-09
  • 本文字数:5875 字

    阅读完需:约 19 分钟

使用 Amazon Textract 和 Amazon Comprehend Medical 实现无服务器化的医疗文档分析(一)

场景概述

  • 在医学报告整理和内容提取的场景中,从业人员往往需要花费大量的时间进行内容阅读和关键字的提炼;Amazon Textract 结合 Amazon Comprehend Medical 的解决方案整体采用无服务器化架构,全自动化也提高整体效率。采用该解决方案,可以以秒级的效率提取出需要的内容;除此之外,该架构也大大降低了整体成本,架构中包含的所有服务都以实际使用计费。

  • Amazon Textract 是一个托管的 OCR(Optical Character Recognition) 服务,Amazon Comprehend Medical 是一个医疗语义分析的托管人工智能服务。通过 Amazon Textract 将医学报告和诊断报告的表单表格转化成序列化文档,通过 Amazon Comprehend Medical 对这些序列化文档进行分析并快速获取不同分类的信息。在 CRO(Clinical Research Organization) 等行业场景中,可以通过这个解决方案对医学研究、药物分析及诊断报告提供有效的帮助和补充。

服务架构

  • 在这个架构中,我们需要创建:

  • 一个 Amazon S3 存储桶用来存放输入的文档资料和输出的结果文件

  • 一个用来调用 Amazon Textract API 的 AWS Lambda 函数

  • 一个用来调用 Amazon Comprehend Medical API 的 AWS Lambda 函数



架构逻辑如下:


  1. 以用户向 Amazon S3 传入一个文档为例,上传成功后 AWS Lambda 函数会以该事件作为触发并调用 Amazon Textract API,将该文档内容提取成序列化的文档以及待分析的文本,并存入 Amazon S3 的相应路径

  2. 上述待分析文本传入 Amazon S3 后,又会触发下一个 AWS Lambda 函数,调用 Amazon Comprehend Medical API,对内容进行语义分析,并将分析后的结果写入 Amazon S3

  3. 完成以上自动化的操作后,用户即可查询读取提炼后的内容进行进一步的工作

具体实现

Amazon S3 存储桶配置

  • 创建用于输入和输出医学分析报告的存储桶和桶下面相应目录,例如:

  • 存储桶:s3://medical-report-analysis-<unique_identifier>

  • 这里的<unique_identifier> 用以和其他用户的 S3 存储桶区分,因为 Amazon S3 存储桶的名称具有全球唯一性

  • 文档输入目录:s3://medical-report-analysis-<unique_identifier>/input

  • 手动检查目录:s3://medical-report-analysis-<unique_identifier>/manual

  • 分析输入目录:s3://medical-report-analysis-<unique_identifier>/medical

  • 保护数据目录:s3://medical-report-analysis-<unique_identifier>/phi

  • 原始文档目录:s3://medical-report-analysis-<unique_identifier>/raw

  • 分析结果目录:s3://medical-report-analysis-<unique_identifier>/result



  • 启用 Amazon S3 的版本控制

AWS IAM 权限配置

由于整体技术实现会通过 AWS Lambda 作为粘合剂将几个服务串联起来,所以需要创建相应的 AWS IAM 角色以确保服务之间有权限进行相互调用;以下会创建用于串接 Amazon S3 和 Amazon Textract 的 AWS IAM Role,以及用于串接 Amazon S3 和 Amazon Comprehend Medical 的 AWS IAM Role:


  1. 创建用于串接 Amazon S3 和 Amazon Textract 的 AWS IAM Policy:

  2. 策略名称:LAMBDA_TEXTRACT_S3_RW

  3. 策略文档:


Python


{  "Version": "2012-10-17",  "Statement": [    {      "Effect": "Allow",      "Action": [        "textract:*",        "s3:*",        "cloudwatch:*",        "logs:*",        "iam:GetPolicy",        "iam:GetPolicyVersion",        "iam:GetRole"      ],      "Resource": "*"    },    {      "Effect": "Allow",      "Action": "iam:CreateServiceLinkedRole",      "Resource": "arn:aws:iam::*:role/aws-service-role/events.amazonaws.com/AWSServiceRoleForCloudWatchEvents*",      "Condition": {        "StringLike": {          "iam:AWSServiceName": "events.amazonaws.com"        }      }    }  ]}
复制代码


  1. 创建用于串接 Amazon S3 和 Amazon Textract 的 AWS IAM Role:

  2. 受信任实体:Lambda

  3. 绑定策略:LAMBDA_TEXTRACT_S3_RW

  4. 角色名称:LAMBDA_TEXTRACT_S3_RW_ALL

  5. 创建用于串接 Amazon S3 和 Amazon Comprehend Medical 的 AWS IAM Policy:

  6. 策略名称:LAMBDA_COMPREHENDMEDICAL_S3_RW

  7. 策略文档:


Python


{  "Version": "2012-10-17",  "Statement": [    {      "Effect": "Allow",      "Action": [        "comprehendmedical:*",        "s3:*",        "cloudwatch:*",        "logs:*",        "iam:GetPolicy",        "iam:GetPolicyVersion",        "iam:GetRole"      ],      "Resource": "*"    },    {      "Effect": "Allow",      "Action": "iam:CreateServiceLinkedRole",      "Resource": "arn:aws:iam::*:role/aws-service-role/events.amazonaws.com/AWSServiceRoleForCloudWatchEvents*",      "Condition": {        "StringLike": {          "iam:AWSServiceName": "events.amazonaws.com"        }      }    }  ]}
复制代码


  1. 创建用于串接 Amazon S3 和 Amazon Textract 的 AWS IAM Role:

  2. 受信任实体:Lambda

  3. 绑定策略:LAMBDA_COMPREHENDMEDICAL_S3_RW

  4. 角色名称:LAMBDA_COMPREHENDMEDICAL_S3_RW_ALL

AWS Lambda 函数 – textract_content_ingest

  1. 函数名称:textract_content_ingest

  2. 运行时:Python 3.8

  3. 执行角色:LAMBDA_TEXTRACT_S3_RW_ALL

  4. 内存分配:1024 MB

  5. 超时:1 分钟

  6. 代码如下:


Python


import boto3import json
def lambda_handler(event, context): # File definition s3Key = event['Records'][0]['s3']['object']['key'] keyName = s3Key.split('/')[1].split('.')[0] outFile = '/tmp/output.json' outputKey = 'raw/' + keyName + '/raw.json' medicalRaw = "/tmp/medicalraw.txt" medicalRawKey = 'raw/' + keyName + '/medicalraw.txt' medicalReport = '/tmp/medicalreport.txt' medicalReportKey = 'medical/' + keyName + '/medicalreport.txt'
# S3 and Textract Configuration s3Bucket = event['Records'][0]['s3']['bucket']['name'] fileType = 'FORMS'
# Call Textract to convert form to json textract = boto3.client('textract') textractResponse = textract.analyze_document( Document={ 'S3Object': { 'Bucket': s3Bucket, 'Name': s3Key } }, FeatureTypes=[ fileType ] ) with open(outFile, 'w') as outfile: outfile.write(json.dumps(textractResponse, indent=4))
# Ingest content for blocks in textractResponse['Blocks'][1:]: if blocks['Confidence']: if (blocks['Confidence'] >= 70) and (blocks['BlockType'] == 'LINE'): with open(medicalReport, 'a') as medicalReportOut: medicalReportOut.write(blocks['Text'] + "\r\n") elif (blocks['Confidence'] >= 70) and (blocks['BlockType'] == 'WORD'): with open(medicalRaw, 'a') as medicalRawOut: medicalRawOut.write(blocks['Text'] + "\r\n") else: continue else: print("oops")
# Upload outputs to s3 s3 = boto3.resource('s3') try: s3.meta.client.upload_file(outFile, s3Bucket, outputKey) s3.meta.client.upload_file(medicalReport, s3Bucket, medicalReportKey) s3.meta.client.upload_file(medicalRaw, s3Bucket, medicalRawKey) except Exception as e: print(e) print("Upload failed!") else: print("Upload done!")
复制代码

AWS Lambda 函数 – comprehendmedical_analysis

  1. 函数名称:comprehendmedical_analysis

  2. 运行时:Python 3.8

  3. 执行角色:LAMBDA_COMPREHENDMEDICAL_S3_RW_ALL

  4. 内存分配:1024 MB

  5. 超时:1 分钟

  6. 代码如下:


Python


import boto3import json
def lambda_handler(event, context): # Configure definition s3Bucket = event['Records'][0]['s3']['bucket']['name'] s3Key = event['Records'][0]['s3']['object']['key'] keyName = s3Key.split('/')[1].split('.')[0] localFinal = '/tmp/result.txt' phiFinal = '/tmp/phi.txt' manualFinal = '/tmp/manual.txt' medicalResult = 'result/' + keyName + '/medicalresult.txt' phiResult = 'phi/' + keyName + '/phi.txt' manualResult = 'manual/' + keyName + '/manual.txt'
# Ingest medical report try: s3 = boto3.client('s3') except Exception as e: print(e) print('connect S3 failed!') else: print('connect S3 successfully')
s3_object = s3.get_object(Bucket=s3Bucket, Key=s3Key) body = s3_object['Body']
# Execute medical analysis try: comprehendMedical = boto3.client('comprehendmedical') except Exception as e: print(e) else: print('connect Comprehend Medical successfully')
detectEntities = comprehendMedical.detect_entities_v2( Text=body.read().decode('utf-8') ) detectOutputRaw = detectEntities['Entities']
# Categorize different types of information report_ANATOMY = [] report_MEDICAL_CONDITION = [] report_MEDICATION = [] report_PROTECTED_HEALTH_INFORMATION = [] report_TEST_TREATMENT_PROCEDURE = [] report_MANUAL = []
for ctgy in detectOutputRaw: if ctgy['Score'] >= 0.6: if ctgy['Category'] == 'ANATOMY': report_ANATOMY.append(ctgy) elif ctgy['Category'] == 'MEDICAL_CONDITION': report_MEDICAL_CONDITION.append(ctgy) elif ctgy['Category'] == 'MEDICATION': report_MEDICATION.append(ctgy) elif ctgy['Category'] == 'PROTECTED_HEALTH_INFORMATION': report_PROTECTED_HEALTH_INFORMATION.append(ctgy) elif ctgy['Category'] == 'TEST_TREATMENT_PROCEDURE': report_TEST_TREATMENT_PROCEDURE.append(ctgy) else: continue else: report_MANUAL.append(ctgy)
result_ANATOMY = [] result_MEDICAL_CONDITION = [] result_MEDICATION = [] result_PROTECTED_HEALTH_INFORMATION = [] result_TEST_TREATMENT_PROCEDURE = [] result_MANUAL = []
if report_ANATOMY: for anatomy in report_ANATOMY: result_ANATOMY.append(anatomy['Text']) if report_MEDICAL_CONDITION: for medical_condition in report_ANATOMY: result_MEDICAL_CONDITION.append(medical_condition['Text']) if report_MEDICATION: for medication in report_MEDICATION: result_MEDICATION.append(medication['Text']) if report_PROTECTED_HEALTH_INFORMATION: for protected_health_information in report_PROTECTED_HEALTH_INFORMATION: result_PROTECTED_HEALTH_INFORMATION.append(protected_health_information['Text']) if report_TEST_TREATMENT_PROCEDURE: for test_treatment_procedure in report_TEST_TREATMENT_PROCEDURE: result_TEST_TREATMENT_PROCEDURE.append(test_treatment_procedure['Text']) if report_MANUAL: for test_manual in report_MANUAL: result_MANUAL.append(test_manual['Text'])
with open(localFinal, 'a') as localfile: if result_ANATOMY: localfile.write('Anatomy:\r\n' + '\r\n'.join(set(result_ANATOMY))) if result_MEDICAL_CONDITION: localfile.write('\r\n---\r\n') localfile.write('Medical Condition:\r\n' + '\r\n'.join(set(result_MEDICAL_CONDITION))) if result_MEDICATION: localfile.write('\r\n---\r\n') localfile.write('Medication:\r\n' + '\r\n'.join(set(result_MEDICATION))) if result_TEST_TREATMENT_PROCEDURE: localfile.write('\r\n---\r\n') localfile.write('Test Treatment Procedure:\r\n' + '\r\n'.join(set(result_TEST_TREATMENT_PROCEDURE))) localfile.close()
with open(phiFinal, 'a') as phifile: if result_PROTECTED_HEALTH_INFORMATION: phifile.write('Protected Health Information:\r\n' + '\r\n'.join(set(result_PROTECTED_HEALTH_INFORMATION))) phifile.close()
with open(manualFinal, 'a') as manualfile: if result_MANUAL: manualfile.write('Manually Check:\r\n' + '\r\n'.join(set(result_MANUAL))) manualfile.close()
# Upload outputs to s3 s3Upload = boto3.resource('s3') try: s3Upload.meta.client.upload_file(localFinal, s3Bucket, medicalResult) s3Upload.meta.client.upload_file(phiFinal, s3Bucket, phiResult) s3Upload.meta.client.upload_file(manualFinal, s3Bucket, manualResult)
except Exception as e: print(e) print("Upload failed!") else: print("Upload done!")
复制代码

Amazon S3 事件与 AWS Lambda 集成

  1. 使用拥有 Amazon S3 管理权限的用户登录 AWS 管理控制台

  2. 进入到相应的 Amazon S3 存储桶 (medical-report-analysis-<unique_identifier>)

  3. 切换到“属性”选项卡,点开“事件”

  4. 点击“添加通知”,输入名称“upload_report”,事件勾选 “PUT”,前缀处输入 “input/”,发送到选择 AWS Lambda,选择函数 textract_content_ingest,然后选择保存

  5. 点击“添加通知”,输入名称“comprehendmedical_analysis”,事件勾选 “PUT”,前缀处输入 “medical/”,发送到选择 AWS Lambda,选择函数 comprehendmedical_analysis,然后选择保存


本文转载自 AWS 技术博客。


原文链接:https://amazonaws-china.com/cn/blogs/china/serverless-medical-document-analysis-with-amazon-textract-and-amazon-comprehend-medical/


2020-01-09 15:57783

评论

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

【HarmonyOS NEXT】实战——登录页面

帅比九日

鸿蒙 arkui ArkTS HarmonyOS NEXT

多客校园圈子小程序源码 校园生活综合服务平台 校园服务小程序源码

DUOKE七七

行政人员必备!如何快速生成一批人员信息卡?

草料二维码

从 Llama 1 到 3.1:Llama 模型架构演进详解

Baihai IDP

程序员 AI LLM llama Baihai IDP

反向 Debug 了解一下?揭秘 Java DEBUG 的基本原理

京东科技开发者

SecureCRT for mac(终端SSH工具)

Mac相关知识分享

企业数字化转型现状

芯盾时代

数字化转型 iam

CST软件如何将平面结构弯曲贴到另一个结构上

思茂信息

仿真 cst CST软件

项目申报评审系统(源码+文档+部署+讲解)

深圳亥时科技

AlDente Pro for Mac(MacBook 电池健康的实用小工具)

Mac相关知识分享

记录一次RPC服务有损上线的分析过程

京东科技开发者

套娃嵌入:如何优化向量搜索成本,并兼顾延迟与召回

Zilliz

Milvus 向量搜索 套娃嵌入 向量存储

2024 都要过完了,我不允许你在 Go 中还不会解决 CORS 跨域问题

江湖十年

Go 面试 后端 CORS 跨域

Go语言中的加解密利器:go-crypto库全解析

左诗右码

Go

打造个性化的Allure2报告:定制Logo和样式的软件测试报告

测试人

软件测试

16.迭代器模式设计思想

杨充

商业开源服饰电商大模型-摹图

摹图

AI AI大模型 AI 图像生成

Sketch for mac(专业矢量绘图设计软件)中文版

Mac相关知识分享

如何把苹果电脑里的照片导出至U盘 Mac照片批量拷到移动硬盘

阿拉灯神丁

存储 拷贝 硬盘 Tuxera NTFS教程 mac 效率工具

2025山西晋中等保测评机构地址在哪里?电话多少?

行云管家

等保 等保测评 晋中

公共事业信息系统怎么定义?需要过等保吗?

行云管家

信息系统 等保 等保测评 公共事业

FL Studio提速这样做!告别卡顿、闪退,畅快编曲

阿拉灯神丁

音乐制作 编曲软件 FL Studio2024 FL水果

社区论坛小圈子小程序源码系统:自定义小程序管理社区圈子软件圈子系统系统开发-做社区圈子丨圈子论坛社区交友系统开源版小程序源码丨

DUOKE七七

php 源码 开源软件

IPQ5312, IPQ5322, and IPQ5332: Analysis of Differences and Applications in WiFi 7 Motherboard Chips

wifi6-yiyi

5G WiFi7 6G

俯瞰 Monorepo,别一番风景!

蛋先生DX

前端 前端架构 前端工程化 Monorepo

【行云流水线】满足你对工作流编排的一切幻想~skr

京东科技开发者

一键擦除手写笔迹,试试这款省时省力的学习利器

合合技术团队

学习 手写识别 文字擦除 人工智能】

DoH与DoT协议:增强DNS安全性的双保险

代码忍者

HyperWorks基于几何投影的网格变形

智造软件

仿真 altair hyperworks

拼多多商品详情数据接口(Pdd.item_get)丨拼多多API接口指南

tbapi

拼多多商品详情接口 拼多多API接口

XMind for mac (XMind思维导图)中文版

Mac相关知识分享

使用 Amazon Textract 和 Amazon Comprehend Medical 实现无服务器化的医疗文档分析(一)_行业深度_亚马逊云科技 (Amazon Web Services)_InfoQ精选文章