WEBサービス開発グループの堀です。
前回のYocto Projectの投稿の続きで応用編を書く予定だったのですが、作例が締め切りに間に合わなかったため、今回は古典的な手法のchatbotエンジン「chatterbot」をご紹介したいと思います。(ごめんなさい)
chatterbotとは?
2006年以降、深層学習の進歩によって第3次人工知能ブームと呼ばれるほどに盛り上がりを見せているAI関係ですが、何かと似た画像を探す画像認識のようなシステムの裏方で処理を担うようなものだけでなく、人と対話する機械/プログラム(いわゆるchatbot)といった私達が一般的に思い描く人工知能に近いものがサービスとして提供されるようになってきました。(残念ながら?SFの世界で描かれるようなものにはまだ及びませんが…)
chatbot自体は以前から存在しますが、機械学習用ハードウェアの進歩も加わって以前のものよりもずっと自然な受け答えが可能になってきているものの、そういったハードウェアはまだまだ高価ですし、気軽に使えるというものでもありません。
ただ、現在の非力なハードウェアも半世紀前と比べれば十分高速ですし、処理に時間のかかる古典的な手法でも実用的な時間で動作させることが可能な時代になりましたので、用途に合わせて古典的な手法を使うのもよいのではないでしょうか?
と、前置きが長くなりましたが、今回紹介するchatterbotは簡易的な対話chatbotを作ることができるPythonライブラリで、文章の判定にロシアの学者ウラジーミル・レーベンシュタインが1965年に考案した「レーベンシュタイン距離」を使用しています。予め用意した問いと答えのリストから、ユーザーからの問いに近いものを探して答えを返すといったchatbot(所謂エキスパートシステムあるいは人工無能)を簡単に作ることができます。
レーベンシュタイン距離とは
wikipediaにレーベンシュタイン距離の説明がありますのでそちらをご覧ください。と、丸投げするのも何ですので、「こんばんわ」が「こんにちわ」とどのくらい似ているか判定する場合で考えてみます。「こんばんわ」から文字を1文字ずつ交換して「こんにちわ」にするには何回必要でしょうか?同じなのは「こ」「ん」「わ」ですので2回交換すれば同じになります。このようなときレーベンシュタイン距離は2であると表します。
こんばんわ → こん「に」んわ → こん「に」「ち」わ
つまり、1文字ずつ交換して回数が少ないものほど似ているという風に考えられますので、問いと答えのリストから似ている問い(距離が近いもの)を選び出して、答えとして返せば会話風になるわけです。
仕組みはとても単純なのですが、比較する文章が多く、長くなるほど計算量が多くなってしまうというデメリットがあります。一方で英語、中国語、日本語など言語に関係なく同じロジックで計算可能であるといったメリットもあります。
インストール
普通にpipでインストールして終わりですが、python3前提になっていますので、うっかりpython2環境に入れないように注意が必要です。
1 |
$ pip3 install chatterbot |
コーパスの準備
問いと答えのリストをyaml形式で作成します。日本語はないのですが、こちらに英語やロシア語など複数言語のサンプルが用意されていますので、ひとまずはサンプルで動作確認をするのがよいと思います。以下は英語の挨拶用コーパスのサンプルですが、問いと答えを羅列する単純な書式になっています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
categories: - greetings conversations: - - Hello - Hi - - Hi - Hello - - Greetings! - Hello - - Hello - Greetings! - - Hi, How is it going? - Good - - Hi, How is it going? - Fine - - Hi, How is it going? - Okay - - Hi, How is it going? - Great |
対話してみる
対話のプログラムは数行で記述できます。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
from chatterbot import ChatBot chatbot = ChatBot( "crappybot", trainer='chatterbot.trainers.ChatterBotCorpusTrainer', storage_adapter="chatterbot.storage.JsonFileStorageAdapter", ) # トレーニング用のコーパスを指定 chatbot.train("chatterbot.corpus.english.greetings") # 問いかけ response = chatbot.get_response("Hi") print(response) |
問いかけをする前に先ほどのコーパスをトレーニング用データとして指定してtrain()を行う必要があります。train()の後、get_response()で問いかけの文字を与えることでレーベンシュタイン距離で一番近いものを返却してくれます。
上の例では「Hi」という文字列を問いとして渡していますので、とコーパス内の問いから距離が近い(まったく同じ)「Hi」に紐づいた「Hello」という答えを返します。
1 2 |
$ chatterbot.py Hello |
トレーニングデータはstorage_adapterパラメータで格納先(方法)を指定することができ、ファイル出力のほかにmongodbのようなdbへの格納も可能になっています。ユーザーとの対話をトレーニングデータとしても保存できますので、対話を繰り返すことでコーパスの強化が可能です。が、おかしな受け答えも格納してしまいますので、よくニュースになっているようなことになる恐れがあります。
【参考】中国AI「お喋りロボット」の反乱――ネットユーザーが勝つのか?
なお、距離が同じときはランダムに選ばれるような仕組みになっていたりしますので、同じ質問で複数の問いをコーパスに書いても問題はなく、同じ質問で異なる回答が返すといった使い方もできます。
また、セッション機能も用意されていて連続した対話を実装することも可能です。
最後に
とくに捻りもない簡単な紹介になってしまいましたが、手軽に試せるchatbot(dialog)エンジンchatterbotの紹介でした。精度はamazonやIBM、Microsoftなどが提供している今時のエンジンに比べるべくもありませんが、ネットワークに繋げられない貧弱なマイコンボードに載せて簡易なロボットを作ったりなど、用途によっては十分使えるのではないかと思います。コーパスを作るのがちょっと大変ですが、何かのお役に立てば幸いです。