PythonでOCRとchatGPTを使って、過去問の類似問題を作成したい。

Qiita初投稿になります。技術的にも未熟ですがどうぞよしなに。
# 始めに
　大学では過去問さえ持っていれば単位はどうにかなるという風潮がありますが、入手が難しい場合や少ししか手に入らない時があります。そんな場合、テスト対策に何を勉強すればいいか困りますよね（強引）。chatGPTを使ったら何とでもなるのではと思い作ってみることにしました。
# 流れ
　こんな感じのをイメージしてます。
```mermaid
graph TD;
    作成したい問題の画像をとり文字を読み取る-->その文字をchatGPTに流し類似問題を作成するように命じる
    -->完成した類似問題を出力する

```
# 前提条件
　せっかくなら画像から文字を読み取って、それに似た問題を作ってもらえたら嬉しい。
　事前準備としてはこちら。
　　・OpenAIのAPIキーの取得
　　・Tesseractのインストール（詳しくは[こちら](https://myafu-python.com/work/text-extraction/)）
　　・ライブラリのインストール
```python:
pip install pillow
pip install pyocr
pip install openai
```
# 画像から文字を認識する
　画像認識のプログラムはこんな感じです（ほとんど参考文献と同じ）。
　Tesseractのパスを環境変数に追加しておいてください。

~~~
from PIL import Image
import pyocr

#pyocrにTesseractを指定する。
pyocr.tesseract.TESSERACT_CMD = r'Tesseractのパス\tesseract.exe'
tools = pyocr.get_available_tools()
tool = tools[0]

#文字を抽出したい画像のパスを選ぶ
img = Image.open('画像のパス')

#画像の文字を抽出
builder = pyocr.builders.TextBuilder(tesseract_layout=6)
text = tool.image_to_string(img, lang="jpn", builder=builder)

print(text)
~~~
　ここで類似問題を作成したい問題の画像を選択し、文字を読み取ります。うまくいけば読み取られた内容が出力されるはずです（精度はまちまち…）。

# それをchatGPTに投げる
~~~
import openai

# APIキーの設定
openai.api_key = "APIkey"

assistant_roll = input("科目名を入れてください")
system_request = "あなたは{}の大学教授です"
system_result = system_request.format(assistant_roll)

user_request = "{}に類似した問題とその答えを作成してください"
user_result = user_request.format(text)


response = openai.ChatCompletion.create(
    model="gpt-3.5-turbo",
    messages=[
        {"role": "system", "content": system_result},
        {"role": "user", "content": user_result},
    ],
)
print(response.choices[0]["message"]["content"].strip())
~~~
　APIキーは各自で取得したものを入れてください。
　問題の科目名をユーザーに入力してもらい、chatGPTにはその科目の大学教授になりきってもらいます。その後、先ほど読み取った問題の類似問題を作成するように命じます。

# 実践
今回使用するのはこちらの画像。
![math1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3293324/8ddf3370-8755-c02f-3510-53da915a5f0f.png)
~~~:結果
#認識した文字
77616,267540の最大公約数をユークリッドの互除法によって求めなさい。

#chatGPTになりきってもらう役割
科目名を入れてください数学

#chatGPTの作成した問題とその解法
問題：12315と53555の最大公約数をユークリッドの互除法によって求めなさい。

解答：まず、12315を53555で割った余りを求めます。
53555で12315を割ると、商は0、余りは12315です。

次に、先ほどの余り12315を新たな割る数として、53555を割ります。
12315で53555を割ると、商は0、余りは12315です。

前回と同じ余りになってしまったので、余りが最大公約数となります。
つまり、12315と53555の最大公約数は12315となります。
~~~
えーと、問題は作成してくれましたが、解答はめちゃくちゃ間違っています……。
chatGPTは計算が苦手という話はよく聞きますが、これもそんな感じですね。

# 反省
　今回、作ってわかった反省点はこんな感じ、
　　・文字の認識があまり高い精度を保てない。
　　・chatGPTが嘘をつくことがままある（間違っていると気が付けないと問題）
　ただOCRとchatGPTのAPIを使えたのは面白かったです。

# 全体像
　参考までにプログラムを載せておきます。改良していただけたら、とてもうれしいです。
~~~
import openai
from PIL import Image
import pyocr

# APIキーの設定
openai.api_key = "APIkey"

#pyocrにTesseractを指定する。
pyocr.tesseract.TESSERACT_CMD = r'Tesseractのパス\tesseract.exe'
tools = pyocr.get_available_tools()
tool = tools[0]

#文字を抽出したい画像のパスを選ぶ
img = Image.open('画像のパス')

#画像の文字を抽出
builder = pyocr.builders.TextBuilder(tesseract_layout=6)
text = tool.image_to_string(img, lang="jpn", builder=builder)
print(text)

assistant_roll = input("科目名を入れてください")
system_request = "あなたは{}の大学教授です"
system_result = system_request.format(assistant_roll)

user_request = "{}に類似した問題とその答えを作成してください"
user_result = user_request.format(text)

response = openai.ChatCompletion.create(
    model="gpt-3.5-turbo",
    messages=[
        {"role": "system", "content": system_result},
        {"role": "user", "content": user_result},
    ],
)
print(response.choices[0]["message"]["content"].strip())
~~~

# 参考文献
こちらのサイトを参考に作成しました。ありがとうございました。
[PyocrとTesseractで精度の高いOCRを作ってみよう](https://myafu-python.com/work/text-extraction/)
[[初心者向き] OpenAI APIを使ってPythonでChatGPT遊びするための最初の三歩くらい](https://dev.classmethod.jp/articles/openai-api-chat-python-first-step/)