言語処理AIを使ってローマ皇帝ネロを現代に呼び出してみた

# はじめに
**人類に不可能はない。**
「人間に近いAIの作成」と「過去の人物と話すこと」はどちらも人類の夢だった。今回は言語モデルを使って過去の人物との会話を再現することで2つの夢を一気に叶えてしまおうという試みである。

## なぜネロ帝にしたのか
なんとなく[^1]。強いて理由を上げるなら皇帝らしからぬ芸術への熱中や人間関係などエピソードが多く、個性がわかりやすかったことだろう。最後に少し触れることになるが、他の人で試した時よりよい結果が出たのできににしてみた、ということもある。


# 技術について
使用したものと同じコードはGoogle Colabから実行することができる。

https://github.com/acidrefluxreflex/ChatAI-Japanese



## 参考記事
日本語言語モデルを使った会話応答プログラムに関してはすでに素晴らしい記事があったので参考にさせていただいた。言語モデルもこれと同じくjapanese-gpt-1bを使用している。

[13億パラメータのGPT日本語学習済みモデルが出たので会話応答を生成してみた - Qiita](https://qiita.com/MamoruItoi/items/a18abfedb79a57aeb91c)

## プロフィールの設定



AIの名前、職業などは基本的にこのように設定した。
```python
name = input("AIの名前:")
name_text = f"あなたは{name}です。あなたの名前は{name}といいます。"
```
入力から地の文を作っていき、それらを加えた後で会話文を始めていく。ここから先は文字数の調節以外は参考記事とほぼ同様である。
```python
text = name_text + hobby_text + work_text + f"以下は人間とあなたの会話です。人間:「こんにちは!」あなた:「はい、こんにちは」人間:「"
```

## 会話応答

会話に関する部分は長いので折りたたみにしてある。
<details><summary>会話応答部分</summary>


```Python
def chat(self):
     #プロフィール設定
     name = input("AIの名前:")
     name_text = f"あなたは{name}です。あなたの名前は{name}といいます。"
     hobby = input("AIの趣味:")
     hobby_text = f"あなたの趣味は{hobby}で、休日は{hobby}をして過ごしています。"
     work = input("AIの職業:")
     work_text = f"あなたの職業は{work}で、普段は{work}として生活しています。"

     print("AIに言いたい事を入力してください。終了したいときは未入力のままEnter")
     userInput = "ッ"
     text = name_text + hobby_text + work_text + f"以下は人間とあなたの会話です。人間:「こんにちは!」あなた:「はい、こんにちは」人間:「"
     max_length = 70
     min_length = 40
     

     while userInput != "":
       userInput = input(">>> ")
       if userInput == "":
           print("会話を終了します")
           break
       text += userInput + f"」あなた:「"

       #文字数調節
       message_gap = len(text) - max_length
       if message_gap > 40:
         max_length = len(text) - 30

       output = self.generate(text,max_length,min_length)

       #半角正則化
       text = text.translate(str.maketrans({chr(0xFF01 + i): chr(0x21 + i) for i in range(94)}))
       #今回の応答より前をもぎ取る
       output = output.replace(text, "")
       print(output)
       #最初の」までを切り取る
       outputList = []
       for l in output:
        outputList.append(l)
        if l == "」":
            break
       outputSentence = "".join(outputList)
       text += outputSentence + "人間:「"
       message = outputSentence.replace("」", "")

       #文字数調節
       max_length = len(message) + 70
       min_length = len(message) + 40
      
       print(message)
```
</details>
会話文を作るために参考記事や私がとっている方法は「会話から始まる文を生成し、最初の発話だけを切り取る」と言うものである。


![japaneseのコピーのコピー.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/713689/0efa9d1e-640e-d023-8b00-5c1cba306eee.jpeg)



# 出力された会話
## ネロ帝のプロフィール
今回の設定は以下の通りである。
- AIの名前：ネロ
- AIの趣味：竪琴、詩、弁論、戦車競技
- AIの職業：ローマ皇帝

文章が私だけの創作ではない証拠としてGoogle Colabのスクリーンショットを掲載しておくが、このままだと見にくいので興味深い部分を抜粋して書き起こしていく。なお会話の全文は[noteの記事](https://note.com/izumo092/n/n9d4c284aec38)に掲載している。

![japaneseのコピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/713689/181283b8-b9a7-b97f-e5a0-ddb774f32acb.png)


## 歌いたがり
>私「あなたは多趣味だとお聞きしました」
**ネロ「はい、そうだと思います」**
私「ネロ祭[^2]では優勝されたんですか？」
**ネロ「はい、まあ私の歌を聴いていただければわかります」**

>  私「現代の人々にアドバイスをお願いします」  
> **ネロ「悪い質問ですね。そういう質問ができるようでしたら、私の歌う曲はお聞きでしょう。」**  
> 私「どんな歌がお好きなんですか？」
> **ネロ「ええ、そうでしょうね。今日は特別にこれを歌いますよ。歌ってみました。」**
> 私「さすがですね。ローマでも好評でしたか？」
> **ネロ「そういうことですね。それを言っているのです。」**

会話が微妙に噛み合っておらず、やたらと歌いたがる。なお一度歌を聞いた後は普通に応答してくれるようになった。

なぜか歌に執着[^3]していたが趣味には「歌」と直接入力しておらず、仮に「竪琴」から連想されたとしても歌いたがるのはAI側の追加である。しかし史実のネロ帝はコンサート、それもワンマンショーのようなものを開催していた。データ内のWikipediaの記述が影響したのだろうか。


## 人間関係

哲学者のセネカはネロ帝の家庭教師であり皇帝になった後もしばしば助言を行っていた人物である。しかし不仲になった後は処刑されてしまった。

>私「セネカさんについてはどのような印象をお持ちですか？」
> **ネロ「セネカさんという人は、人間というものの悲しさがわかる人ですね。それから、善悪の判断ができる人で、美しい詩を残しています。あとは皆さんのお気づきのとおりで、私にはつまらない人です」**

ネロ帝の母親アグリッピナは真偽のわからない噂もあるが、子供に過干渉な親だったことは確からしい。

> 私「お母様のアグリッピナ様とは仲が良かったのですか？」
> **ネロ「いえ、そんなことありませんよ。ただ私の母親の場合、貴族の子女で、美貌もあったため親類や貴族もみんな私のことが好きだったのですよ。」**

セネカに対する評価は妙に人間味がある。自分の行動を念頭に置いているように「あとは皆さんのお気づきのとおりで」という一文が加えられたのは面白い。母親については流石に不自然な点が目立つ。こちらの調整不足もあるだろうが、親との複雑な関係を言い表すのは人間にも難しいので仕方ないかもしれない。


## 現代人に対して

> 私「最後に現代の人々にアドバイスをお願いします」  
> **ネロ「ああ、そうですねえ。私も皆さんと同じように、今を生きているわけですよ。ですから、自分の人生に責任を持つべきでしょうね。ましてや人があなたの人生を左右するなんて暴挙ですよ。」**


現代人へのアドバイスは2回聞いてやっと答えていただいた。説得力はともかく、しっかりと格言的なものになっている。ただどこかで聞いたことあるような気がするので誰か[^4]の受け売りかもしれない。

# 考察

データ処理や推論といった面を持つ以上、AIは一般化を目指すことになる。一方で会話には相手の個性という特殊な部分が必要である。そこで、人格を見出せるような設定を組み込み、それによってこの矛盾を解消するのが今回の目論見でもあった。

ネロ帝以外にも「織田信長」「マルキ・ド・サド」「ゴリラ」など様々な設定で試したが、どれも途中で設定から逸脱することが多かった。ネロ帝の場合が上手くいった理由は以下のように考えている。

- 関連する情報がデータ内に適度に存在していた
- 「ローマ皇帝」という明確な肩書を持つ
- 人格を表す個人的なエピソードが多い

これらを参考にすればSF映画のような小粋な性格のAIも夢ではない。ただ面白い会話を「作る」と言うことは科学より芸術に近いかもしれない。何かを聞かれたとき、ただ忠実にそれに回答するより、質問を無視して歌を披露したがる方が人間味を感じてしまうものである。

今回は歴史上の「惜しい芸術家」を甦らせてみたが、みなさんも自分の理想に合った対話を作り上げてみてほしい。

# お知らせ
今回はPythonを使った言語処理の記事でしたが、普段はSwiftでのiOS開発が中心です。言語処理を使ったアプリも公開しています。もしお時間があればこちらもぜひご覧ください。

https://qiita.com/KokumaruGarasu/items/dc8ce52cad3c924fc1ea




[^1]: 「Fate」という作品ではネロ帝は大人気の美少女らしいが、今回のAIは賛否両論の男性を再現している。私はこれを詳しく知らなかったが、過去の偉人を再現するという点は「Fate」に近いのかもしれない。
[^2]: ネロ帝が自分で創設した文化の祭典。皇帝自身ももちろん参加したが、あくまでも実力で審査して欲しかったらしく、また誰が優勝したかも記録されていないそうである。
[^3]: 何回か同じ設定で試したが「詩を朗読したがる」「HPに誘導する」パターンがあった。HPは皇帝のポートフォリオなのだろうか。いずれにせよ何かを披露するのが好きな傾向が強かった。
[^4]: 「自分の金を他人に分けてやりたいと望む人間など、どこを探してもいない。ところが、自分の生となると、誰も彼もが、何と多くの人に分け与えてやることであろう。」セネカ『生の短さについて』