Amazon Textractで自然言語を使ったクエリ機能オプションが追加されていたのでためしてみた

2022.04.24

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

いわさです。

Amazon Textractを使うとドキュメントからテキストやフォームデータを抽出することが出来ます。
Textractでは単にOCRとしてテキストを抽出するだけでなく、テキストのフォームデータやテーブルデータとして認識するアイテムの分析機能があります。
先日、その分析機能にクエリ機能が追加されました。

このクエリ機能を使うと、自然言語を用いてドキュメントから必要なアイテムを指定出来るようになりました。
実際に使ってみると具体的な利用シーンがわかるのでさっそく試してみましょう。

なお、残念ながらまだ日本語には対応されていません。

マネジメントコンソールから

CLIやSDKから利用することも出来ますが、マネジメントコンソールから機能を試すことが出来ますのでまずはそちらから試してみます。
サンプルドキュメントも用意されているので便利です。

今回、クエリメニューが追加されています。

既にサンプルのクエリが設定されていて、ドキュメント上でも強調されていますね。
このようにクエリを自然言語による質問形式で入力し、Textractがドキュメント上から要素を案内してくれます。

もちろん自分でクエリを入力することも出来ます。
クエリの編集画面からサンプルクエリを削除し、新たに1つ追加してみましょう。

サンプルドキュメントはワクチン接種カードのようです。カードのタイトルを聞いてみます。

クエリに対する回答が得られていますね。
このように、ひとつひとつのドキュメントのコンテキストやレイアウトに依存した抽出条件をTextractにおまかせ出来ます。

色々なパターン

他にもいくつかパターンを試してみましたので紹介します。

表の中の一部分のデータを取得してみます。
ここでは一回目に接種したワクチンの品名を聞いてみました。

「ファイザー」と回答がありました。

何回ワクチン接種したのかを聞いてみました。
こちらは回答が得られませんでした。

私の英語が悪い可能性もおおいにあり得るのですが、いくつかのパターンを試してもダメでした。
与える情報をもう少し工夫する必要があるかもしれないです。

今度は、Yes/Noを聞いてみました。
明確なものに関しては回答してくれました。

こちらはNoの例です。

上記は明確にYes/Noを回答しやすい質問だったのですが、「ワクチンのBooster Shotは実施済みか?」などは回答を得られませんでした。
テーブルデータに関する質問は条件の与え方をもう少し工夫しないといけない可能性があります。

CLIから

実際に利用する際はSDKやCLI/APIから利用することになると思います。
今回はCLIのAnalyze-Documentで確認をしました。

新しい抽出アクションが追加されたわけではなく、Analyze-DocumentサブコマンドのQueryオプションとして指定する点に注意です。
なお、このオプションはAWS CLIだと v2.5.7以上から利用が可能なのでバージョンアップをしましょう。

事前に先程のサンプルドキュメントと同じものをJPEG形式でS3バケットに保存しており、documentパラメータでS3オブジェクト情報を指定します。
なお、通常のanalyze-documentの結果が得られるので要素が膨大です。ここではjqを使って、BlockTypeでフィルタリングしています。

クエリの結果はBlockTypeがQUERY_RESULTで取得されます。

$ aws textract analyze-document --document '{"S3Object":{"Bucket":"hogebucketname","Name":"hoge.jpeg"}}' --feature-types '["QUERIES"]' --queries-config '{"Queries":[{"Text":"What is the patient name?"}]}' | jq '.Blocks[] | select(.BlockType == "QUERY_RESULT" or .BlockType == "QUERY")'
{
  "BlockType": "QUERY",
  "Id": "f8877c84-059b-4c2a-91a9-33ad857f33d6",
  "Relationships": [
    {
      "Type": "ANSWER",
      "Ids": [
        "4a1653e2-f44a-4348-ac3b-b1bba3d76ea7"
      ]
    }
  ],
  "Query": {
    "Text": "What is the patient name?"
  }
}
{
  "BlockType": "QUERY_RESULT",
  "Confidence": 76,
  "Text": "Mary Major",
  "Geometry": {
    "BoundingBox": {
      "Width": 0.31586402654647827,
      "Height": 0.035269711166620255,
      "Left": 0.03966005519032478,
      "Top": 0.14315353333950043
    },
    "Polygon": [
      {
        "X": 0.03966005519032478,
        "Y": 0.14315353333950043
      },
      {
        "X": 0.35552409291267395,
        "Y": 0.14315353333950043
      },
      {
        "X": 0.35552409291267395,
        "Y": 0.17842324078083038
      },
      {
        "X": 0.03966005519032478,
        "Y": 0.17842324078083038
      }
    ]
  },
  "Id": "4a1653e2-f44a-4348-ac3b-b1bba3d76ea7"
}

名前を質問し、回答で得られていますね。

さいごに

日本語早く来てほしいというのは毎回のことですが、早く来てほしいですね。

この機能の利点としては自然言語で質問するだけなのでドキュメントのレイアウトを意識しなくても抽出出来る点です。
シンプルなOCRの場合は抽出されたテキストから、さらに必要な情報を探す必要があると思いますが、分析機能でクエリが使えるようになっておまかせできるようになるというのは、Textractが単なるOCRサービスではないという点を象徴したアップデートな感じががしますね。

とはいえ自然言語なので、聞き方でかなり精度が変わる様子です。
以下の記事ではクエリの作成にあたってベストプラクティスが案内されていますのでこのあたりを意識してパフォーマンスや精度の調整を行う必要があります。

抜粋すると、

  • 複数の回答が得られるような曖昧な質問は避けて、具体的なるようなヒントを与えた質問にする
  • 出来るだけドキュメント上の単語を使用して明確化する
  • もし事前にレイアウトを知っている場合は場所についても質問に含める(例:「一番上」など)
  • 回答の語数が長くなるような質問を避ける