Amazon Textractに再入門する(2022年12月版)
はじめに
こんちには。
データアナリティクス事業本部 機械学習チームの中村です。
本記事は「クラスメソッド 機械学習チーム アドベントカレンダー 2022」の15日目です。
本記事ではAmazon Textractに入門していきます。
Amazon Textractとは
Amazon TextractはPDFなどのファイルからテキストを抽出するフルマネージドな機械学習サービスです。
単純なOCRだけではなく、フォームやラベルを識別・理解した上での抽出が可能です。
Pricing(料金)
今回も使用する前にPricingを確認していきましょう。
Pricingを確認することでおおよその機能概要も把握できます。
5つのAPIがあり、API毎に料金が変化する形となっています。5つのAPIは以下です。
- Detect Document Text API
- Analyze Document API
- このAPIは、さらにForms、Tables、Queriesなどの組み合わせで料金が変動します。
- Analyze Expense API
- Analyze ID API
- Analyze Lending API
Detect Document Text APIが最も料金が小さく、基本的な機能と考えれば良さそうです。
(参考までに今現在のUS Eastで、ページあたり$0.0015、1円もしない計算となります。)
Detect Document Text API以外は、一桁分料金が上昇します。
(参考までに今現在のUS Eastで最も高いAPIで、ページあたり$0.07、10円くらいの計算となります。)
それぞれのAPIの機能の概要は以下です。
- Detect Document Text API
- シンプルなOCR機能。画像データからテキストフォントや手書き文字を認識して、文字情報にします。
- Analyze Document API
- Forms、Tables、Queriesの組み合わせで使用する。
- Formsは、KeyとValueのペアで情報を抽出する。
- Tablesは、表形式のデータを抽出する。
- Queriesは、必要な情報を質問形式で与え、その該当したデータを抽出する。1ページあたりのクエリ数上限は処理モードにより15~30の幅で制限あり。
- Analyze Expense API
- 請求書ID、請求書番号、請求書#、関連する値などを請求書や領収書から抽出する。
- Analyze ID API
- パスポート(米国)、運転免許証、その他の身分証明書を理解
- Analyze Lending API
- 住宅ローン関連の様々な申請書類から情報の分類と抽出を自動化する、住宅ローン書類処理に特化したAPIです
この中でAnalyze Lending APIは最近リリースされた機能となります。
弊社のブログでも速報を出しています。
まだ日本語ページには、Analyze Lending APIのPricingが記載されておりませんので、英語のページをご確認ください。
サポート状況
リージョンは現在以下に対応しています。
- US East (Northern Virginia)
- US East (Ohio)
- US West (Oregon)
- US West (N. California)
- AWS GovCloud (US-West)
- AWS GovCloud (US-East)
- Canada (Central)
- EU (Ireland)
- EU (London)
- EU (Frankfurt)
- EU (Paris)
- Asia Pacific (Singapore)
- Asia Pacific (Sydney)
- Asia Pacific (Seoul)
- Asia Pacific (Mumbai)
日本のリージョンには対応していないので、注意が必要です。
言語としては英語、ドイツ語、フランス語、スペイン語、イタリア語、ポルトガル語に対応しており、日本語には対応していません。 また更に、手書き文字、請求書と領収書、身分証明書、クエリの処理は英語のみの対応となっているようです。
その他、ファイルのフォーマットとしては、PNG、JPEG、TIFF、PDFに対応しています。 150dpi以上の画質で提供するのが理想とされています。 PNG、JPEG、TIFFは1ファイル1ページとカウントされ、PDFは1ページをそのまま1ページとカウントします。
信頼度の扱い
Amazon Textractでは、抽出されたすべての抽出された情報が、各データを包含するバウンディングボックス座標で返されます。
またボックス毎に信頼度スコア(0から100の間の数値)が計算されるので、これによって、結果をどのように使用するかを信頼度に基づき意思決定を行うことができます。
具体的には、Amazon Augmented AIと統合されているため、信頼度が低い予測を人間の手でレビューすることが可能となっています。
統合は、信頼度スコアの閾値か、ランダムサンプリングの割合のいずれかを指定することが可能です。
データのプライバシーについて
その他、データのプライバシーについてFAQsに記載が多くあります。
データ削除が必要であれば要求に応じる、機密性の高いアクセスをしているなどの記載があります。
実際に組み込む場合は目を通しておく必要がありそうです。
マネコンから使ってみた
それではデモをかねてまずはマネジメントコンソールから使ってみたいと思います。
リージョンは us-east-1 を選択しておきます。
文書を分析する
まずは文書を分析するを左のメニューで選択してやってみます。
こちらは「Detect Document Text API」と「Analyze Document API」の結果を見ることができます。
デモ
Textractのページに行くとデモ画面になっていることが分かります。
右側の結果をクリックすると、左側でバウンディングボックスがハイライトされることが分かります。(逆も可能)
信頼度スコアについては、マネコンからは確認する方法がわかりませんでしが、後述するように結果をダウンロードすれば確認が可能です。
右側の結果は、タブに分かれており、生のテキストが一番シンプルな「Detect Document Text API」の結果で、 フォーム、テーブル、クエリが「Analyze Document API」の結果となっています。
フォームは、Key-Valueのペアを見つけてくれています。 縦のペアも横のペアも自動で判別しているようです。
テーブルは、検出されたテーブルの個数分それぞれ確認できます。 セルの結合などもうまく検出されていることがわかります。
クエリは、自然言語で知りたいものを尋ねる形で結果を得ることができます。
実際にアップロードして分析
次に実際にファイルをアップロードして動作を確認します。
この前のre:Invent 2022参加時に持参した、海外旅行の障害保険付保内容(英文版)の画像で試してみます。
フォーマットはJPGとなります。
ページの下部にボタンがあるので、そちらからローカルからファイルをアップロードできます。
アップロードすると、フォーム、テーブル、クエリ、署名の検出が選択できます。今回はフォームとテーブルにチェックします。
すぐに結果が得られます。
英語部分は問題なく抽出されていることがわかります。日本語文字は対応していないものの、多少ノイズとなって混ざってしまうようです。 こちらは、後述するように信頼度で足切りすることも可能です。
フォームもきちんとKey, Valueのペアが認識されています。
テーブルも問題なく抽出されていることがわかります。
結果のダウンロード
結果は以下のボタンからファイルで得ることも可能です。
zipがダウンロードされ、今回は以下のようなファイル構成となっていました。
ファイル名 | 説明 |
---|---|
analyzeDocResponse.json | 全ての結果が含まれるJSONファイル |
rawText.txt | OCRの結果(Detect Document Text APIの結果) |
keyValues.csv | フォームの結果 |
table-1.csv | テーブルの結果(連番でテーブル毎のファイル) |
table-2.csv | テーブルの結果(連番でテーブル毎のファイル) |
queryAnswers.csv | クエリの結果 |
signatures.csv | 署名の結果 |
analyzeDocResponse.jsonには全ての結果が含まれており、バウンディングボックスの場所やそれぞれの信頼度(Confidence)も確認することができます。 クエリと署名は有効にしていないのですが、レコード0件のファイルが取得されました。
アップロードファイルのフォーマット
マネコンからのアップロードは画面上でも記載の通り以下の制約があるため注意が必要です。
ドキュメントは 11 ページ未満、5 MB 未満で、JPEG、PNG または PDF のいずれかの形式である必要があります。
コンソールバケットについて
マネコンからPDFを処理する場合のみ、S3にコンソールバケットを作成する必要があり、マネコンから作成してよいか問われるため、その場合はOKを押すとコンソールバケットが作成されます。
費用の分析
次に、費用の分析で請求書などの分析を行ってみます。
こちらは「Analyze Expense API」の結果を見ることができます。
デモ
レシートの分析結果のデモがまず確認できます。
タブで「概要フィールド」と「明細項目のフィールド」に分かれており、 「概要フィールド」は、請求元名、請求元住所、請求元電話番号、請求日、合計金額、税などがきちんと見分けられています。
「明細項目のフィールド」もひとつずつ識別できていることが分かりますね。
実際にアップロードして分析
次に実際にファイルをアップロードして動作を確認します。
この前のre:Invent 2022参加時に現地で購入した際のレシートがありますので、そちらを使ってみます。 使うのはPanda Expressのレシートです。フォーマットはJPEGです。
先ほどと同様にアップロードボタンでアップロードすると以下のように検出結果が得られました。
正しく認識できていることがわかります。デモの文書と全くレイアウトが異なっていますが、このように識別できるのは凄いことですね。 明細もきちんと識別できていました。
他のレシートでもやってみます。バーガーキングのレシートです。
TOTALという項目がなく、AMOUNT PAIDとなっていますが、Normalized Fieldという形でTOTALに正規化されていることが分かります。
またTAXの字が消えかかっており、IAXと検出されているものの、こちらもNormalized FieldとしてTAXに正規化されていることが分かります。
ちなみにレシートの拡大図は以下のような形です。(縦に結構線が入ってしまっているものの、正規化を加味すると正しく処理できているのは凄いと感じました)
その他、何個か試しましたが、ほとんど検出できていそうです。
費用の分析のうち、最も難しそうなものは請求元名と感じました。この項目はロゴマークとともに印字してあったりするため、致し方ない部分もありそうです。
結果のダウンロード
先ほどと同様に結果もダウンロードすることができます。
ファイル名 | 説明 |
---|---|
analyzeDocResponse.json | 全ての結果が含まれるJSONファイル |
summaryFields-1.csv | 概要フィールドの結果(連番) |
lineItemFields-1.csv | 明細項目のフィールドの結果(連番) |
連番はレシート毎(PDFなどの場合にページ毎)に振られる番号となります。
フィールドの結果には、Normalized Fieldも記載されています。
アップロードファイルの制約
先ほどと同様、マネコンからのアップロードは画面上でも記載の通り以下の制約があるため注意が必要です。
ドキュメントは 5 MB 未満で、JPEG、PNG、PDF、TIFF のいずれかの形式である必要があります。
Boto3を使った確認
次にBoto3からの動作を確認していきます。
IAMユーザの準備
まずは作業用のIAMユーザを作成して、以下のポリシーを与えます。
今回は、cm-nakamura-test-textract
というユーザ名にしました。
- arn:aws:iam::aws:policy/AmazonTextractFullAccess
- arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess
後者のS3のポリシーはBytesではなくS3Objectとして同期実行をする場合や、非同期実行の場合(必ずS3Objectを使用するため)に必要となります。
作成後は、./aws/config
に以下を追記します。
[profile cm-nakamura-test-transcribe] region = us-east-1 output = json
また./aws/credentials
に認証情報を記載しておきます。
[cm-nakamura-test-textract] aws_access_key_id = "アクセスキー ID" aws_secret_access_key = "シークレットアクセスキー"
以下でアクティブにします。(PowerShellの場合)
$env:AWS_PROFILE = "cm-nakamura-test-transcribe"
同期実行
同期実行でリクエストするAPIは、レスポンスに解析結果が含まれる形のAPIです。
処理タイプ毎に以下のようにAPIが準備されているのでそちらを使います。(Analyze Lending APIは同期実行に非対応)
処理タイプ | API |
---|---|
Detect Document Text API | detect_document_text |
Analyze Document API | analyze_document |
Analyze Expense API | analyze_expense |
Analyze ID API | analyze_id |
Analyze Lending API | 非対応 |
まずは「Detect Document Text API」を使いBytesで入力するシンプルな例を試してみます。
import boto3 # Detect text in the document client = boto3.client('textract', region_name='us-east-1') with open("test.jpg", "rb") as image_file: data = image_file.read() response = client.detect_document_text( Document={'Bytes': data} )
responseとして得られるものは、先ほどもダウンロードができたanalyzeDocResponse.json
となります。
同様に「Analyze Document API」を使う場合も以下のようにします。
response = client.analyze_document( Document={'Bytes': data}, FeatureTypes=['FORMS','TABLES'] )
また、Bytesとして与えずにS3Objectを指定する形で処理させることもできるようですね。
response = client.detect_document_text( Document={ 'S3Object': { 'Bucket': 'バケット名', 'Name': 'オブジェクト名', } } )
結果はJSONのままでは見にくい場合もあるため、ある程度可視化するコードが必要となりそうです。 Pythonの場合は以下がJSONのパース時に参考になるかと思います。
またファイル形式はPDFにも対応していますが、単一ページのみで複数ページのPDFは、同期実行は対応していないためご注意ください。 (後述する非同期実行であれば複数ページにも対応しています)
非同期実行
非同期実行でリクエストするAPIは、ジョブを投げて、結果は別のAPIで取得するAPI群となります。
処理タイプ毎に以下のようにAPIが準備されているのでそちらを使います。(Analyze ID APIは非同期実行に非対応)
処理タイプ | ジョブ開始 | 結果取得 |
---|---|---|
Detect Document Text API | start_document_analysis | get_document_analysis |
Analyze Document API | start_document_text_detection | get_document_text_detection |
Analyze Expense API | start_expense_analysis | get_expense_analysis |
Analyze ID API | なし | なし |
Analyze Lending API | start_lending_analysis | get_lending_analysis,get_lending_analysis_summary |
「Detect Document Text API」を使うシンプルな例で試してみます。
response = client.start_document_text_detection( DocumentLocation={ 'S3Object': { 'Bucket': 'バケット名', 'Name': 'オブジェクト名', } } )
このように非同期実行は、S3Objectとして入力を与える必要があり、ローカルから直接Bytesを指定することができません。
結果は以下のAPIで取得します。
response = client.get_document_text_detection( JobId=job_id )
response['JobStatus']
が'IN_PROGRESS'
の場合は処理中で、'SUCCEED'
となっている場合は結果が得られます。
また処理が終わったかどうかをSNSトピックで通知することも可能となっているようです。詳細は公式ドキュメントを参照してください。
まとめ
いかがでしたでしょうか。Amazon Textractについての一通りの使用方法について触れていきました。
かなり性能も良いと感じたので、日本語対応されたら周囲での利用が進みそうな印象を受けました。期待して待ちたいと思います。
本記事が、今後Amazon Textractを活用されようとする方の一助となれば幸いです。