GPTファインチューニングデータをかさ増しする

# GPT-3.5がファインチューニング対応可能に
GPT3.5がAPI利用でファインチューニング（カスタマイズ）可能となり「できた・できない」「こうすればよい」など様々話題になっています。

https://qiita.com/tmgauss/items/22c4e5e00282a23e569d


ただいざ
### 独自のデータ用意して

と言われると困るわけで、基本は **「質問」：「回答」** のペアでデータを用意しなくてはいけないので、なかなか難しいところです。
そんな中、すごいものが登場しました。
# LlamaIndexによるQAの作成

[LlamaIndex](https://medium.com/axinc/llamaindex-chatgpt%E3%81%A7%E7%8B%AC%E8%87%AA%E3%81%AE%E3%83%87%E3%83%BC%E3%82%BF%E3%81%AB%E5%AF%BE%E3%81%97%E3%81%A6%E8%B3%AA%E5%95%8F%E3%81%99%E3%82%8B%E3%81%9F%E3%82%81%E3%81%AE%E3%83%95%E3%83%AC%E3%83%BC%E3%83%A0%E3%83%AF%E3%83%BC%E3%82%AF-4f87c82f2f92)というLLM関連ツールを利用し、読み込んだ文章から **「質問」：「回答」** を自動で抽出しています。※こちらはnpakaさんの解説note

https://note.com/npaka/n/ne1990cdbb39a

蒸留…ってのがすごいですね。
やっているとことはGPTを使って **”あなたは教師だから、この文章から問題を作って”**
と指示しているようです。

# ファインチューニングデータのかさ増し

ただこちらの方法は決まった文章や資料を学習させたい場合に有効で、GPTに **ある人物やキャラクターになりきって回答してもらう** ファインチューニングには利用しづらそうです。

しかし、このGPTに質問を作ってもらうという発想はどうにか利用できないかと思いました。
ということで、今回GPTにファインチューニングに使う質問データを増やしてもらうツールを作りました。

**元のQ&Aデータはこちら**
![スクリーンショット 2023-09-09 140846.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3549938/dd0dbef1-1bba-4fed-069c-1e923b950dc6.png)
単純に質問と回答を記載したCSVです。GPTに大谷翔平選手になってもらおうとしています。
これを読み込んでGPT3.5に質問を増やして新たなCSVを作ってもらいます。

```Python:Python
import openai
import pandas as pd

openai.api_key = '-- ここはOpenAIのAPIキー --' 

import pandas as pd

# 変数初期化
df_newqa = pd.DataFrame()

# 入力(QA)ファイルパス指定
qa_filepath = '/content/otani_qa.csv'

# 出力ファイルパス指定
out_filepath = "/content/otani_newqa.csv"

# GPTへの指示
instruction = "AIの学習を強化する試みを行っています。 私が提示する質問を別の言い方に変えてください。回答は2つお願いします。"

with open(qa_filepath, "r") as file:

    for line in file:

        # CSVファイルを1行ずつ読み込み","で分割
        strs = line.split(",")

        # 2列目が質問、3列目が回答とする（1列目は行数）
        question = strs[1]
        answer = strs[2].replace('\n', '') # 改行を消す

        # 最初に自作の質問・回答も返戻用DataFrameに加える
        df = pd.DataFrame([[question,answer]])
        df_newqa = pd.concat([df_newqa,df])

        # "質問"を使いGPTへ問い合わせ（"回答"は使わない）
        response = openai.ChatCompletion.create(
          model='gpt-3.5-turbo',
          messages=[
                {'role': 'system', 'content': instruction},
                {'role': 'user', 'content': f'「{question}」を別の言い方に変えてください。日本語で2つ回答をお願いします。'},
            ]
        )

        # GPTからの回答内容取得
        response_mes = response.choices[0].message.content

        # 改行で分割（回答が2つある想定）
        gpt_question =response_mes.split('\n')

        for gq in gpt_question:

          # かぎかっこや1,2など余計な文字を消す
          gq = gq.translate(str.maketrans({'1': '', '2': '','１': '', '２': '', '.': '','「':'','」':'',')':'','(':''}))
          gq = gq.strip()

          # DataFrameに追加
          df = pd.DataFrame([[gq,answer]])
          df_newqa = pd.concat([df_newqa,df])

# DataFrameに列名・indexを付ける
df_newqa = df_newqa.rename(columns={0:'質問',1: '回答'}).reset_index(drop=True)

# CSVに出力
df_newqa.to_csv(out_filepath, index=True)
```
<br>

**出力結果（CSV）**
![スクリーンショット 2023-09-09 142023.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3549938/f8ef1699-d19f-d255-9913-9a7bebc9eac3.png)

GPTへのシステムプロンプトは **”AIの学習を強化する試みを行っています。 私が提示する質問を別の言い方に変えてください。回答は2つお願いします。”** とし、個々プロンプトも **「～」を別の言い方に変えてください。** といった問いかけにしています。2つお願いしましたが、別に何個でもいいと思います。

AIに対し **「AIの学習を強化する試み」** と言うのは変ですが、ここはなんでもいいと思います。
あとGPTの回答形式は様々で、コードで"「」"など不要なものを消していますが、それでもいらないものが入ってきてしまうと思うので、そこは確認してください。

またコードからわかる通りCSVの **"回答"** は利用していません。
後々ファインチューニングデータを作りやすいように付けているだけで、GPTへの問い合わせには関係ないです。

**こんな同じような質問を学習させて意味あるの？**

と思う方もいるかと思いますが、あくまで私の体感ですが、学習させたQ&Aデータと全く同じ質問をしたときと、似たような質問のときでは回答スピードが結構違ってきます。
恐らくGPTが回答を受付けたとき→「これはファインチューニングにあったものか？」
を推論するのに時間がかかっているのだと思われます。（※あくまで推測です）

GPTのファインチューニングへのご参考にしていただければと思います。
<br>
**※noteでキャラクターLINEBOTの作成について書いており、そこから派生したものとなっています。**

https://note.com/nekoniii3/n/nd58f14ac181a