目次

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
  • 信頼スコア: 検出精度の定量化

目次

  1. 概要
  2. Comprehend Medical が解決する課題
  3. 主な特徴
  4. 医療エンティティ検出
  5. ICD-10-CM / RxNorm / SNOMED CT マッピング
  6. PHI 検出・匿名化
  7. アーキテクチャ
  8. 主要ユースケース
  9. 設定・操作の具体例
  10. CLI 操作
  11. SDK 実装例
  12. IaC (CloudFormation/Terraform)
  13. 類似サービス比較表
  14. ベストプラクティス
  15. トラブルシューティング
  16. セキュリティ・コンプライアンス
  17. パフォーマンスチューニング
  18. コスト最適化
  19. 2025-2026 最新動向
  20. 学習リソース・参考文献
  21. 実装例・チェックリスト
  22. まとめ

概要

初心者向けメモ: 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/>(研究・共有)"]

主要ユースケース

  1. 電子カルテ(EMR)の構造化

    • 自由記述テキストを ICD-10-CM・RxNorm で構造化
    • コーディング工数 50-70% 削減
  2. 医療請求自動化

    • 医師記録から診断コードを自動抽出
    • 請求コード精度向上・収益サイクル高速化
  3. 臨床研究コホート選定

    • 特定の疾患・投薬履歴の患者を自動抽出
    • 大量医療記録から研究対象者を効率的に特定
  4. データ匿名化(HIPAA 準拠)

    • カルテから PII を自動検出・マスキング
    • 研究用データセットの安全な作成
  5. 薬剤相互作用分析

    • 投薬記録から薬剤を自動抽出
    • RxNorm で標準化後、相互作用 DB と照合
  6. ファーマコビジランス

    • 有害事象報告書から症状・薬剤を抽出
    • 医薬品の安全性監視を効率化
  7. AI 医療分析

    • Bedrock と組み合わせて医療テキストのサマリー化
    • 医師の意思決定サポート
  8. 医療データの BI / 分析

    • 構造化データで BI ダッシュボード構築
    • 患者集団の疾患・投薬パターン分析
  9. 医療データレイク構築

    • 複数病院のカルテを統一フォーマットで統合
    • HealthLake との連携
  10. 多言語医療情報処理

    • 複数言語のカルテを統一スキーマで処理
    • グローバル臨床試験の患者データ整理

設定・操作の具体例

AWS Management Console での実行

  1. 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 エコ 高精度・研究

ベストプラクティス

✅ 推奨パターン

  1. テキスト前処理

    • テキストをクリーニング(特殊文字除去)
    • 信頼スコア閾値を 0.7 以上に設定
  2. 複数 API の組み合わせ

    DetectEntities → ICD-10-CM / RxNorm マッピング
    並列実行で効率化
    
  3. PHI 検出・匿名化

    • すべての医療データに DetectPHI を適用
    • 人間による最終確認
  4. 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