株式会社wevnalでCTOを務めている木曽です。近年、チャット利用者の入力した文章や音声からその内容を汲み取って適切な応答を返す仕組み、このようなものがWebサービスとして昨今いくつも立ち上がっています。

今回は、ここ数年の技術系トピックとしてNo.1と言っていい「AI」や「Chatbot」について、ユーザーの皆さんにもプログラミングなしでその片鱗に触れていただけるような内容をお届けしていきます。

特に、その中でもFacebook系のサービス「wit.ai」を実際に使う手順をご紹介しながら、日本語の自然言語処理について触れていただきたいと考えています。
 

Wit.aiならブラウザ上で自然言語学習やChatbotの構築が可能

Wit.aiとは、Chatbot、モバイルアプリ、音声デバイスなどと連携した"自然言語処理を支援する無償のサービス"です。

Wit.aiは2013年に創業したのち、2015年にFacebookに買収され、Facebook傘下のボットエンジンとなりました。類似のサービスとしてはGoogle傘下のapi.ai、MicrosoftのLUISなどがあり、活況を呈しています。

Wit.aiは現在50言語をサポートしていますが、日本語を含む39言語についてはまだβ版の状態です。日本語が、英語を始めとする欧米言語と大きく異なる点の1つに「単語がスペースで区切られていないこと」があります。このため、Wit.aiでの日本語の扱いには正直苦戦するところがあるのですが、「わかち書き」という手法を組み合わせることで、日本語の自然言語認識を構築することができます。
  

Wit.aiの利用手順(アカウント作成)

Wit.aiを利用するにあたり、まずアカウントを作成する必要があります。

GitHub、またはFacebookのアカウントでログインすることが可能です。ここでは、FacebookアカウントでログインしてWit.aiアカウントを作成してみます。

wev_101.png

  1. [Log in with Facebook] を押します。

wev_102.png
2. Facebookログインダイアログが出ますので、Facebookのアカウント情報でログインします。

wev_103.png
3. 追加情報として、WIt.ai上でのユーザー名、メールアドレス、利用目的を聞かれますので入力します。利用目的が特に審査されることはないので適当な記載で大丈夫です。

ここまで進むと、早速、MyFirstAppというアプリの作成画面に移ります。ここで自然言語認識を利用した会話モデルを作成していくことができます。
  

【実践】航空券予約を理解させてみよう

続いては、「XからYへの航空券を予約したい」という発言から、航空券予約を行うChatbotを作成すると仮定して、Wit.aiの自然言語処理を使ってみます。
  

インテントとエンティティ

まずは、会話モデルを作成していきます。その際、Wit.aiで会話モデルを作るにあたって2つの定義、「インテント(intent)」と「エンティティ(entity)」を理解しておきましょう。

インテントとは

インテントとは「意図」の意味です。ユーザーの発言の内容から、ユーザーが何を問いかけているのか、その意図を分類する概念です。例えば、「東京の明日の天気は?」といった発言から、ユーザーは「天気を尋ねている」とユーザーの意図を分類・認識する仕組みです。この認識により初めて「天気を応答する」処理を開始することができます。

エンティティとは

エンティティとは、発言の中に含まれる「(インテントにとって)意味を持つ単語」の意味です。エンティティは、日時や場所、依頼や質問の対象となるモノなどを分離、認識する概念です。例えば、前述の「東京の明日の天気は?」といった発言からは、具体的にどのような天気を知りたいのかを認識する必要があります。ここでは「東京」「明日」という言葉が、天気を答えるにあたって意味を持つ単語であり、すなわちエンティティである、ということができます。

●自然言語の認識を行うにあたりwit.aiでは

1. 発言の内容からインテントを推定し、そのインテントに対応する処理を決定する。
2. また、発言の内容からエンティティを推定し、処理のパラメータ(日時、場所といった具体的な要求)を処理に渡して実行する。

自然言語の認識を行うにあたって、wit.aiは上記のような動作を行います。これにより、自然言語による発言から実際の処理への結び付けを行っているのです。そして、このインテントの推定やエンティティの推定の部分に人工知能が用いられています。
  

日本語を学習させる

●App新規作成
では、Wit.ai上に実際にプロジェクトを作成して、日本語を学習させてみましょう。

wev_001.png
Wit.aiではプロジェクトを「App」と呼んでいます。Wit.aiにログイン後、上図のように右上の「+(New App)」を押して新規App作成へ進みます。

wev_002.png
すると、こちらの画面となるので、「App Name」にプロジェクトの名前を入力します。必要であれば「App Description」にプロジェクトの説明文も記載します。
その後「Language」を「Japanese」を選択し、「Open/Private」はプロジェクトを公開するか、自分や限られたメンバーだけで利用するかの設定です。

wev_003.png
ここでは「Private」にしておきます。最後に「+Create App」を押して新規作成は終了となり、下記画面になります。

wev_004.png
  

●学習の開始
では、さっそく文章の学習を開始しましょう。Appを作成しただけでは、まだ何も知らない赤ん坊の状態です。これからいくつかの文章とインテント、エンティティを教えていきます。

ここでは以下のような学習文を用意しました。

明日羽田からハノイに行きたいです
明日成田からルクセンブルクに行こうと思います
7/22に成田からロンドンに行きたい
福岡から羽田に来週月曜日に行きたい
月曜日の成田発ドバイ行きのチケットはありますか?
再来週関空からフランクフルトへ行きたい

いずれも「航空券の予約(空き状況の確認)」を意図として、想定した学習文です。
この場合、インテントは「航空券の予約」で、エンティティに相当するのは「明日」「ルクセンブルク」「福岡」「パリ」など日付や場所を表す単語になります。

wev_005a.png

まず「Test how your app understands a sentence」の下の入力欄に「明日羽田からハノイに行きたいです」と入力します。その下に「+ Add a new entity」というリンクがありますが、これを使って、エンティティを教えていきます。

wev_005b.png
入力した文の「明日」の部分をマウスで選択します。すると、その下が「+ Create an entity for "明日"」に変化します。

wev_005c.png
そこにマウスカーソルを合わせて「date」と記載します。

wev_005d.png
この作業は「"明日"という単語は"date"という名のエンティティとして学習してください」という指示になります。
※「date」と入力する際に、いくつか推薦候補が表示されますがここではいったん無視してください

wev_005f.png
続いて、「羽田」をエンティティとして登録します。入力文の「羽田」の部分をマウスで選択します。「+ Create an entity for "羽田"」となったところで、「from_location」と新しいエンティティ名を入力します。これは、「この『羽田』という語は『from _location』すなわち出発地という意味のエンティティですよ」と教えるわけです。なお、エンティティ名(ここではfrom _location)は、任意に決めることができます。

wev_005g.png
同様に「ハノイ」を「to_location」という到着地という意味のエンティティとして登録します。

wev_005h.png
「行きたい」を選択し、「+ Create an entity for "行きたい"」の中から、「intent」を選択します。これにより文に対するインテントを認識させ、最後に「Validate」ボタンを押して、この学習を登録します。

wev_005j.png
これで、「明日」「羽田」「ハノイ」というエンティティ、「行きたい」というインテントが学習されました。
  

分かち書きについて

さて、ここまで"インテント"と"エンティティ"という概念を用いた学習を見てきました。

しかし、実はWit.aiにおいてこの作業を続けても、残念ながら良い学習はしません。「羽田」「福岡」のような登録したインテント単語は理解するようになりますが、未知の地名などは理解できず、我々が期待する「学習」という領域に達しません。

これがどういうことかについてご説明します。
Wit.aiは自然言語処理の学習手法の1つですが、単語間の近接度合いや頻出度合いを数値化し、それを元に過去の学習結果に「似ている」答えを導き出しています。ところが、ここで日本語を扱う場合に問題が発生します。日本語ではスペース(空白)によって単語が区切られてないため、ただの文章を与えただけではコンピュータが単語の区切りを理解できず、この単語間の近接度合いや頻出度合いをうまく処理できないのです。

このような問題に対処するために、日本語の自然言語処理の分野では、文章を単語(品詞)で区切る「分かち書き」という手法がよく用いられます。その元となるのが「形態素解析」という、文章を品詞で分解する技術です。

形態素解析を行う代表的なライブラリに「mecab」などがあります。
例えば「明日羽田からハノイに行きたいです」という文章を「明日 羽田 から ハノイ に 行き たい です」といった具合に、辞書を用いて単語をスペース区切りにして分解したテキストに変換します。mecabを利用するにはプログラミングの知識が必要となるためここでは割愛しますが、この分かち書きをした文章を用いてWit.aiに学習させていきます。
  

分かち書きテキストによる学習

先ほど学習用の文章を用意しましたが、以下のように分かち書きをした形にしてみます。

明日 羽田 から ハノイ に 行き たい です
明日 成田 から ルクセンブルク に 行こ う と 思い ます
7/22 に 成田からロンドン に 行き たい
福岡 から 羽田に来週 月曜日 に 行き たい
月曜日 の 成田 発 ドバイ 行き の チケット は あり ます か?
再来週 関空 から フランクフルト へ 行き たい

wev_006.png
このように分かち書きした文章を使ってWit.aiにインテントを学習させていきます。
  

●学習結果の確認
ここまでWit.aiに入力をしたところで、次の文章を入力してみましょう。

明後日 福岡 から バンコク へ 行き たい です

wev_009.png
すると、Wit.aiは自動的にエンティティを見付け出し、上図のようにエンティティが区別されます。「福岡」を「from location」、バンコクを「to location」と正しく認識しています。

ちなみに、これは単に「XからYへ」という語順に従っているだけなのでしょうか。

続いては、このような"行き先"と"出発地"の語順を入れ替えた文章を入れてみましょう。

8/30 に パリ へ 大阪国際空港 から 行き たい です

wev_010.png
結果的に、"行き先"と"出発地"の語順を入れ替えても、正しく「パリ」を「to_location」、「大阪国際空港」を「from_location」と認識しています。また、「大阪国際空港」はこれまでエンティティとして登録していない単語です。単なる登録済みのキーワード検索ではなく、文脈から「大阪国際空港」を「from_location」だと認識していることがわかります。

このように複数の文章を用いてエンティティを教えていくと、登録したキーワードだけではなく、文脈からも学習によってエンティティを分類することが可能となります。
  

●応答文の作成とテスト
最後に、これまで学習した結果をもとに簡単な会話を作成してみましょう。

wev_202.png

Wit.aiの「Stories」という機能を使います。
メインメニューの右から3つ目にある「Stories」をクリックすると上図のような画面になります。左にある「+ Create a story」を押すと上の画面となり、New Story内の入力欄(User say……)に下記のように入力します。

wev_203.png

明日 羽田 から ハノイ に 行き たい です

エンティティが自動的に認識されているのがわかります。

次にこれに対するボットの応答文を作成します。画面下の「Bot sends」を押し、The bot says……の欄に次のように入力してみましょう。

{date}、{from_location}発{to_location}着の便ですね?

wev_204.png

{}で囲まれた文字はエンティティの名前です。これにより人間の入力した文章から学習によって取り出したエンティティを用いたボットの応答文が作成でき、上部にある「Save Story」を押してこの会話を保存します。

では、この会話をチャット形式でテストしてみましょう。

wev_204.png

右下にある「Press ~ to chat with your bot」を押すと、チャット画面が表示されます。

wev_206.png

「再来週 名古屋 から プーケット へ の チケット は あり ます か ?」

「再来週、名古屋発プーケット着の便ですね?」

上記のように応答がされましたでしょうか。
  
The bot saysに入力した応答文で正しく返ってきました。「名古屋」も「プーケット」も学習では用いていないボットにとっては未知の単語ですが、出発地と到着地であることが正しく認識されたようです。
  

運用例

ここまでWit.aiにおける自然言語認識の例をご覧いただきました。

すでに、皆さんもお気付きかと思いますが、このWit.aiだけでは私たちの知っている「チャット」での話はできません。

以下のような既存のメッセンジャープラットフォームに用意されているAPI(Applicatino Programing Interface)を使って、プログラミングすることでFacebookメッセンジャーやLINEメッセンジャーと接続して利用することができます。

各種メッセンジャーアプリとの接続

●Facebookメッセンジャーとの連携
Wit.aiで構築したインテントやエンティティの認識処理、またStoriesで登録したボットの応答などを、Facebookメッセンジャーからやりとりすることができます。Facebookメッセンジャーとのつなぎこみについては、プログラミングが必要となりますので以下に公開情報を掲載して割愛したいと思います。

参考:
https://developers.facebook.com/docs/messenger-platform
  
●LINEとの連携
LINE@の機能の1つに、Messenger APIというものがあります。ユーザーが開設したLINE@アカウントにChatbot機能を持たせるAPIです。プログラミングが必要となりますが、LINE@のチャットで話しかけられた内容をWit.aiへ渡して適切な応答文を返す、といった連携が可能となります。

参考:
https://business.line.me/ja/services/bot
  

予約発券システムとの接続

実際に予約システムとして完成させるためには、空席確認や発券処理を行うシステムとの結合が必要となります。

これまで、ユーザーの発言からWit.aiを用いてエンティティという形で発着地を特定するところまでみてきました。実現に向けて、特定した地名から想定される空港名まで特定したり、「明日」などといった表現から年月日を特定するなどの後処理も必要でしょう。さらに細かくは、「人数」、「往復か片道か」という情報もユーザーから得なければ空席確認ができません。また、ユーザーがわざわざ分かち書きの文を入力はしてはくれませんから、前述のmecabのような形態素解析ライブラリを用いて自動的に分かち書きの形にする前処理も必要となります。

このような様々な基礎技術と学習処理を組み合わせて初めて、人間が発した言葉からその目的に応じた処理を行うボットが完成するのです。
  

まとめ

Wit.aiという自然言語処理サービスを用いて、ユーザーの発言した日本語文からその意図や必要な単語を取り出す処理をみてきました。学習に用意した文章は10を下回る数でしたが、航空券予約に必要な発着地の希望を正しく取り出せることが確認できました。

このように学習を用いた自然言語処理は身近なものになってきました。Chatbotによるヘルプデスクなど企業での利用も進んできています。また、これらの技術を高度に応用したApple HomePod、Amazon Echo、Google Homeといった製品も出荷され家庭内での利用も始まりました。

今後、ヒューマンマシンインタフェースの1つとしてしっかりと定着してきそうな技術といえそうです。