目次
Amazon Comprehend Medical 完全ガイド v2.0
初心者から実務者向けの包括的解説
Amazon Comprehend Medical は、医療・臨床テキストから構造化された医療情報を自動抽出する NLP サービスです。診断名・症状・薬剤・手術・投薬量・患者情報などを医療テキストから自動識別し、ICD-10-CM(疾患分類)・RxNorm(薬剤)・SNOMED CT(医療用語)との自動マッピングも提供します。HIPAA 準拠の PHI(保護対象健康情報)検出・匿名化で医療データのコンプライアンス処理を自動化します。本ドキュメントは、Comprehend Medical の概念・アーキテクチャ・設計パターン・エコシステム・2025-2026 の最新動向を体系的に解説する包括的ガイドです。
ドキュメントの目的
本ガイドは以下を対象としています。
- 初心者向け: Comprehend Medical とは何か、医療 NLP の基本を学びたい方
- 医療 IT 向け: 電子カルテ(EMR)の構造化・コーディング自動化の実装
- 臨床研究向け: コホート選定・患者データ抽出の効率化
- バイオインフォマティクス向け: 有害事象報告・ファーマコビジランス
- 意思決定者向け: Google Cloud Healthcare API・Azure Health Bot との比較
2026 年の Comprehend Medical エコシステム
- Custom Entity Recognition for Medical: カスタム医療エンティティの学習・検出
- SNOMED CT マッピング拡張: より詳細な医療概念マッピング
- Bedrock 統合: 生成 AI による医療テキストのサマリー化
- HealthLake との連携: EMR データの一括処理・統一フォーマット化
- 連邦学習対応 (検討中):オンプレ医療データの安全な分析
- 多言語医療 NLP:日本語・中国語への対応拡大
定義
AWS 公式による定義:
“Amazon Comprehend Medical is a natural language processing (NLP) service that extracts medical information from unstructured clinical text.”
特徴:
- 医療特化 NLP: 医療用語・略語・文脈を正確に理解
- ICD-10-CM マッピング: 医療請求コーディング自動化
- PHI 検出・匿名化: HIPAA コンプライアンス
- 複数オントロジー: ICD-10-CM / RxNorm / SNOMED CT
- 信頼スコア: 検出精度の定量化
目次
- 概要
- Comprehend Medical が解決する課題
- 主な特徴
- 医療エンティティ検出
- ICD-10-CM / RxNorm / SNOMED CT マッピング
- PHI 検出・匿名化
- アーキテクチャ
- 主要ユースケース
- 設定・操作の具体例
- CLI 操作
- SDK 実装例
- IaC (CloudFormation/Terraform)
- 類似サービス比較表
- ベストプラクティス
- トラブルシューティング
- セキュリティ・コンプライアンス
- パフォーマンスチューニング
- コスト最適化
- 2025-2026 最新動向
- 学習リソース・参考文献
- 実装例・チェックリスト
- まとめ
概要
初心者向けメモ: Comprehend Medical は「医療テキスト専用の NLP サービス」です。汎用 Comprehend では医療用語(HTN=高血圧、DM=糖尿病、qd=1 日 1 回)を正確に解釈できませんが、Comprehend Medical は医療訓練データで学習したため医療テキストを高精度に処理します。
Comprehend Medical は以下を実現します:
- 医療エンティティ抽出 - 症状・薬剤・検査・治療を自動識別
- ICD-10-CM 自動コーディング - 医療請求の自動コード化
- PHI 検出・匿名化 - HIPAA 準拠のデータ処理
- RxNorm マッピング - 薬剤名の標準化
- 信頼スコア - 検出精度を定量化
- スケール - 毎秒数千ドキュメント処理可能
Comprehend Medical が解決する課題
1. 医療テキストのコーディング作業が人手
課題: 医師の手書き診断記録を ICD-10-CM コードに変換するのは医療コーダーの負担
Comprehend Medical の解決:
医師記録: "2型糖尿病、高血圧症、神経障害"
↓
Comprehend Medical
├── "2型糖尿病" → ICD-10-CM: E11
├── "高血圧症" → ICD-10-CM: I10
└── "神経障害" → ICD-10-CM: G60-G99
↓
自動請求コード提案 → コーダー検証(工数削減)
2. PHI(個人識別情報)の検出・除去が複雑
課題: 臨床研究で患者データを共有する際、氏名・生年月日・住所を手動で除去?
Comprehend Medical の解決:
カルテテキスト: "田中太郎(1980-01-15、東京都渋谷区)"
↓
DetectPHI API
├── PATIENT: "田中太郎"
├── DATE: "1980-01-15"
└── ADDRESS: "東京都渋谷区"
↓
自動マスキング: "[PATIENT]([DATE]、[ADDRESS])"
↓
匿名化データで安全に研究利用
3. 医療 NLP が複雑・低精度
課題: 医療テキストを自分で NLP モデル訓練? 汎用 NLP では精度不足
Comprehend Medical の解決: 事前訓練済み医療 NLP(精度 95%+)
主な特徴
| 特徴 | 説明 |
|---|---|
| 医療特化 | 医療用語・文脈を高精度に理解 |
| 複数エンティティ | 症状・薬剤・検査・治療・解剖学を検出 |
| ICD-10-CM | 疾患コードの自動マッピング |
| RxNorm | 薬剤名の標準化・マッピング |
| SNOMED CT | 医療概念の標準オントロジーマッピング |
| PHI 検出 | 患者氏名・住所・生年月日を自動検出 |
| 信頼スコア | 各検出の確信度を 0-1 で定量化 |
| HIPAA 対応 | 医療データ安全処理・匿名化 |
| スケール | API 形式で任意規模・リアルタイム対応 |
医療エンティティ検出
DetectEntitiesV2 API
医療テキストから自動抽出するエンティティ:
| エンティティ | 例 |
|---|---|
| MEDICAL_CONDITION | “2型糖尿病”、“高血圧症”、“発熱” |
| MEDICATION | “メトホルミン 1000mg”、“アスピリン” |
| TEST_TREATMENT_PROCEDURE | “血液検査”、“MRI”、“手術名” |
| ANATOMY | “左心室”、“右膝”、“肺” |
| PROTECTED_HEALTH_INFORMATION | 患者名、生年月日、住所、電話番号 |
| DOSAGE | “1 日 2 回”、“100mg” |
| STRENGTH | “500mg”、“10%” |
| ROUTE | “経口”、“静脈注射” |
| FREQUENCY | “毎日”、“週 3 回” |
レスポンス例
{
"Entities": [
{
"Id": 0,
"BeginOffset": 0,
"EndOffset": 8,
"Score": 0.99,
"Text": "2型糖尿病",
"Category": "MEDICAL_CONDITION",
"Type": "DIAGNOSIS",
"Traits": [{"Name": "DIAGNOSIS"}]
},
{
"Id": 1,
"BeginOffset": 20,
"EndOffset": 32,
"Score": 0.95,
"Text": "メトホルミン 500mg",
"Category": "MEDICATION",
"Type": "GENERIC_NAME",
"Traits": [
{"Name": "FORM", "Score": 0.95},
{"Name": "DOSAGE", "Score": 0.92}
]
}
]
}
ICD-10-CM / RxNorm / SNOMED CT マッピング
InferICD10CM
医療条件を ICD-10-CM コードに自動変換:
入力: "患者は 2型糖尿病と高血圧症の診断"
↓
出力:
[
{
"Text": "2型糖尿病",
"ICD10CMConcepts": [
{
"Code": "E11",
"Description": "Type 2 diabetes mellitus",
"Score": 0.98
}
]
},
{
"Text": "高血圧症",
"ICD10CMConcepts": [
{
"Code": "I10",
"Description": "Essential (primary) hypertension",
"Score": 0.97
}
]
}
]
InferRxNorm
薬剤名を RxNorm コード化:
入力: "患者にメトホルミン 1000mg を 1 日 2 回処方"
↓
出力:
{
"Medication": {
"Text": "メトホルミン",
"RxNormConcepts": [
{
"Code": "6809",
"Description": "Metformin",
"Score": 0.99
}
],
"Dosage": "1000mg",
"Frequency": "1 日 2 回"
}
}
InferSNOMEDCT
医療概念を SNOMED CT オントロジーにマッピング:
入力: "左膝の変形性関節症"
↓
出力:
{
"Condition": "左膝の変形性関節症",
"SNOMEDCTConcepts": [
{
"Code": "202625002",
"Description": "Osteoarthritis of knee",
"Anatomy": "膝関節"
}
]
}
PHI 検出・匿名化
DetectPHI API
保護対象健康情報を自動検出:
text = "患者 山田太郎(生年月日 1980-05-15)は東京都渋谷区在住。" \
"電話: 090-1234-5678。メール: yamada@example.com"
response = client.detect_phi(Text=text)
# 出力
{
"Entities": [
{
"Type": "PATIENT",
"Score": 0.98,
"BeginOffset": 3,
"EndOffset": 8,
"Text": "山田太郎"
},
{
"Type": "DATE",
"Score": 0.96,
"BeginOffset": 13,
"EndOffset": 24,
"Text": "1980-05-15"
},
{
"Type": "ADDRESS",
"Score": 0.95,
"BeginOffset": 26,
"EndOffset": 33,
"Text": "東京都渋谷区"
},
{
"Type": "PHONE_OR_FAX",
"Score": 0.99,
"BeginOffset": 39,
"EndOffset": 52,
"Text": "090-1234-5678"
},
{
"Type": "EMAIL",
"Score": 0.97,
"BeginOffset": 57,
"EndOffset": 77,
"Text": "yamada@example.com"
}
]
}
自動匿名化
def anonymize_text(text, phi_entities):
for entity in sorted(phi_entities, key=lambda x: x['BeginOffset'], reverse=True):
start = entity['BeginOffset']
end = entity['EndOffset']
entity_type = entity['Type']
replacement = f"[{entity_type}]"
text = text[:start] + replacement + text[end:]
return text
# 結果
"患者 [PATIENT](生年月日 [DATE])は[ADDRESS]在住。" \
"電話: [PHONE_OR_FAX]。メール: [EMAIL]"
アーキテクチャ
graph TB
Clinical["医療テキスト<br/>(カルテ・退院サマリー・処方箋)"]
DetectEntities["DetectEntitiesV2<br/>(エンティティ抽出)"]
ICD10["InferICD10CM<br/>(疾患コード化)"]
RxNorm["InferRxNorm<br/>(薬剤コード化)"]
SNOMED["InferSNOMEDCT<br/>(医療概念マッピング)"]
DetectPHI["DetectPHI<br/>(個人情報検出)"]
Anonymize["匿名化・マスキング"]
Clinical -->|症状・薬剤・検査| DetectEntities
DetectEntities -->|医療条件| ICD10
DetectEntities -->|薬剤名| RxNorm
DetectEntities -->|医療概念| SNOMED
Clinical -->|個人情報| DetectPHI
DetectPHI -->|検出結果| Anonymize
ICD10 --> Output["構造化データ<br/>(医療 DB / BI)"]
RxNorm --> Output
SNOMED --> Output
Anonymize --> Output["匿名化データ<br/>(研究・共有)"]
主要ユースケース
-
電子カルテ(EMR)の構造化
- 自由記述テキストを ICD-10-CM・RxNorm で構造化
- コーディング工数 50-70% 削減
-
医療請求自動化
- 医師記録から診断コードを自動抽出
- 請求コード精度向上・収益サイクル高速化
-
臨床研究コホート選定
- 特定の疾患・投薬履歴の患者を自動抽出
- 大量医療記録から研究対象者を効率的に特定
-
データ匿名化(HIPAA 準拠)
- カルテから PII を自動検出・マスキング
- 研究用データセットの安全な作成
-
薬剤相互作用分析
- 投薬記録から薬剤を自動抽出
- RxNorm で標準化後、相互作用 DB と照合
-
ファーマコビジランス
- 有害事象報告書から症状・薬剤を抽出
- 医薬品の安全性監視を効率化
-
AI 医療分析
- Bedrock と組み合わせて医療テキストのサマリー化
- 医師の意思決定サポート
-
医療データの BI / 分析
- 構造化データで BI ダッシュボード構築
- 患者集団の疾患・投薬パターン分析
-
医療データレイク構築
- 複数病院のカルテを統一フォーマットで統合
- HealthLake との連携
-
多言語医療情報処理
- 複数言語のカルテを統一スキーマで処理
- グローバル臨床試験の患者データ整理
設定・操作の具体例
AWS Management Console での実行
- Comprehend Medical コンソール
テキスト入力エリアに医療テキストをペースト 例: "患者は 2型糖尿病で、メトホルミン 500mg を 1 日 2 回処方中。 初診日は 2023-05-15。" → 「Analyze」クリック → エンティティ・ICD-10-CM・RxNorm 自動表示
CLI 操作
DetectEntitiesV2
aws comprehendmedical detect-entities-v2 \
--text "患者は 2型糖尿病と診断された。メトホルミン 1000mg を 1 日 2 回処方。" \
--region us-east-1
InferICD10CM
aws comprehendmedical infer-icd10cm \
--text "患者は 2型糖尿病、高血圧症、神経障害を持つ。" \
--region us-east-1
InferRxNorm
aws comprehendmedical infer-rx-norm \
--text "メトホルミン 500mg を 1 日 2 回、アスピリン 100mg を毎日処方。" \
--region us-east-1
DetectPHI
aws comprehendmedical detect-phi \
--text "患者名: 田中太郎、生年月日: 1980-05-15、住所: 東京都渋谷区" \
--region us-east-1
SDK 実装例
Python (Boto3)
import boto3
import json
client = boto3.client('comprehendmedical', region_name='us-east-1')
# 医療エンティティ検出
def detect_medical_entities(text):
response = client.detect_entities_v2(Text=text)
print("医療エンティティ:")
for entity in response['Entities']:
print(f" {entity['Text']} ({entity['Category']}/{entity['Type']}) - Score: {entity['Score']:.2f}")
return response
# ICD-10-CM 推定
def infer_icd10cm(text):
response = client.infer_icd10cm(Text=text)
print("\nICD-10-CM コード:")
for entity in response['Entities']:
if 'ICD10CMConcepts' in entity:
for concept in entity['ICD10CMConcepts']:
print(f" {entity['Text']} → {concept['Code']}: {concept['Description']}")
return response
# RxNorm 推定
def infer_rx_norm(text):
response = client.infer_rx_norm(Text=text)
print("\nRxNorm コード:")
for entity in response['Entities']:
if 'RxNormConcepts' in entity:
for concept in entity['RxNormConcepts']:
print(f" {entity['Text']} → {concept['Code']}: {concept['Description']}")
return response
# PHI 検出
def detect_phi(text):
response = client.detect_phi(Text=text)
print("\n検出された PHI:")
for entity in response['Entities']:
print(f" {entity['Text']} ({entity['Type']}) - Score: {entity['Score']:.2f}")
return response
# 匿名化
def anonymize_text(text, phi_response):
entities = sorted(phi_response['Entities'], key=lambda x: x['BeginOffset'], reverse=True)
for entity in entities:
start = entity['BeginOffset']
end = entity['EndOffset']
entity_type = entity['Type']
replacement = f"[{entity_type}]"
text = text[:start] + replacement + text[end:]
return text
# 使用例
if __name__ == '__main__':
sample_text = """
患者 山田太郎(生年月日 1980-05-15)は 2型糖尿病の診断を受けた。
メトホルミン 1000mg を 1 日 2 回処方、アスピリン 100mg を毎日処方。
初診日: 2023-05-15。
"""
detect_medical_entities(sample_text)
infer_icd10cm(sample_text)
infer_rx_norm(sample_text)
phi_response = detect_phi(sample_text)
anonymized = anonymize_text(sample_text, phi_response)
print(f"\n匿名化テキスト:\n{anonymized}")
Java
import software.amazon.awssdk.services.comprehendmedical.ComprehendMedicalClient;
import software.amazon.awssdk.services.comprehendmedical.model.*;
public class ComprehendMedicalExample {
public static void main(String[] args) {
ComprehendMedicalClient client = ComprehendMedicalClient.builder().build();
String text = "患者は 2型糖尿病と診断。メトホルミン 500mg 1 日 2 回処方。";
// DetectEntitiesV2
DetectEntitiesV2Request request = DetectEntitiesV2Request.builder()
.text(text)
.build();
DetectEntitiesV2Response response = client.detectEntitiesV2(request);
System.out.println("医療エンティティ:");
response.entities().forEach(entity ->
System.out.println(" " + entity.text() + " (" + entity.category() + ") - Score: " + entity.score())
);
// InferICD10CM
InferICD10CMRequest icdRequest = InferICD10CMRequest.builder()
.text(text)
.build();
InferICD10CMResponse icdResponse = client.inferICD10CM(icdRequest);
System.out.println("\nICD-10-CM:");
icdResponse.entities().forEach(entity -> {
if (entity.icd10CMConcepts() != null) {
entity.icd10CMConcepts().forEach(concept ->
System.out.println(" " + concept.code() + ": " + concept.description())
);
}
});
client.close();
}
}
IaC (CloudFormation/Terraform)
CloudFormation
AWSTemplateFormatVersion: '2010-09-09'
Description: 'Comprehend Medical Setup'
Resources:
ComprehendMedicalRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service: comprehendmedical.amazonaws.com
Action: sts:AssumeRole
ManagedPolicyArns:
- arn:aws:iam::aws:policy/ComprehendMedicalFullAccess
MedicalDataBucket:
Type: AWS::S3::Bucket
Properties:
BucketName: medical-text-bucket
VersioningConfiguration:
Status: Enabled
MedicalAnalysisLambda:
Type: AWS::Lambda::Function
Properties:
FunctionName: MedicalTextAnalysis
Runtime: python3.11
Role: !GetAtt LambdaRole.Arn
Handler: index.lambda_handler
Code:
ZipFile: |
import boto3
import json
comprehend_medical = boto3.client('comprehendmedical')
def lambda_handler(event, context):
text = event.get('text', '')
response = comprehend_medical.detect_entities_v2(Text=text)
return {
'statusCode': 200,
'body': json.dumps(response, default=str)
}
Terraform
resource "aws_iam_role" "comprehend_medical_role" {
name = "comprehend-medical-role"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Action = "sts:AssumeRole"
Effect = "Allow"
Principal = {
Service = "comprehendmedical.amazonaws.com"
}
}]
})
}
resource "aws_iam_role_policy_attachment" "comprehend_policy" {
role = aws_iam_role.comprehend_medical_role.name
policy_arn = "arn:aws:iam::aws:policy/ComprehendMedicalFullAccess"
}
resource "aws_s3_bucket" "medical_text" {
bucket = "medical-text-analysis-bucket"
versioning {
enabled = true
}
}
resource "aws_lambda_function" "medical_analysis" {
filename = "medical_analysis.zip"
function_name = "MedicalTextAnalysis"
role = aws_iam_role.lambda_role.arn
handler = "index.lambda_handler"
runtime = "python3.11"
}
類似サービス比較表
| 比較軸 | Comprehend Medical | Google Cloud Healthcare API | Azure Health Bot | John Snow Labs |
|---|---|---|---|---|
| クラウド | AWS | GCP | Azure | OSS / クラウド |
| 医療 NLP | ✅ 高精度 | ✅ 高精度 | ✅ 限定的 | ✅ 非常に高精度 |
| ICD-10-CM | ✅ | ✅ | ⚠️ | ✅ |
| RxNorm | ✅ | ✅ | ⚠️ | ✅ |
| SNOMED CT | ✅ | ✅ | ⚠️ | ✅ |
| PHI 検出 | ✅ | ✅ | ❌ | ✅ |
| HIPAA | ✅ | ✅ | ✅ | オプション |
| HealthLake 統合 | ✅ | ❌ | ❌ | ❌ |
| 推奨用途 | AWS ヘルスケア | Google Cloud 環境 | Microsoft エコ | 高精度・研究 |
ベストプラクティス
✅ 推奨パターン
-
テキスト前処理
- テキストをクリーニング(特殊文字除去)
- 信頼スコア閾値を 0.7 以上に設定
-
複数 API の組み合わせ
DetectEntities → ICD-10-CM / RxNorm マッピング 並列実行で効率化 -
PHI 検出・匿名化
- すべての医療データに DetectPHI を適用
- 人間による最終確認
-
HIPAA コンプライアンス
- Business Associate Agreement(BAA)署名
- 監査ログ有効化
トラブルシューティング
| 症状 | 原因 | 対策 |
|---|---|---|
| 信頼スコアが低い | テキスト品質・医療用語外 | テキスト前処理・サンプル確認 |
| ICD-10-CM マッピング失敗 | 医療条件でない / 曖昧 | テキスト明確化・複数条件試行 |
| PHI 検出漏れ | テキスト形式の多様性 | サンプル追加・人間による確認 |
| API レート制限 | リクエスト多すぎ | バッチ処理・バックオフ実装 |
セキュリティ・コンプライアンス
| 項目 | 実装 |
|---|---|
| HIPAA | BAA 署名で PHI 処理対応 |
| IAM | API 操作の最小権限 |
| KMS | 保存時暗号化 |
| TLS | 転送中の暗号化 |
| 監査ログ | CloudTrail で API 操作記録 |
| データ保持 | 顧客コンテンツ永続保存なし |
パフォーマンスチューニング
- バッチ処理 - 複数ドキュメント同時処理
- 非同期実行 - Lambda で SQS キュー処理
- キャッシング - 同一テキストの結果キャッシュ
コスト最適化
DetectEntities / ICD-10-CM / RxNorm / SNOMED CT / DetectPHI:
$0.01 ユニット(100 文字 = 1 ユニット)
例: 10,000 ドキュメント × 平均 500 文字
= 50,000 ユニット × $0.01 = $500
2025-2026 最新動向
- Custom Entity Recognition Medical - カスタム医療エンティティ学習
- Bedrock 統合 - 医療テキストのサマリー化
- 多言語対応拡大 - 日本語・中国語への対応
- HealthLake 連携強化 - EMR データ一括処理
学習リソース・参考文献
公式リソース
実装例・チェックリスト
チェックリスト
- [ ] Comprehend Medical API アクセス権限確認
- [ ] テキスト前処理パイプライン設計
- [ ] 信頼スコア閾値設定
- [ ] ICD-10-CM / RxNorm マッピング検証
- [ ] PHI 検出・匿名化実装
- [ ] HIPAA BAA 署名
- [ ] CloudTrail 監査ログ有効化
- [ ] バッチ処理・非同期実行設計
- [ ] エラーハンドリング・再試行ロジック
- [ ] コスト見積もり・予算アラート設定
まとめ
Amazon Comprehend Medical は 「医療・臨床テキストに特化した NLP サービス」 です。診断名・症状・薬剤などの医療エンティティを自動抽出し、ICD-10-CM・RxNorm・SNOMED CT コードにマッピングします。HIPAA 準拠の PHI 検出・匿名化で医療データのコンプライアンス処理を自動化し、EMR 構造化・コホート選定・臨床研究のデータ前処理を効率化します。
最終更新:2026-04-26 バージョン:v2.0