Document IntelligenceとAI翻訳でローカルファイルのPDFを翻訳する

今回は何となく思いついた、英文のPDFファイルを日本語に翻訳するということをやっていきたいと思います。
（翻訳サイトにぶん投げればいいじゃんと言われたらそれまでですが、文量が多いとめんどくさいですしね。）

前提として、ドキュメント翻訳の機能を使えば、PDFファイルはAI翻訳単体で翻訳することが出来ます。
しかし、ローカルにあるファイルに対してドキュメント翻訳を適用する方法が見つからなかったので、今回はDocument Intelligenceで文書ファイルからテキストを抽出し、AI翻訳でテキストを翻訳するというやり方でやっていきたいと思います。

# Document Intelligenceの作成
1. [Azure](https://portal.azure.com/)にアクセスします。
1. 「Document Intelligence」を選択します。
    ![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3314839/d0d717ad-448f-7b65-459c-b5cc2e1d2b3e.png)
1. 「作成」を選択します。
    ![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3314839/1d2f11c3-233a-f612-6d87-61662c1e9309.png)
1. サブスクリプション、リソースグループ、リージョンを選択し、名前を入力してください。
価格レベルは無料プランがありますので、個人利用ならそれで十分だと思います。
![3_blur.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3314839/1901adb2-8c4c-c2ed-f34e-eaaf22ab2dbe.png)
1. その他の項目はデフォルトで構いません。リソースを作成してください。これで完了です。

# AI翻訳の作成
手順はDocument Intelligenceと同じです。
手順2で検索欄に「翻訳」と入力してください。

# コードを作成する
サンプルコードは下記の通りになります。
``` python
from azure.ai.formrecognizer import DocumentAnalysisClient
from azure.core.credentials import AzureKeyCredential
import requests
import uuid
import json
import sys
import os
from tkinter import filedialog
from pathlib import Path


def getPdfPath():
    # 選択可能なファイル形式
    type = [('文書ファイル', '*.pdf')]

    # 初期パス
    dir = "C:\\Users\\"

    # ファイル選択ダイアログ
    pdf_path = filedialog.askopenfilename(filetypes=type, initialdir=dir)
    if not (pdf_path):
        # キャンセル
        return pdf_path
    else:
        # 選択したファイルのフルパスを返す
        return Path(pdf_path)


def pdfToText(filePath):

    # キーとエンドポイントを設定
    form_recognizer_client = DocumentAnalysisClient(
        endpoint="Document Intelligenceのエンドポイント",
        credential=AzureKeyCredential("Document Intelligenceのキー"),
    )

    # PDFファイルをオープン
    with open(filePath, "rb") as f:
        # PDFファイルを分析
        poller = form_recognizer_client.begin_analyze_document(
            "prebuilt-read", document=f)

    # 分析結果を取得
    form_recognizer_results = poller.result()

    # PDFファイルと同じ場所にテキストファイルを作成
    filename = str(filePath).replace('pdf', 'txt')

    text = ''

    with open(filename, "w", encoding="utf-8") as f:
        # ページ数でループ
        for page in form_recognizer_results.pages:
            # 行数でループ
            for line in page.lines:
                # ファイルに抽出結果を書き込む
                f.write(line.content+"\n")
                text = text + line.content
    return text


def translate(filePath, text):
    # キーとエンドポイントを設定
    key = "AI翻訳のキー"
    endpoint = "AI翻訳のエンドポイント"

	# リージョンを設定
    location = "japaneast"

	# postするURLを作成
    path = '/translate'
    constructed_url = endpoint + path

	# apiのバージョンと変換元言語、変換先言語を指定する
    params = {
        'api-version': '3.0',
        'from': 'en',
        'to': ['ja']
    }

	# ヘッダー設定
    headers = {
        'Ocp-Apim-Subscription-Key': key,
        'Ocp-Apim-Subscription-Region': location,
        'Content-type': 'application/json',
        'X-ClientTraceId': str(uuid.uuid4())
    }

	# ボディ設定
    body = [{
        'text': text
    }]

	# 翻訳をかける
    request = requests.post(
        constructed_url, params=params, headers=headers, json=body)
    response = request.json()

	# 翻訳結果を取得
    result = response[0]["translations"][0]["text"]

    # PDFファイルと同じ場所にテキストファイルを作成
    filename, ext = os.path.splitext(str(filePath))
    filename = filename+"-ja.txt"

    with open(filename, "w", encoding="utf-8") as f:
        # ファイルに抽出結果を書き込む
        f.write(result.replace('。', '。\n'))


if __name__ == "__main__":
    # パスを取得
    filePath = getPdfPath()

    if not filePath:
        sys.exit()

    # PDFをテキストに変換
    text = pdfToText(filePath)

    # テキスト翻訳
    translate(filePath, text)
```

キーとエンドポイントは作成したリソースの値を設定してください。
それぞれ、リソースの概要にあります。
![5_blur.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3314839/3db55441-e874-59ed-31ee-1c964b09b458.png)

![4_blur.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3314839/555f8157-91f2-0e0d-ce39-4e9e38fdd41e.png)

# 実行してみる
それでは、実行してみます。
今回は、TOEFLのサンプル問題の１ページ目だけで試していきたいと思います。
https://www.cpi-japan.com/_files/ugd/7e6e28_1151b466fa9642aa8e46345712536d2d.pdf

このファイルを選択して、実行すると2つのテキストファイルが作成されると思います。
1つ目は拡張子がtxtに変わっただけのファイル、2つ目はファイル名に「-ja」が付加されたテキストファイルです。
これは、Document Intelligenceで抽出したテキストを書き込んだものと、抽出したテキストを翻訳にかけて日本語に変換されたものをテキストファイルに書き込んだものになります。

まずは、Document Intelligenceで抽出した結果を確認してみます。
```
TOEFL IBT Sample
Reading
Cougars
(1)
Originating in the highland areas of Brazil about 300,000 years
ago, the cougar -- otherwise known as the puma or mountain lion
-- is one of the largest cats in the Americas, second only to the
jaguar. Despite popular belief, the animal is not a "big cat."
This is because it is smaller than the biggest members of the cat
family, such as lions or tigers. Likewise, unlike those big cats,
the cougar cannot emit an ear-piercing roar. Nevertheless, the
cougar is an excellent hunter that can bring down prey -- such as
moose -- that are several times its size.
(2)
Cougars live in nearly every type of climate in the Americas,
except the arctic. Indeed, of all the large predators in the
Western Hemisphere, it has the widest range. This is evident in
that cougar populations exist in places as far apart as Patagonia,
the Sonoran Desert and the Yukon. With its easy adaptability to
various weather and terrain, prey abundance is the primary
factor in whether a specific region can support cougars.
Secondary factors include thick vegetation or rock cover, both
for hunting and, for females, to hide kittens.
(3)
```
ざっと確認したところ完璧に抽出できていました。文句なしですね。
次に、日本語訳したテキストファイルの方も確認してみます。
```
TOEFL IBT SampleReadingクーガー(1)約30万年前にブラジルの高地に生息するクーガーは、ピューマまたはピューマとも呼ばれ、アメリカ大陸でジャガーに次ぐ最大のネコ科動物の1つです。
一般に信じられていることとは裏腹に、この動物は「大きな猫」ではありません。
これは、ライオンやトラなどのネコ科の最大のメンバーよりも小さいためです。
同様に、それらの大きな猫とは異なり、クーガーは耳をつんざくような咆哮を発することができません。
それにもかかわらず、クーガーは優れたハンターであり、その数倍の大きさの獲物(ムースなど)を倒すことができます。
(2)クーガーは、北極圏を除くアメリカ大陸のほぼすべてのタイプの気候に住んでいます。
確かに、西半球のすべての大型捕食者の中で、それは最も広い範囲を持っています。
これは、クーガーの個体群がパタゴニア、ソノラ砂漠、ユーコン準州など、遠く離れた場所に存在することからも明らかです。
さまざまな天候や地形に簡単に適応できるため、獲物の豊富さは、特定の地域がクーガーをサポートできるかどうかの主な要因です。
二次的な要因には、狩猟用と、雌の場合は子猫を隠すための厚い植生または岩被覆が含まれます。
(3)
```
改行の基準を決めるのが、なかなか難しいため、今回は「。」がつくたびに改行しました。
私は英語が得意ではないですが「ピューマまたはピューマ」というのは日本語的にはおかしいです。
しかし、調べてみるとマウンテンライオンとピューマは同じ動物らしいので、ある意味より正確に訳せているのではないでしょうか。
私の英語力に絶望しつつ、残りはDeepLさんに任せたいと思います。
```
TOEFL IBTサンプル
リーディング
クーガー
(1)
約30万年前にブラジルの高地で誕生したクーガー（ピューマまたはマウンテンライオンとして知られる）は、ジャガーに次ぐアメリカ大陸最大のネコ科動物のひとつである。
一般に信じられていることとは裏腹に、この動物は「大きな猫」ではない。
というのも、ライオンやトラのようなネコ科最大の動物よりも小さいからだ。
同様に、それらの大型ネコ科動物とは異なり、クーガーは耳を劈くような咆哮を発することができない。
とはいえ、クーガーはその数倍の大きさのヘラジカなどの獲物を仕留めることができる優れたハンターである。
(2)
クーガーはアメリカ大陸のほぼすべての気候に生息している、 北極を除く。実際、西半球の大型肉食動物の中で クーガーは西半球に生息する大型肉食動物の中で最も広い範囲に生息している。
このことは クーガーの個体群がパタゴニアから遠く離れた場所に存在していることからも明らかである、 パタゴニア、ソノラン砂漠、ユーコンなど、遠く離れた場所にクーガーの個体群が存在することからも明らかである。
様々な天候や地形に適応しやすく 様々な天候や地形に適応しやすいクーガーにとって、獲物の豊富さは、特定の地域がクーガーを維持できるかどうかの第一の要因である。特定の地域がクーガーを養えるかどうかの第一の要因である。
二次的な要因としては、厚い植生や岩の覆いなどがある。メスの場合は子猫を隠すためである。
(3)
```
どちらも大方訳せてそうですが、主観と偏見マシマシな視線で見ればDeepLの方が正確かなと思いました。

# まとめ
今回はDocument Intelligenceと翻訳を使って文書ファイルを日本語訳するものを作りました。
余裕があればChat GPTのようにファイルを投げて、文書に関しての質問の回答や要約の作成なんかもやってみたいです。