AIが生成した文章と人間が書いた文章を分類できるのか（本検証）

# 今回の検証内容
今回の検証は、[前回の検証][1]の続きからとなる。
前回の検証では、動物の名前を使ってWikipediaのsummaryを抽出してそれを人間の作成した文章とし、AIの作成した文章はChatGPTのAPIを使用して作成したうえで600件ほどのスモールなデータセットで、動物に関する説明の文章という種類を絞ったもので実施をした。今回の検証では、より汎化性を上げられるのかという命題のもと訳8万件ほどのデータセット（AIと人間それぞれ約4万件）を準備して検証を実施した。

# データセットに準備
今回に関しては、それぞれのデータセットは以下のように作成した。
 - 人間の作成した文章：Wikipediaのsummary
 - AIの生成した文章：LINE社の公開している[japanese-large-lm-3.6b-instruction-sft][2]の回答

## 人間側のデータセットの準備
人間側に関しては、前回の検証と同様にWikipediaのsummaryを使用して作成した。前回と違う点としては、大量のデータの準備が必要であったため、tensorflow_datasetsから[wiki40b/ja][3]を使用してWikipedia上のタイトルのみを取得したうえで、そのタイトルをWikipediaのAPIを使用して検索をかけsummaryを取得した点である。wiki40b/jaに関しては、タイトルのみだけでなく本文も取得できるものの、このデータセットが作成された当時の文章であることと、区切り方の関係でsummaryのみを抽出するのが難しかったため、タイトルのみを取得する形をとった。
取得に使用したnotebookに関しては以下に格納してある。
https://github.com/N-OKAMOTO1031/detect_AI_generated_sentences/blob/main/get_wikipedia_sentence.ipynb
データセットに関しては以下に格納してある。
https://github.com/N-OKAMOTO1031/datasets/blob/main/detect_AI_generated_sentences/main_verification/wikipedia_summary.csv

## AI側のデータセットの準備
今回の検証では、AI側のデータセットは公開されているモデルを使用して作成することにした。というのも、今回の4万件をChatGPTに投入するととんでもない料金（約400トークン×4万×0.002$=32000$）になるため流石に無理だったためである。使用したモデルとしては、LINE社が公開している[japanese-large-lm-3.6b-instruction-sft][2]を使用して実施した。ただ、それでも以下のような問題が発生した。
 - モデルが重く、colabのハイメモリ、A100のGPUでないとまともに動かない。
 - それらを使用しても単一のnotebookでは85時間かかる。
問題点の一つ目としては、お金の暴力で解決した。（大体15000円ぐらい飛んでった）二つ目に関しては、4万件のデータセットを100個ずつに分割したうえで一つずつ番号で管理し、ロードする際に終了している番号を探索し同じ番号を実行しないような仕組みを構築したnotebookを6枚（A100,V100のGPUに対して3枚ずつ）用意し同時実行することによって実行時間を短縮した。（一時間当たりの消費コンピューティングユニットが33とかになって買った分で足りるかかなりビビッた）
ただ、データ数が多く個人で検証を実施している関係でデータのクレンジングに関しては行っていない。今回に関しては、AIが生成した文章であればいいという判断のもと問題ないかと思ったが、後述するがクレンジングを行うことによって精度の向上ができた可能性もあったかもしれない。
こちらに関しても、作成したnotebookは以下に格納してある。
https://github.com/N-OKAMOTO1031/detect_AI_generated_sentences/blob/main/get_llm_sentence.ipynb
データセットに関しては以下に格納してある。
https://github.com/N-OKAMOTO1031/datasets/blob/main/detect_AI_generated_sentences/main_verification/llm_summary.csv

# ファインチューニングの実行
今回に関しても、使用したモデルは前回と同じモデル（[bert-base-japanese-whole-word-masking][4]）を使用した。
前回の検証と違う点に関しては、データセットの量が十分にあるためtrain、valid、testの3つに90%、10%、10%に分割を実施して検証を行った。
それ以外の大きな変更点はないため、詳しく確認したい方がいたら以下のnotebookを格納していただきたいです。
https://github.com/N-OKAMOTO1031/detect_AI_generated_sentences/blob/main/tuning_bert_japanese_classifier.ipynb

# 結果
今回のファインチューニングに関しては、前回に比べて大きく結果が変わった。今回の検証のtrainとvalidのlossの変化をいかに示す。問題点としては、trainのlossに関しては小さくなっていっているものの、validのlossが逆に大きくなってしまっている。（train側が振動していたためepochを20で終了させている）
testデータに対して予測した際のAccuracyに関しては、99.2%となったもののvalidのlossの挙動がかなり気になる結果となった。
考察に関しては次の項で実施したいと思う。
| epoch | train | valid |
| ---- | ---- | ---- |
| 1 | 170.2533 | 13.4073 |
| 2 | 65.7433 | 16.3315 |
| 3 | 48.2002 | 11.6937 |
| 4 | 33.2247 | 11.3996 |
| 5 | 25.2652 | 11.9813 |
| 6 | 16.6875 | 15.9069 |
| 7 | 12.8385 | 14.8391 |
| 8 | 8.4734 | 15.2402 |
| 9 | 7.1986 | 16.2623 |
| 10 | 6.2786 | 16.6848 |
| 11 | 3.8589 | 19.2246 |
| 12 | 6.7874 | 17.5390 |
| 13 | 4.625 | 17.8305 |
| 14 | 4.6859 | 18.3513 |
| 15 | 2.3763 | 19.8515 |
| 16 | 3.4197 | 18.3330 |
| 17 | 1.4315 | 21.2472 |
| 18 | 2.6571 | 20.8284 |
| 19 | 3.0832 | 20.8726 |
| 20 | 1.9641 | 21.0284 |

以下に前回の検証時のtrainとvalidのepochごとのlossの変化を添付する。（前回の検証に使用したnotebookを書き換えてしまっていたのでepochを20にして今回のために実行しなおしている）
| epoch | train | valid |
| ---- | ---- | ---- |
| 1 | 0.0503 | 0.0060 |
| 2 | 0.0425 | 0.0066 |
| 3 | 0.0343 | 0.0047 |
| 4 | 0.0309 | 0.0041 |
| 5 | 0.0276 | 0.0038 |
| 6 | 0.0271 | 0.9346 |
| 7 | 0.0227 | 0.4970 |
| 8 | 0.0197 | 0.1995 |
| 9 | 0.0179 | 0.0362 |
| 10 | 0.0161 | 0.0068 |
| 11 | 0.0148 | 0.0051 |
| 12 | 0.0129 | 0.0042 |
| 13 | 0.0120 | 0.0027 |
| 14 | 0.0111 | 0.0020 |
| 15 | 0.0098 | 0.0019 |
| 16 | 0.0101 | 0.0016 |
| 17 | 0.0086 | 0.0013 |
| 18 | 0.0082 | 0.0013 |
| 19 | 0.0073 | 0.0013 |
| 20 | 0.0072 | 0.0012 |

# 考察
今回の結果に関して、過学習の際の挙動に見えるためデータの分離に失敗している可能性があるようにも考えられる。しかしながら、ランダムにデータを分離しており一応3回ほど（これ以上はリソースの関係で難しい）実施したもののすべて同じような挙動をしていた。今回から以下のような原因が考えられる。
 - 今回、8万件とデータセットの規模が大きくなり、文章のカテゴリーに関してもかなり増えたためランダムな分離でも偏りが発生している可能性。
 - データセットに関して、単純に抽出しただけなのでノイズが多く混ざっている可能性。
 - 単純にカテゴリーが増えすぎて結果が発散してしまった可能性。

これらの考察に対しての対策としては以下のようなものが考えられる。
 - 文章をカテゴリーに分けて、それぞれでtrain、valid、testに分割を行う
 - クレンジング

しかし、個人での検証ではこの辺りが限界（リソース的にも規模的にも）な気がしているため今後の検証に関しては未定です。

[1]:https://qiita.com/NOkamo/items/178fba564d44cd1c18bc
[2]:https://engineering.linecorp.com/ja/blog/3.6b-japanese-language-model-with-improved-dialog-performance-by-instruction-tuning
[3]:https://huggingface.co/datasets/range3/wiki40b-ja
[4]:https://huggingface.co/cl-tohoku/bert-base-japanese-whole-word-masking