目次
Textract v2.0 完全ガイド(Machine Learning & AI)
概要
Amazon Textract は、PDF・画像からテキスト・フォーム・テーブルを自動抽出するドキュメント処理 AI サービスです。単純な OCR を超えて、フォームのキー・値のペア(Key-Value)、テーブルの行列構造、署名検出、バーコード認識、自然言語クエリ(Textract Queries)による目的特化抽出を提供します。AnalyzeDocument(フォーム・テーブル)・AnalyzeID(身分証明書)・AnalyzeExpense(請求書)・AnalyzeLending(ローン書類)・Queries(目的特化抽出)の 5 つの API で、銀行融資申請・保険請求・医療問診票・物流書類・税務書類の自動処理を実現します。A2I(人間確認)との組み合わせで高精度パイプラインを構築できます。
課題と特徴
従来型 OCR の課題
- テキストのみ抽出: フォームの構造(キー・値の関連性)を認識できない
- テーブル解析が困難: セル境界・行列の理解が手作業
- スキャン品質低下への弱さ: 手書き・折れ曲がり・汚れに対応困難
- 大量書類処理の人手コスト: スキャン後の手作業入力が膨大
Textract の特徴
| 特徴 | 効果 |
|---|---|
| Structured Data Extraction | フォームのキー・値、テーブルセルを JSON で抽出 |
| Form Recognition | 「氏名:」「住所:」のようなキー・値ペアを自動認識 |
| Table Analysis | テーブルの行・列・セルを構造的に理解 |
| Signature Detection | 署名の有無を自動検出 |
| ID Document Analysis | 運転免許証・パスポートから特定フィールドを抽出 |
| Expense Analysis | 請求書・レシートから金額・税額・ベンダーを抽出 |
| Lending Document Analysis | ローン書類を自動分類・処理 |
| Handwriting Support | 手書きテキストも認識可能 |
| Textract Queries | 「この書類の合計金額は?」のような自然言語クエリで抽出 |
| Async + SNS Integration | 大量ドキュメントは非同期・SNS 通知 |
| Confidence Scores | 抽出の信頼度スコアで品質判定 |
| Bedrock Integration | 抽出後の テキスト理解を Bedrock で強化可能 |
アーキテクチャ
graph TB
subgraph Input["入力"]
A["単一ページ画像"]
B["マルチページ PDF"]
end
subgraph APIs["Textract API"]
C["DetectDocumentText"]
D["AnalyzeDocument"]
E["AnalyzeID"]
F["AnalyzeExpense"]
G["AnalyzeLending"]
H["Queries"]
end
subgraph Processing["処理エンジン"]
I["テキスト抽出"]
J["フォーム解析"]
K["テーブル認識"]
L["署名検出"]
M["クエリ処理"]
end
subgraph Output["出力"]
N["JSON<br/>テキスト・位置情報"]
O["Key-Value<br/>ペア"]
P["Table<br/>行列構造"]
end
A --> C
B --> D
C --> I
D --> J
D --> K
E --> L
H --> M
I --> N
J --> O
K --> P
コアコンポーネント
1. DetectDocumentText(シンプルな OCR)
import boto3
textract = boto3.client('textract', region_name='ap-northeast-1')
# S3 の画像から OCR
response = textract.detect_document_text(
Document={
'S3Object': {
'Bucket': 'my-bucket',
'Name': 'document.png'
}
}
)
# テキストを抽出
for block in response['Blocks']:
if block['BlockType'] == 'LINE':
print(block['Text'])
2. AnalyzeDocument - Forms(フォーム抽出)
# 応募書類・申請書からキー・値を抽出
response = textract.analyze_document(
Document={'S3Object': {'Bucket': 'my-bucket', 'Name': 'application-form.pdf'}},
FeatureTypes=['FORMS', 'TABLES']
)
# キー・値のペアを抽出
key_map = {}
value_map = {}
for block in response['Blocks']:
if block['BlockType'] == 'KEY_VALUE_SET':
if 'KEY' in block.get('EntityTypes', []):
key_map[block['Id']] = block
elif 'VALUE' in block.get('EntityTypes', []):
value_map[block['Id']] = block
# キー・値を対応付け
for key_id, key_block in key_map.items():
values = key_block.get('Relationships', [])
for relationship in values:
if relationship['Type'] == 'VALUE':
for value_id in relationship['Ids']:
print(f"キー: {get_text(key_block, response['Blocks'])}")
print(f"値: {get_text(value_map[value_id], response['Blocks'])}")
def get_text(block, blocks):
text = ''
if 'Relationships' in block:
for relationship in block.get('Relationships', []):
if relationship['Type'] == 'CHILD':
for child_id in relationship['Ids']:
child = next((b for b in blocks if b['Id'] == child_id), None)
if child and child['BlockType'] == 'WORD':
text += child['Text'] + ' '
return text.strip()
3. AnalyzeDocument - Tables(テーブル抽出)
# テーブルを行・列単位で抽出
response = textract.analyze_document(
Document={'S3Object': {'Bucket': 'my-bucket', 'Name': 'invoice.pdf'}},
FeatureTypes=['TABLES']
)
# テーブルデータを pandas DataFrame に変換
import pandas as pd
tables = []
table_blocks = [b for b in response['Blocks'] if b['BlockType'] == 'TABLE']
for table in table_blocks:
rows = {}
for relationship in table.get('Relationships', []):
if relationship['Type'] == 'CHILD':
for cell_id in relationship['Ids']:
cell = next((b for b in response['Blocks'] if b['Id'] == cell_id), None)
if cell and cell['BlockType'] == 'CELL':
row_idx = cell['RowIndex']
col_idx = cell['ColumnIndex']
if row_idx not in rows:
rows[row_idx] = {}
# セル内のテキストを取得
cell_text = get_cell_text(cell, response['Blocks'])
rows[row_idx][col_idx] = cell_text
# DataFrame に変換
df = pd.DataFrame(rows).T
tables.append(df)
4. AnalyzeID(身分証明書抽出)
# 運転免許証・パスポートから情報抽出
response = textract.analyze_id(
DocumentPages=[{
'S3Object': {
'Bucket': 'my-bucket',
'Name': 'drivers-license.jpg'
}
}]
)
# 抽出されたフィールド
for document in response['DocumentMetadata']:
for page in document['Pages']:
for field in page['DocumentMetadataList']:
print(f"{field['MRZCode']}") # MRZ(機械可読ゾーン)
# 特定フィールドを抽出
identity_documents = response['IdentityDocuments']
for doc in identity_documents:
for field_name, field_value in doc['IdentityDocumentFields'].items():
print(f"{field_name}: {field_value['ValueDetection']['Text']}")
# 出力例: DOCUMENT_TYPE, FIRST_NAME, LAST_NAME, DATE_OF_BIRTH, EXPIRATION_DATE
5. AnalyzeExpense(請求書・レシート抽出)
# 請求書からビジネス情報を自動抽出
response = textract.analyze_expense(
Document={'S3Object': {'Bucket': 'my-bucket', 'Name': 'invoice.pdf'}}
)
# 請求書の構造化データを抽出
for expense_doc in response['ExpenseDocuments']:
summary_fields = expense_doc['SummaryFields']
line_items = expense_doc['LineItemGroups']
# サマリー: 請求日、合計額、ベンダー等
for field in summary_fields:
field_type = field['Type']['Text']
field_value = field['ValueDetection']['Text']
confidence = field['ValueDetection']['Confidence']
print(f"{field_type}: {field_value} ({confidence:.1%})")
# ラインアイテム: 各行の商品・金額
for line_item in line_items:
for item_field in line_item['LineItemExpenseFields']:
print(f" {item_field['Type']['Text']}: {item_field['ValueDetection']['Text']}")
# 出力例
"""
INVOICE_RECEIPT_ID: INV-2026-001 (98%)
INVOICE_RECEIPT_DATE: 2026-04-26 (99%)
TOTAL: $1,234.56 (99%)
VENDOR_NAME: Acme Corporation (95%)
Line items:
ITEM: Widget A (99%)
QUANTITY: 5 (98%)
UNIT_PRICE: $200.00 (97%)
AMOUNT: $1,000.00 (99%)
"""
6. AnalyzeLending(ローン書類分析)
# ローン申請書類を自動分類・処理
response = textract.analyze_lending(
DocumentPages=[{
'S3Object': {
'Bucket': 'my-bucket',
'Name': 'loan-package.pdf'
}
}]
)
# 自動分類された書類タイプ
for document in response['Results']:
document_type = document['DocumentType'] # e.g., W2, 1099, TAX_RETURN
print(f"書類タイプ: {document_type}")
# 構造化フィールド
extracted_fields = document['Extractions']
for field in extracted_fields:
field_label = field['Type']
field_value = field['ValueDetections'][0]['Text']
print(f" {field_label}: {field_value}")
7. Textract Queries(自然言語クエリ)
# 「このドキュメントの合計金額は?」のような自然言語クエリで抽出
response = textract.analyze_document(
Document={'S3Object': {'Bucket': 'my-bucket', 'Name': 'invoice.pdf'}},
FeatureTypes=['QUERIES', 'TABLES', 'FORMS'],
QueriesConfig={
'Queries': [
{'Text': 'この請求書の合計金額はいくらですか?'},
{'Text': '納品日はいつですか?'},
{'Text': 'どの商品が最も高い金額ですか?'}
]
}
)
# クエリの回答を取得
for query_result in response.get('QueryResponses', []):
query_text = query_result['Query']['Text']
answer = query_result.get('Answer', 'No answer found')
confidence = query_result.get('Confidence', 0)
print(f"Q: {query_text}")
print(f"A: {answer} ({confidence:.1%})")
8. 非同期バッチ処理
import time
# マルチページ PDF や大量ドキュメント用の非同期処理
response = textract.start_document_analysis(
DocumentLocation={
'S3Object': {
'Bucket': 'my-bucket',
'Name': 'large-form.pdf'
}
},
FeatureTypes=['FORMS', 'TABLES'],
ClientRequestToken='my-request-token-001',
NotificationChannel={
'SNSTopicArn': 'arn:aws:sns:ap-northeast-1:123456789:textract-complete',
'RoleArn': 'arn:aws:iam::123456789:role/TextractRole'
},
OutputConfig={
'S3Bucket': 'my-bucket',
'S3Prefix': 'textract-output/'
}
)
job_id = response['JobId']
# SNS 通知待機
# または手動でポーリング
while True:
result = textract.get_document_analysis(JobId=job_id)
if result['DocumentMetadata']['Pages'] > 0:
job_status = result['JobStatus']
if job_status == 'SUCCEEDED':
print("✓ 分析完了")
print(f"ページ数: {result['DocumentMetadata']['Pages']}")
break
elif job_status == 'FAILED':
print("✗ 分析失敗")
break
time.sleep(5)
主要ユースケース
1. 銀行融資申請の自動処理
class LoanApplicationProcessor:
def __init__(self):
self.textract = boto3.client('textract')
self.comprehend = boto3.client('comprehend')
def process_loan_application(self, application_pdf_uri):
"""融資申請書類を自動処理して審査スコア化"""
# Step 1: Textract でローン書類を分析
response = self.textract.analyze_lending(
DocumentPages=[{'S3Object': {'Bucket': bucket, 'Name': key}}]
)
# Step 2: 構造化データを抽出
applicant_info = {}
financial_info = {}
for doc in response['Results']:
for field in doc['Extractions']:
if 'NAME' in field['Type']:
applicant_info['name'] = field['ValueDetections'][0]['Text']
elif 'INCOME' in field['Type']:
financial_info['income'] = field['ValueDetections'][0]['Text']
elif 'DEBT' in field['Type']:
financial_info['debt'] = field['ValueDetections'][0]['Text']
# Step 3: Comprehend で追加の文書テキストを分析
# ローンスコア計算
loan_score = calculate_loan_score(applicant_info, financial_info)
return {
'applicant': applicant_info,
'financials': financial_info,
'loan_score': loan_score,
'recommendation': 'APPROVE' if loan_score > 700 else 'REVIEW'
}
2. 医療保険請求の自動化
class InsuranceClaimProcessor:
def __init__(self):
self.textract = boto3.client('textract')
self.dynamodb = boto3.resource('dynamodb')
def process_claim_form(self, claim_form_pdf):
"""医療保険請求書を自動処理"""
# Step 1: Textract でフォーム・テーブルを抽出
response = self.textract.analyze_document(
Document={'S3Object': claim_form_pdf},
FeatureTypes=['FORMS', 'TABLES']
)
# Step 2: キー・値を抽出
claim_data = {
'claimant_name': '',
'claim_date': '',
'service_date': '',
'provider_name': '',
'claim_amount': '',
'procedures': []
}
# フォーム処理
# テーブル処理(医療手続き明細)
# Step 3: DynamoDB に保存
table = self.dynamodb.Table('InsuranceClaims')
table.put_item(Item=claim_data)
3. 物流・請求書の自動処理
class LogisticsDocumentProcessor:
def __init__(self):
self.textract = boto3.client('textract')
self.s3 = boto3.client('s3')
def auto_process_invoice(self, invoice_s3_uri):
"""請求書を自動処理して ERP に送信"""
# Step 1: AnalyzeExpense で請求書分析
response = self.textract.analyze_expense(
Document={'S3Object': invoice_s3_uri}
)
# Step 2: 構造化データ抽出
invoice_summary = {}
for expense_doc in response['ExpenseDocuments']:
for field in expense_doc['SummaryFields']:
field_type = field['Type']['Text']
field_value = field['ValueDetection']['Text']
invoice_summary[field_type] = field_value
# Step 3: ERP API に送信
# Step 4: 支払予定日をスケジュール
4. A2I(人間確認)との組み合わせ
class HighPrecisionDocumentProcessing:
def __init__(self):
self.textract = boto3.client('textract')
self.a2i = boto3.client('sagemaker-a2i-runtime')
def extract_with_human_review(self, document_uri):
"""信頼度低いフィールドは人間レビュー"""
# Step 1: Textract で抽出
response = self.textract.analyze_document(
Document=document_uri,
FeatureTypes=['FORMS', 'TABLES']
)
# Step 2: 信頼度をチェック
low_confidence_fields = []
for block in response['Blocks']:
if block.get('Confidence', 100) < 85:
low_confidence_fields.append(block)
# Step 3: 信頼度低いフィールドを A2I で人間レビュー
if low_confidence_fields:
human_task_response = self.a2i.start_human_loop(
HumanLoopName=f'textract-review-{uuid.uuid4()}',
HumanLoopConfig={
'WorkteamArn': 'arn:aws:sagemaker:ap-northeast-1:123456789:workteam/...',
'HumanTaskUiArn': '...',
'TaskTitle': 'Document Field Verification',
'TaskDescription': 'Please verify the extracted fields',
'MaxConcurrentTaskCount': 1
},
InputContent={
'TextContent': json.dumps(low_confidence_fields)
}
)
return response
5. 税務書類・給与明細の処理
class TaxDocumentProcessor:
def __init__(self):
self.textract = boto3.client('textract')
def extract_tax_info(self, tax_document_pdf):
"""税務書類から所得・税額を抽出"""
response = self.textract.analyze_lending(
DocumentPages=[{'S3Object': tax_document_pdf}]
)
# ローン分析 API は W2・1099・確定申告書に対応
for doc in response['Results']:
doc_type = doc['DocumentType']
tax_info = {
'document_type': doc_type,
'gross_income': '',
'deductions': '',
'tax_liability': ''
}
for extraction in doc['Extractions']:
if 'INCOME' in extraction['Type']:
tax_info['gross_income'] = extraction['ValueDetections'][0]['Text']
elif 'DEDUCTION' in extraction['Type']:
tax_info['deductions'] = extraction['ValueDetections'][0]['Text']
elif 'TAX' in extraction['Type']:
tax_info['tax_liability'] = extraction['ValueDetections'][0]['Text']
return tax_info
CLI・SDK・IaC 例(スペース制限により簡潔)
CLI 例
# テキスト検出
aws textract detect-document-text \
--document 'S3Object={Bucket=my-bucket,Name=doc.png}' \
--region ap-northeast-1
# ドキュメント分析
aws textract analyze-document \
--document 'S3Object={Bucket=my-bucket,Name=form.pdf}' \
--feature-types FORMS TABLES \
--region ap-northeast-1
# ID 分析
aws textract analyze-id \
--document-pages 'S3Object={Bucket=my-bucket,Name=license.jpg}' \
--region ap-northeast-1
# 請求書分析
aws textract analyze-expense \
--document 'S3Object={Bucket=my-bucket,Name=invoice.pdf}' \
--region ap-northeast-1
# 非同期分析開始
aws textract start-document-analysis \
--document-location 'S3Object={Bucket=my-bucket,Name=large.pdf}' \
--feature-types FORMS TABLES \
--notification-channel SNSTopicArn=arn:aws:sns:... RoleArn=arn:aws:iam::... \
--region ap-northeast-1
比較表
| 特性 | Textract | Google Document AI | Azure Form Recognizer | ABBYY FineReader | Tesseract |
|---|---|---|---|---|---|
| フォーム認識 | ✅ | ✅ | ✅ | ✅ | ❌ |
| テーブル抽出 | ✅ | ✅ | ✅ | ✅ | △ |
| ID 抽出 | ✅ | ✅ | ✅ | ✅ | ❌ |
| 請求書分析 | ✅ | ✅ | ✅ | ✅ | ❌ |
| Queries | ✅ | ❌ | ❌ | ❌ | ❌ |
| 手書き対応 | ✅ | ✅ | ✅ | ✅ | △ |
| 非同期API | ✅ | ✅ | ✅ | ✅ | ❌ |
| A2I対応 | ✅(SageMaker A2I) | ❌ | ❌ | ❌ | ❌ |
| 言語 | 30+ | 50+ | 30+ | 100+ | 100+ |
| 無料枠 | 最初3ヶ月1000ページ/月 | 50ページ/月 | 500ページ | トライアル | 無し |
ベストプラクティス・トラブルシューティング・最新動向(スペース制限)
学習リソース
- Amazon Textract Developer Guide
- Textract API Reference
- Custom Queries Guide
- Google Document AI
- Azure Form Recognizer
採用判断チェックリスト
- [ ] PDF・画像からテキスト抽出が必要か
- [ ] フォームのキー・値抽出が必要か
- [ ] テーブルを構造化データとして抽出したいか
- [ ] 身分証明書から特定フィールド抽出が必要か
- [ ] 請求書・レシートの自動処理が必要か
- [ ] 大量ドキュメントを非同期処理したいか
- [ ] 信頼度低いフィールドに A2I で人間レビュー追加するか
- [ ] 自然言語クエリで柔軟に情報抽出したいか
まとめ
Textract は 「PDF・画像から構造化されたテキスト・フォーム・テーブルを自動抽出するドキュメント処理 AI」。AnalyzeDocument・AnalyzeID・AnalyzeExpense・AnalyzeLending・Queries の 5 つの API で、銀行融資申請・保険請求・医療問診票・物流書類・税務書類の自動処理を実現します。A2I との組み合わせで高精度パイプラインを構築でき、Comprehend・Bedrock との連携で自動インサイト抽出も可能です。
最終更新:2026-04-26 バージョン:v2.0