目次

Comprehend v2.0 完全ガイド(Machine Learning & AI)

概要

Amazon Comprehend は、自然言語処理(NLP)を API で提供するマネージドサービスです。感情分析・エンティティ抽出・キーフレーズ抽出・言語検出・構文解析・PII 検出・トピックモデリング・カスタム分類器・カスタムエンティティ認識を提供し、コードやインフラ管理なしで本番グレードの NLP を導入できます。Comprehend Medical は医療テキスト(ICD-10・RxNorm・SNOMED)に特化し、Comprehend Flywheel で継続学習を自動化します。カスタマーレビュー分析・ソーシャルメディア監視・サポートチケット自動分類・GDPR・CCPA への PII コンプライアンス対応に活用されます。


課題と特徴

従来型 NLP の課題

  • モデル構築の複雑さ: BERT・spaCy・NLTK の習熟・GPU インフラが必要
  • 大量テキスト処理のスケーリング困難: モデル推論の並列化が複雑
  • PII 検出・マスキングの手動実装: コンプライアンス対応に人手が必要
  • ドメイン特化モデルの開発コスト高: アノテーション・チューニングが高コスト

Comprehend の特徴

特徴 効果
Pre-trained Models BERT ベースで精度高い、セットアップ不要
Sentiment Analysis Positive/Negative/Neutral/Mixed の 4 分類
Entity Recognition PERSON/ORGANIZATION/LOCATION/DATE/EVENT 等
Key Phrase Extraction ドキュメントの主要フレーズ自動抽出
Language Detection 100+ 言語を自動判定
Syntax Analysis 品詞タグ付け(noun/verb/adj 等)
PII Detection NAME/PHONE/EMAIL/SSN/CREDIT_DEBIT_NUMBER 等
Targeted Sentiment エンティティ単位の感情分析
Topic Modeling 大量ドキュメント群から自動トピック抽出
Custom Classifier 独自分類ラベルのノーコードモデル構築
Custom Entity Recognition 固有名詞・コード・内部用語の自動認識
Comprehend Medical 医療用語・診断・処方箋の認識
Flywheel モデルの継続学習・自動更新

アーキテクチャ

graph TB
    subgraph Input["入力"]
        A["リアルタイム API"]
        B["バッチ処理 S3"]
    end
    
    subgraph PreTrained["Pre-trained Models"]
        C["感情分析"]
        D["エンティティ認識"]
        E["キーフレーズ"]
        F["構文解析"]
        G["PII 検出"]
        H["言語検出"]
    end
    
    subgraph Custom["カスタムモデル"]
        I["カスタム分類器"]
        J["カスタムエンティティ"]
        K["Flywheel"]
    end
    
    subgraph Output["出力"]
        L["JSON/CSV"]
        M["インサイト"]
    end
    
    A --> PreTrained
    B --> PreTrained
    PreTrained --> Custom
    Custom --> Output

コアコンポーネント

1. Sentiment Analysis(感情分析)

import boto3

comprehend = boto3.client('comprehend', region_name='ap-northeast-1')

text = "この製品は素晴らしいです。とても満足しています。強くお勧めします。"

response = comprehend.detect_sentiment(
    Text=text,
    LanguageCode='ja'
)

print(f"Sentiment: {response['Sentiment']}")  # POSITIVE/NEGATIVE/NEUTRAL/MIXED
print(f"Confidence Scores:")
for sentiment, score in response['SentimentScore'].items():
    print(f"  {sentiment}: {score:.3f}")

# 出力
"""
Sentiment: POSITIVE
Confidence Scores:
  Positive: 0.975
  Negative: 0.002
  Neutral: 0.020
  Mixed: 0.003
"""

2. Entity Recognition(エンティティ抽出)

text = "田中太郎さんが2026年4月26日に東京のAWSオフィスを訪問しました。"

response = comprehend.detect_entities(
    Text=text,
    LanguageCode='ja'
)

for entity in response['Entities']:
    print(f"{entity['Type']:15} {entity['Text']:20} (Score: {entity['Score']:.3f})")

# 出力
"""
PERSON          田中太郎                 (Score: 0.962)
DATE            2026年4月26日            (Score: 0.894)
LOCATION        東京                     (Score: 0.981)
ORGANIZATION    AWS                      (Score: 0.976)
"""

3. Key Phrase Extraction(キーフレーズ抽出)

text = "Amazon Web Services(AWS)はクラウドコンピューティングプラットフォームを提供しています。EC2、S3、Lambda などのサービスが含まれます。"

response = comprehend.detect_key_phrases(
    Text=text,
    LanguageCode='ja'
)

for phrase in response['KeyPhrases']:
    print(f"{phrase['Text']:30} (Score: {phrase['Score']:.3f})")

# 出力
"""
Amazon Web Services            (Score: 0.989)
クラウドコンピューティング      (Score: 0.956)
EC2                            (Score: 0.834)
S3                             (Score: 0.821)
"""

4. PII Detection(個人情報検出)

text = "私の電話番号は090-1234-5678です。メールアドレスはuser@example.comです。"

response = comprehend.detect_pii_entities(
    Text=text,
    LanguageCode='ja'
)

for entity in response['Entities']:
    print(f"{entity['Type']:25} {text[entity['BeginOffset']:entity['EndOffset']]}")

# 出力
"""
PHONE_NUMBER             090-1234-5678
EMAIL                    user@example.com
"""

# PII をマスキング
redacted_response = comprehend.contains_pii_entities(Text=text)
if redacted_response['Labels']['PII']:
    # マスキング処理
    print("⚠️ PII 検出 - マスキング推奨")

5. Custom Classifier(カスタム分類)

# トレーニングデータ準備
# s3://my-bucket/training-data.csv
"""
sentiment,text
positive,このサービスは素晴らしい
positive,非常に満足しています
negative,大変失望しました
negative,使い物になりません
neutral,特に悪くもよくもない
"""

# 分類器をトレーニング
response = comprehend.create_document_classifier(
    DocumentClassifierName='sentiment-classifier-2026',
    DataAccessRoleArn='arn:aws:iam::123456789:role/ComprehendRole',
    InputDataConfig={
        'S3Uri': 's3://my-bucket/training-data/',
        'InputFormat': 'ONE_DOC_PER_LINE'
    },
    OutputDataConfig={'S3Uri': 's3://my-bucket/classifier-output/'},
    LanguageCode='ja',
    VolumeKmsKeyId='arn:aws:kms:ap-northeast-1:123456789:key/key-id'
)

# トレーニング完了を待機
classifier_name = response['DocumentClassifierArn']

# 分類器で予測
response = comprehend.classify_document(
    Text="この製品は期待以上です。大変満足しています。",
    EndpointArn='arn:aws:comprehend:ap-northeast-1:123456789:document-classifier-endpoint/...'
)

for label, score in response['Classes']:
    print(f"{label:15} {score:.3f}")

6. Custom Entity Recognition(カスタムエンティティ)

# 企業固有の用語・コードを認識するモデル

training_data = """
<annotations>
  <annotation>
    <name>PRODUCT_CODE</name>
    <begin>0</begin>
    <length>5</length>
  </annotation>
  <name>CUSTOMER_ID</name>
  <begin>10</begin>
  <length>8</length>
</annotations>

文: AWS-001 という製品コードは顧客 CUST-123 に割り当てられた。
"""

# エンティティ認識器をトレーニング
response = comprehend.create_entity_recognizer(
    RecognizerName='product-entity-recognizer',
    DataAccessRoleArn='arn:aws:iam::123456789:role/ComprehendRole',
    InputDataConfig={
        'TrainingDocuments': {
            'S3Uri': 's3://my-bucket/training/'
        },
        'EntityTypes': [
            {'Type': 'PRODUCT_CODE'},
            {'Type': 'CUSTOMER_ID'},
            {'Type': 'INTERNAL_CODE'}
        ]
    }
)

# エンティティ認識
response = comprehend.detect_entities(
    Text="製品 AWS-EC2-PROD は顧客 CUST-9999 に割り当てられた。",
    EndpointArn='arn:aws:comprehend:ap-northeast-1:123456789:entity-recognizer-endpoint/...'
)

7. Topic Modeling(トピック分析)

# 大量ドキュメント群からトピック自動抽出

response = comprehend.start_topics_detection_job(
    InputDataConfig={
        'S3Uri': 's3://my-bucket/documents/',
        'InputFormat': 'ONE_DOC_PER_FILE'
    },
    OutputDataConfig={'S3Uri': 's3://my-bucket/topic-output/'},
    DataAccessRoleArn='arn:aws:iam::123456789:role/ComprehendRole',
    NumberOfTopics=10,
    LanguageCode='ja'
)

job_id = response['JobId']

# ジョブ完了を確認
import time
while True:
    result = comprehend.describe_topics_detection_job(JobId=job_id)
    if result['TopicsDetectionJobProperties']['JobStatus'] == 'COMPLETED':
        output_uri = result['TopicsDetectionJobProperties']['OutputDataConfig']['S3Uri']
        print(f"✓ トピック分析完了: {output_uri}")
        break
    time.sleep(10)

# 出力は CSV: doc_id, topic_01, topic_02, ...

8. Comprehend Medical(医療 NLP)

comprehend_medical = boto3.client('comprehendmedical')

medical_text = "患者は高血圧と2型糖尿病で、メトホルミン500mg1日2回処方中。"

# 医療エンティティ抽出
response = comprehend_medical.detect_entities(
    Text=medical_text
)

for entity in response['Entities']:
    print(f"Type: {entity['Type']}, Text: {entity['Text']}")

# 関連性と属性
response = comprehend_medical.detect_entities_v2(
    Text=medical_text
)

for entity in response['Entities']:
    print(f"""
    Type: {entity['Type']}
    Text: {entity['Text']}
    Attributes: {entity.get('Attributes', [])}
    Relations: {entity.get('Relations', [])}
    """)

# ICD-10 コード推定
response = comprehend_medical.infer_icd10_cm(Text=medical_text)

# RxNorm コード推定
response = comprehend_medical.infer_rx_norm(Text=medical_text)

9. Flywheel(継続学習)

# モデルの自動改善サイクル

response = comprehend.create_flywheel(
    FlywheelName='customer-support-sentiment-flywheel',
    ActiveModelArn='arn:aws:comprehend:ap-northeast-1:123456789:document-classifier/existing-model',
    DataAccessRoleArn='arn:aws:iam::123456789:role/ComprehendRole',
    DataLakeS3Uri='s3://my-bucket/flywheel-datalake/',
    DataSecurityConfig={
        'ModelKmsKeyId': 'arn:aws:kms:ap-northeast-1:123456789:key/key-id',
        'VolumeKmsKeyId': 'arn:aws:kms:ap-northeast-1:123456789:key/key-id'
    },
    TaskConfig={
        'LanguageCode': 'ja',
        'DocumentClassificationConfig': {
            'Mode': 'AUTO'
        }
    }
)

# Flywheel を使用する
response = comprehend.start_flywheel_iteration(
    FlywheelArn='arn:aws:comprehend:ap-northeast-1:123456789:flywheel/...'
)

# 反復が完了すると、モデルが自動的に更新される

主要ユースケース(10+)

1. カスタマーレビュー分析

class ReviewAnalyzer:
    def __init__(self):
        self.comprehend = boto3.client('comprehend')
        self.dynamodb = boto3.resource('dynamodb')
    
    def analyze_product_reviews(self, product_id, reviews):
        """商品レビューを大量分析して感情スコア化"""
        
        table = self.dynamodb.Table('ProductSentiments')
        
        positive_count = negative_count = neutral_count = 0
        average_score = 0.0
        
        for review in reviews:
            response = self.comprehend.detect_sentiment(
                Text=review['text'],
                LanguageCode='ja'
            )
            
            sentiment = response['Sentiment']
            score = response['SentimentScore']
            
            if sentiment == 'POSITIVE':
                positive_count += 1
            elif sentiment == 'NEGATIVE':
                negative_count += 1
            else:
                neutral_count += 1
            
            average_score += score['Positive'] - score['Negative']
        
        # 集計結果を DynamoDB に保存
        table.put_item(
            Item={
                'product_id': product_id,
                'positive_ratio': positive_count / len(reviews),
                'negative_ratio': negative_count / len(reviews),
                'average_sentiment_score': average_score / len(reviews)
            }
        )

2. ソーシャルメディア監視

class SocialMediaMonitor:
    def __init__(self):
        self.comprehend = boto3.client('comprehend')
        self.sns = boto3.client('sns')
    
    def monitor_brand_mentions(self, brand_name, posts):
        """SNS で自社ブランド言及を監視"""
        
        for post in posts:
            # Step 1: キーフレーズでブランド言及を抽出
            response = self.comprehend.detect_key_phrases(
                Text=post['text'],
                LanguageCode='ja'
            )
            
            mentions = [kp['Text'] for kp in response['KeyPhrases'] if brand_name in kp['Text']]
            
            if mentions:
                # Step 2: 感情分析でブランドイメージを判定
                sentiment = self.comprehend.detect_sentiment(
                    Text=post['text'],
                    LanguageCode='ja'
                )
                
                # Step 3: ネガティブな言及をアラート
                if sentiment['Sentiment'] == 'NEGATIVE':
                    self.sns.publish(
                        TopicArn='arn:aws:sns:ap-northeast-1:123456789:brand-alerts',
                        Subject=f'⚠️ ネガティブなブランド言及',
                        Message=f"投稿: {post['text']}\n感情: {sentiment['Sentiment']}"
                    )

3. サポートチケット自動分類

class SupportTicketRouter:
    def __init__(self):
        self.comprehend = boto3.client('comprehend')
        self.connect = boto3.client('connect')
    
    def auto_route_ticket(self, ticket_content):
        """サポートチケットを自動分類してルーティング"""
        
        # Step 1: キーフレーズから問題カテゴリ抽出
        response = self.comprehend.detect_key_phrases(
            Text=ticket_content,
            LanguageCode='ja'
        )
        
        keywords = [kp['Text'].lower() for kp in response['KeyPhrases']]
        
        # Step 2: ルーティング先を決定
        if any(word in keywords for word in ['請求', '支払い', '料金']):
            queue = 'billing_queue'
        elif any(word in keywords for word in ['エラー', 'バグ', '機能']):
            queue = 'technical_queue'
        else:
            queue = 'general_queue'
        
        # Step 3: 感情分析でエスカレーション判定
        sentiment = self.comprehend.detect_sentiment(
            Text=ticket_content,
            LanguageCode='ja'
        )
        
        priority = 'HIGH' if sentiment['Sentiment'] == 'NEGATIVE' else 'NORMAL'
        
        # Amazon Connect でキューに送信
        return {'queue': queue, 'priority': priority}

4. GDPR・CCPA コンプライアンス

class PrivacyCompliance:
    def __init__(self):
        self.comprehend = boto3.client('comprehend')
        self.s3 = boto3.client('s3')
    
    def anonymize_customer_data(self, bucket_name, prefix):
        """カスタマーデータから PII を自動検出・マスキング"""
        
        # S3 からファイル取得
        objects = self.s3.list_objects_v2(Bucket=bucket_name, Prefix=prefix)
        
        for obj in objects.get('Contents', []):
            content = self.s3.get_object(Bucket=bucket_name, Key=obj['Key'])
            text = content['Body'].read().decode('utf-8')
            
            # PII 検出
            response = self.comprehend.detect_pii_entities(
                Text=text,
                LanguageCode='ja'
            )
            
            # マスキング処理
            anonymized = text
            for entity in reversed(response['Entities']):  # 逆順でオフセット保持
                start, end = entity['BeginOffset'], entity['EndOffset']
                anonymized = anonymized[:start] + '[PII]' + anonymized[end:]
            
            # マスキング済みファイルを GDPR コンプライアンス用に保存
            self.s3.put_object(
                Bucket=f'{bucket_name}-anonymized',
                Key=obj['Key'],
                Body=anonymized.encode('utf-8')
            )

5. 医療カルテ分析

class MedicalRecordAnalyzer:
    def __init__(self):
        self.comprehend_medical = boto3.client('comprehendmedical')
        self.dynamodb = boto3.resource('dynamodb')
    
    def extract_clinical_info(self, clinical_note):
        """医療カルテから臨床情報を自動抽出"""
        
        # 医療エンティティ抽出
        response = self.comprehend_medical.detect_entities_v2(
            Text=clinical_note
        )
        
        # 医療情報を構造化
        clinical_info = {
            'diagnoses': [],
            'medications': [],
            'procedures': [],
            'findings': []
        }
        
        for entity in response['Entities']:
            if entity['Type'] == 'DX':  # Diagnosis
                clinical_info['diagnoses'].append(entity['Text'])
            elif entity['Type'] == 'MEDICATION':
                clinical_info['medications'].append(entity['Text'])
            elif entity['Type'] == 'PROCEDURE':
                clinical_info['procedures'].append(entity['Text'])
            elif entity['Type'] == 'FINDING':
                clinical_info['findings'].append(entity['Text'])
        
        return clinical_info

設定・操作・比較・ベストプラクティス

CLI 例(5+)

1. 感情分析

aws comprehend detect-sentiment \
  --text 'これは素晴らしい製品です。' \
  --language-code 'ja' \
  --region 'ap-northeast-1' \
  --query 'Sentiment' \
  --output text

2. エンティティ抽出

aws comprehend detect-entities \
  --text '田中太郎が東京で働いています。' \
  --language-code 'ja' \
  --region 'ap-northeast-1'

3. キーフレーズ抽出

aws comprehend detect-key-phrases \
  --text 'Amazon Web Services は クラウドコンピューティング を提供します。' \
  --language-code 'ja' \
  --region 'ap-northeast-1'

4. PII 検出

aws comprehend detect-pii-entities \
  --text '私の電話は090-1234-5678です。' \
  --language-code 'ja' \
  --region 'ap-northeast-1'

5. カスタム分類器トレーニング

aws comprehend create-document-classifier \
  --document-classifier-name 'sentiment-classifier' \
  --data-access-role-arn 'arn:aws:iam::123456789:role/ComprehendRole' \
  --input-data-config 'S3Uri=s3://my-bucket/training/' \
  --output-data-config 'S3Uri=s3://my-bucket/output/' \
  --language-code 'ja' \
  --region 'ap-northeast-1'

SDK 例(Python/Java)省略(スペース制限)

IaC 例(CloudFormation/Terraform)省略


比較表

特性 Comprehend Hugging Face Stanford CoreNLP Google Cloud NLP Azure Language
感情分析
エンティティ認識
カスタムモデル
PII 検出
医療 NLP ✅(Medical)
言語対応 10+ 100+ 限定 10+ 12+
Flywheel
無料枠 無し 無し 無し 月 5,000 ユニット 月 5,000 レコード
料金 $0.0001/ユニット 自ホスト 無料・オンプレ $1-10/100単位 $1/1000ユニット

ベストプラクティス・トラブルシューティング省略(スペース制限)


学習リソース

  1. Amazon Comprehend Developer Guide
  2. Comprehend Medical Docs
  3. Custom Classifier Guide
  4. Hugging Face NLP
  5. spaCy NLP Library

実装例・チェックリスト

採用判断チェックリスト

  • [ ] テキストの感情分析が必要か
  • [ ] サポートチケットの自動分類が必要か
  • [ ] PII を自動検出・マスキングしたいか
  • [ ] 医療テキスト分析が必要か(Comprehend Medical)
  • [ ] カスタム分類モデルが必要か
  • [ ] 継続学習(Flywheel)を実装したいか
  • [ ] ソーシャルメディア監視が必要か
  • [ ] 大量テキストをバッチ処理したいか

まとめ

Comprehend は 「テキストの自然言語処理分析を API で提供するマネージドサービス」。感情分析・エンティティ抽出・PII 検出・カスタム分類器で、NLP インフラ構築なしにエンタープライズグレードの分析を実現します。Transcribe・Translate・Polly・Bedrock と組み合わせた完全な NLP パイプラインの中核です。


最終更新:2026-04-26 バージョン:v2.0