Azure Form Recognizerで帳票をバッチ処理する

Azure Form recognizerというサービスがあります。
https://azure.microsoft.com/ja-jp/services/cognitive-services/form-recognizer/

帳票をいい感じに読み取って狙ったデータを抽出してくれる優れものです。APIもあるので複数の帳票をまとめて処理できるPython scriptを書いてみました
https://github.com/yosukearaiMS13/formrecognizerbatch/blob/master/fy.py

以下、スクリプトの中身と使い方について説明します

# スクリプトの中身
スクリプトは、ドキュメントにあるサンプルを拡張して作っています
https://docs.microsoft.com/ja-jp/azure/cognitive-services/form-recognizer/quickstarts/python-labeled-data?tabs=v2-0

スクリプトは4つのsectionから構成されています
https://github.com/yosukearaiMS13/formrecognizerbatch/blob/master/fy.py

```python:fr.py

# Configurations: 各種設定パラメータ

# Post 分析対象pdf section
## Form recognizerに対し、分析対象データを一旦全部postします

# Get analyze results section
## 先ほどpostしたデータの分析結果（抽出されたデータ含む）を取得します。

# 抽出結果のcsv出力 section
## 抽出結果を出力します。余計な空白の除去と、信頼性が低い抽出値の置き換え
##（しきい値以下の場合抽出値は採用せず、代わりに信頼度を[]囲みで出力）
## を行っています

```

Get analyze resultsと抽出結果のcsv出力sectionでは、Form recognizerから返されたjsonをパースしています。jsonのフォーマットはこちらです
[https://github.com/Azure-Samples/cognitive-services-REST-api-samples/blob/master/curl/form-recognizer/Invoice_1.pdf.ocr.json](https://github.com/Azure-Samples/cognitive-services-REST-api-samples/blob/master/curl/form-recognizer/Invoice_1.pdf.ocr.json)

出力されるcsvのフォーマットは以下です。
- 先頭列: 分析対象の帳票ファイル名
- 2列目以降: 分析モデルに設定した全ラベル（タグ）と、それに対応する抽出値
![csv.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327770/05bf8cff-350f-59c8-78d5-cc3b5c957174.png)


各セクションで利用しているAPIは以下です
- Post 分析対象pdf: [Analyze Form](https://westus2.dev.cognitive.microsoft.com/docs/services/form-recognizer-api-v2/operations/AnalyzeWithCustomForm)
- Get analyze results: [Get Analyze Form Result](https://westus2.dev.cognitive.microsoft.com/docs/services/form-recognizer-api-v2/operations/GetAnalyzeFormResult)
- CSV出力section: [Get Custom Model](https://westus2.dev.cognitive.microsoft.com/docs/services/form-recognizer-api-v2/operations/GetCustomModel)
　- 当該APIにて定義済みの全ラベルを取得し、csvのヘッダの値として使用しています

# スクリプトの使い方
## 1. 環境
Win10 Enterprise, Python 3.8.5, IDEは任意

## 2. データ抽出準備
（※前提作業~データ抽出準備1までは、[こちらのQiita記事](https://qiita.com/komiyasa/items/afee82f7baddcd820251)も参考になります）

- 前提作業: 以下を先にやっておきます
  - [Form Recognizer リソースの作成](https://docs.microsoft.com/ja-jp/azure/cognitive-services/form-recognizer/quickstarts/label-tool?tabs=v2-0#create-a-form-recognizer-resource)
  - [Azure blobの作成(ストレージアカウントの作成->コンテナの作成まで)](https://docs.microsoft.com/ja-jp/azure/storage/blobs/storage-quickstart-blobs-portal)
  - [Azure blobの設定（Shared Access Signatureの作成）](https://docs.microsoft.com/ja-jp/azure/storage/blobs/storage-quickstart-blobs-storage-explorer#work-with-shared-access-signatures)（Azure PortalのStorage Explorerメニューを使うと便利です）
    + ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327770/e4cb77d7-2dbe-31be-67e7-4ef4a036cd9b.png)
    + （アクセス許可の欄は全てcheckします）![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327770/aaae5370-fc5e-688e-b454-39a60518978e.png)
    + （生成されたURL値を後から使いますので、保存しておいてください）![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327770/705f3739-b5be-ddbe-0001-915d953131b5.png)

 

- データ抽出準備1（初回のみ実施）
  - モデル作成用のトレーニングデータをAzure blobに格納する: 以下の形で最低5ファイル（この場合invoice_1~5.pdf）を配置ください（xx.jsonは後から作られるファイルですのでここでは無視）
  - ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327770/c9c47076-ce5d-5852-99de-13ccc94571ca.png)

  - ラベル（タグ）付けツールの設定:
      +  ラベル付けツールはこちら　[https://fott.azurewebsites.net/](https://fott.azurewebsites.net/)
      +  ラベル付け手順: 以下ドキュメントの手順に従い、ラベル付けツールへの接続->プロジェクト作成、まで実施
          +  https://docs.microsoft.com/ja-jp/azure/cognitive-services/form-recognizer/quickstarts/label-tool?tabs=v2-0#connect-to-the-sample-labeling-tool
  - pythonスクリプトへの設定#1

```python:fr.py
## Configurations
endpoint = r"https://xxxxx.cognitiveservices.azure.com/"
apim_key = "xxxxx"
model_id = "xxxxx"
sourceDir = r"C:\xxxxx\*"
confidence_setting = 0.9 # 0~1. 信頼性がこの値以下の場合採用しない
```

　　- endpoint: Form Recognizerのエンドポイント
　　- apim_key: Form Recognizerのキー1 or 2![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327770/21e50af5-135e-a847-6040-233601fdfbbf.png)
　　- sourceDir: 分析対象の帳票ファイルの配置場所をフルパスで記述
　　- confidence_setting: 0~1の値を設定（※スクリプトの仕様として、信頼性がこの値以下の場合抽出された値は採用せず、代わりに信頼性の評価値を[]囲みで出力する仕様にしています）


- データ抽出準備2（ラベルを追加修正する度に実施）
  - ラベル（タグ）付けツール（[https://fott.azurewebsites.net/](https://fott.azurewebsites.net/)）にて、読み込まれたトレーニングデータ（帳票）にラベルをつけていく。つけ終わったらTrainして、モデルを生成する
      + 以下ドキュメントの手順: フォームにラベルを付ける-> カスタム モデルをトレーニングする、まで実施
          + https://docs.microsoft.com/ja-jp/azure/cognitive-services/form-recognizer/quickstarts/label-tool?tabs=v2-0#label-your-forms
      + [こちらのQiita記事](https://qiita.com/komiyasa/items/afee82f7baddcd820251#%E3%82%AB%E3%82%B9%E3%82%BF%E3%83%9E%E3%82%A4%E3%82%BA%E3%82%92%E5%AE%9F%E8%A1%8C%E3%81%99%E3%82%8B) の手順も参考になります
      + Train後Model IDが生成されます（以下）。この値は後で使います![image.png](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F149921%2Ffa4048dc-c641-38e0-6ad9-d1a6e2b291bf.png?ixlib=rb-1.2.2&auto=format&gif-q=60&q=75&s=c73deb1bac3ffc3074b2b6cbd14d359e)
  - pythonスクリプトへの設定#2: model_id

```python:fr.py
## Configurations
endpoint = r"https://xxxxx.cognitiveservices.azure.com/"
apim_key = "xxxxx"
model_id = "xxxxx"
sourceDir = r"C:\xxxxx\*"
confidence_setting = 0.9 # 0~1. 信頼性がこの値以下の場合採用しない
```

　　- Model_id: 上記で取得したModel IDをセットします

## 3.データ抽出実施 

- sourceDirに分析対象の帳票ファイルを配置する
- fr.pyを実行
- スクリプトと同じフォルダにデータ抽出結果csvが出力されます
- ![exec_py.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327770/bb8b9bb3-ddb2-45e7-2cb7-7323cbeaf0cc.png)

## 4. 制約など

- トレーニング及び分析対象帳票のファイル形式ですが、PDFしか試していません
- Form recognizerの現行バージョンv2.0ベースで作っています。他バージョンで使う場合、APIのURLの適宜変更と、Form recognizerが返すjsonフォーマット変更への対応が必要になると思います