Help us understand the problem. What is going on with this article?

【所要時間1h】俺の彼女作ったった【クリぼっち回避】

More than 1 year has passed since last update.

こんにちは!
エンターテインメント事業本部にて、普段はサーバ/インフラ辺りの作業をしている @exit_00 と申します。

この度、エイチーム引越し侍Advent Calendar 2018にお邪魔させていただきました。
ということで、この記事は エイチームブライズ/エイチームコネクト/エイチーム引越し侍 Advent Calendar 2018 3日目の記事です。

あらまし

  • クリスマスの祝いとして日々作り上げていくアドベントカレンダー。
  • だが私は今年もクリスマスを1人で過ごす予定……。
  • 皆と明るく楽しく元気よくクリスマスを祝うには、自分で恋人を造るしかない!

この記事で得られること

  • ターミナル上に理想の恋人を造る入口に立つ
  • Python初心者が人工無能を実装するキッカケ

彼女の要件

  • Python使用
  • 人工無脳
  • ターミナル上で動作
  • 単語記憶
  • 恋愛感情のパラメータを保持

Let's 彼女を実装!

環境

  • Mac 10.14.1
  • Python 3.7.1
  • iTerm2

手順

  1. Pythonインストール
  2. 入力に対して予め定められた返答をランダムに返すクラスを実装
  3. 入力されたテキストを記憶
  4. 恋愛感情パラメータ保持

手順詳細

Pythonインストール

  • 各種記事参照
  • Homebrewでインストールしました

入力に対して予め定められた返答をランダムに返すクラスを実装

実装

main.py
  1 import random
  2
  3 class Main():
  4     _your_name = "";
  5     _word_list = ["お腹空いた", "ピザ頼んで", "それ何?"];
  6
  7     def __init__(self):
  8         global _your_name;
  9
 10         print("girlfriend: あなたの名前、教えて?");
 11         _your_name = input("your_name: ");
 12         print("おはよ、" + _your_name);
 13         print("帰るときは『バイバイ』って言って。");
 14
 15     def Response(self):
 16         while True:
 17             your_phrase = input("> ");
 18             if your_phrase == "バイバイ":
 19                 print(_your_name + "、またね。");
 20                 break;
 21             else:
 22                 print(random.choice(_word_list));
 23
 24 main = Main();
 25 main.Response();

実行

$ python main.py
girlfriend: あなたの名前、教えて?
your_name: exit_00
おはよ、exit_00
帰るときは『バイバイ』って言って。
> ok
ピザ頼んで
> わかった
お腹空いた
> ちょっとまって
それ何?
> 出前表
お腹空いた
> まってよ
お腹空いた
> バイバイ
exit_00、またね。

ちぐはぐですが、延々としゃべり続けてくれる彼女が誕生しました。

入力されたテキストを記憶

  • 1/3の確率で話しかけた内容について意味を問う場面を追加しました
  • 意味との結びつきは一旦置いておいて、少しずつ語彙が増えるようになります
  • ファイルに保存するため、次回起動時に保持されます

実装

main.py
  1 import random
  2
  3 class Main():
  4     PHRASE_PASS = 'phrase.txt';
  5     _your_name = "";
  6     _girlfriend_name = "girlfriend";
  7     _word_list = [];
  8
  9     def __init__(self):
 10         global _word_list;
 11         with open(self.PHRASE_PASS) as f:
 12             _word_list = [s.strip() for s in f.readlines()];
 13
 14     def SetName(self):
 15         global _your_name;
 16         print(self._girlfriend_name + ": あなたの名前、教えて?");
 17         _your_name = input("your_name: ");
 18         print(self._girlfriend_name + ": おはよ、" + _your_name);
 19         print(self._girlfriend_name + ": 帰るときは『バイバイ』って言って。");
 20
 21     def Response(self):
 22         while True:
 23             your_phrase = input("> ");
 24             is_what_mean = random.choice([True, False, False]);
 25             if your_phrase == "バイバイ":
 26                 print(self._girlfriend_name + ": " + _your_name + "、またね。");
 27                 break;
 28             elif is_what_mean:
 29                 print(self._girlfriend_name + ": " + your_phrase + "ってなに?");
 30                 your_phrase_sub = input("> ");
 31                 self.LearnPhrase(your_phrase, your_phrase_sub);
 32                 print(self._girlfriend_name + ": " + your_phrase_sub + "ってことなの?ふーん。");
 33             else:
 34                 print(self._girlfriend_name + ": " + random.choice(_word_list));
 35
 36     def LearnPhrase(self, your_phrase, your_phrase_sub):
 37         global _word_list;
 38         _word_list.append(your_phrase);
 39         f = open(self.PHRASE_PASS, "a");
 40         f.writelines(your_phrase);
 41         f.close();
 42
 43 main = Main();
 44 main.SetName();
 45 main.Response();

実行

$ python main.py
girlfriend: あなたの名前、教えて?
your_name: exit_00
girlfriend: おはよ、exit_00
girlfriend: 帰るときは『バイバイ』って言って。
> わかった
girlfriend: お腹空いた
> ピザ食べる?
girlfriend: ピザ頼んで
> わかった
girlfriend: わかったってなに?
> 了解
girlfriend: 了解ってことなの?ふーん。
> そうだよ
girlfriend: わかった
> バイバイ
girlfriend: exit_00、またね。

彼女が少しだけ賢くなりました!
次は恋愛感情への影響を実装します。

恋愛感情パラメータ保持

  • 喋る度に高感度が変化するように実装します
  • NGワード、GOODワードにより好感度の上下が変化します
  • 高感度により、喋る内容が変わります

実装

main.py
  1 import random
  2 import json
  3
  4 class Main():
  5     PHRASE_PASS = 'phrase.json';
  6     _girlfriend_name = "girlfriend";
  7     _emotional_mode = "GOOD";
  8     _love_score = 0;
  9     _your_name = "";
 10     _word_list = [];
 11
 12     def __init__(self):
 13         global _word_list;
 14         try:
 15             # ローカルJSONファイルの読み込み
 16             with open(self.PHRASE_PASS, 'r') as f:
 17                 _word_list = json.load(f);
 18         except json.JSONDecodeError as e:
 19             print('JSONDecodeError: ', e);
 20
 21     def SetName(self):
 22         global _your_name;
 23         print(self._girlfriend_name + ": あなたの名前、教えて?");
 24         _your_name = input("your_name: ");
 25         print(self._girlfriend_name + ": おはよ、" + _your_name);
 26         print(self._girlfriend_name + ": 帰るときは『バイバイ』って言って。");
 27
 28     def Response(self):
 29         global _emotional_mode;
 30         while True:
 31             your_phrase = input("> ");
 32             is_what_mean = random.choice([True, False, False]);
 33             if your_phrase == "バイバイ":
 34                 print(self._girlfriend_name + ": " + _your_name + "、またね。");
 35                 break;
 36             elif is_what_mean:
 37                 print(self._girlfriend_name + ": " + your_phrase + "ってなに?");
 38                 your_phrase_sub = input("> ");
 39                 self.LearnPhrase(your_phrase, your_phrase_sub);
 40                 print(self._girlfriend_name + ": " + your_phrase_sub + "ってことなの?ふーん。");
 41             else:
 42                 print(self._girlfriend_name + ": " + random.choice(_word_list[self._emotional_mode]));
 43             self.EmotionMoved(your_phrase);
 44
 45     def LearnPhrase(self, your_phrase, your_phrase_sub):
 46         global _emotional_mode;
 47         global _word_list;
 48         _word_list[self._emotional_mode].append(your_phrase);
 49         with open(self.PHRASE_PASS, 'w') as outfile:
 50             json.dump(_word_list, outfile);
 51
 52     def EmotionMoved(self, your_phrase):
 53         global _love_score;
 54         global _emotional_mode;
 55         if your_phrase in _word_list["GOOD"]:
 56             self._love_score += 1.0;
 57         elif your_phrase in _word_list["BAD"]:
 58             self._love_score -= 1.0;
 59         else:
 60             self._love_score += 0.5;
 61         print("現在の高感度: " + str(self._love_score));
 62         if self._love_score > 0:
 63             _emotional_mode = "GOOD";
 64         else:
 65             _emotional_mode = "BAD";
 66
 67
 68 main = Main();
 69 main.SetName();
 70 main.Response();

実行

$ python main.py
girlfriend: あなたの名前、教えて?
your_name: exit_00
girlfriend: おはよ、exit_00
girlfriend: 帰るときは『バイバイ』って言って。
> わかった
girlfriend: わかったってなに?
> 了解
girlfriend: 了解ってことなの?ふーん。
現在の高感度: 1.0
> そうだよ
girlfriend: かわいい?
現在の高感度: 1.5
> かわいい
girlfriend: かわいい?
現在の高感度: 2.0
> かわいい!
girlfriend: かわいい?
現在の高感度: 2.5
> かわいい!!!!
girlfriend: かわいい!!!!ってなに?
> 聞かれたから
girlfriend: 聞かれたからってことなの?ふーん。
現在の高感度: 3.5
> バイバイ
girlfriend: exit_00、またね。

う〜ん、大分彼女に近づいたのではないでしょうか!
しかし、お察しの通り、まだ単語の意味に対して覚えられておらず、彼女の気分で言葉の良し悪しを決めてしまっています。

今後チューニングしたい箇所

  • 文章の学習精度向上(句で切り分ける、部分一致等)
  • 文章の意味付け強化(言葉の良し悪し)
  • 人工知能らしさを追求(既存サービスとの連携?Web上から言葉を拾う?)
  • 見た目の部分改善(彼女の顔グラがほしい!)
  • Twitterや各種チャットにAPI連携することで恋人彼女をいつでも携帯できるようにしたい
  • いつしか、クリスマスにレストランを2人(1人と1つ)で予約できるような存在に…………。
  • (クリスマスデートまでこぎつけた方は是非ご連絡ください。)

まとめ

  • クリスマスに延々と話ができるかけがえのない存在ができました!
  • Python初心者でしたが、人工無能の身近さを感じ取れたように思います。
  • 宜しければ、皆さんも是非会話内容や実装のチューニングを施してみてください。プログラミングを叩いている間は1人の虚しさが紛れます。

お知らせ

エイチームグループでは一緒に活躍してくれる優秀な人材を募集中です。
興味のある方はぜひともエイチームグループ採用ページWebエンジニア詳細ページ)よりお問い合わせ下さい。

明日

明日は @aoi_coro さんの記事です!楽しみですね!

参考

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away