Watsonに博多弁をしゃべらせてみた

*※この記事は、[Bluemix Advent Calendar 2016](http://qiita.com/advent-calendar/2016/bluemix)の21日目の投稿です。*

#はじめに
　2016年10月26日、[IBMとSlack社の業務提携](https://bita.jp/dml/watson_slack)が発表されました。そこで、今回はIBM Bluemixで提供されているWatson Conversation APIを使ったSlackボットの開発手順を紹介します。学習させたい対話データの量に依存しますが、実際に動くアプリケーションは1-2時間で完成します。また、ここで書いた内容はすべて無償利用枠でできるようにしておりますので、クラウドやWatsonを体感できるハンズオン教材としてもお使いいただけます。

<img width="1150" alt="スクリーンショット 2016-12-21 19.34.13.png" src="https://qiita-image-store.s3.amazonaws.com/0/63451/2d4d8812-4258-4d70-681d-2d1708a3a01d.png">

この記事で伝えたいことは以下３つです。

- IBM Bluemixを使えば誰でも簡単・高速にアプリケーションのプロトタイプが開発できる。プログラミング・スキルもそこそこ重要だが、それよりもデータの活用方法やビジネス・アイデアが重要。
- 日本語特有の難解な自然言語のゆらぎ、曖昧性、そして方言すらもWatsonは理解できる。Watson自体ももちろんすごいが、クラウド＋API経由でその機能を呼び出せる点が素晴らしい。
- PaaSを使えば、気象情報、時刻表、グルメ情報などの外部APIと簡単に連携できる。APIエコノミーにおいて企業APIの公開は大変重要。

#アーキテクチャ

<img width="883" alt="スクリーンショット 2016-12-21 20.58.56.png" src="https://qiita-image-store.s3.amazonaws.com/0/63451/eb98761f-d581-a28c-6de8-75adfde6ebca.png">

　開発するアーキテクチャの全体像を説明します。ユーザーとのインターフェースにはSlackを用います。ユーザーはスマホやPCからSlackアプリやWebブラウザを用いてSlack上に作成したslackbotと対話します。ユーザーとのインターフェース層としてslackbotを利用するためスクラッチでユーザー・インターフェースを開発する必要がありません。アプリケーション層では、ユーザーからの自然言語のテキスト・メッセージをWatson Conversation APIが受取り、適切な回答をやり取りします。このとき、「天気」、「グルメ」、「電車時刻表」に関する質問であれば、「何の質問をされているか？」をWatson Conversation API (NLC)が識別し、質問内容に応じて外部APIを呼び出して情報を取得して回答するというアプリケーションです。外部APIを用いることで対話内容に付加価値のある情報を持たせることができます。アプリケーション開発は、すべてNode-RED上で完結させることができるので、あらかじめ処理がカプセル化されたノードをGUI上でつなぐという操作だけで一連の処理を実装できます。開発からサービス提供までPaaS上で行うため開発者はインフラを気にせずにアプリケーション開発に注力することができ、クイックにサービスを提供することが可能です。

#材料
　Slackボット開発に用いたサービス・APIは以下のとおりです。プラットフォームとなるBluemixのアカウント、アプリケーション開発のためのNode-RED、自然言語での対話機能を実現するWatson Conversation API、そしてユーザー・インターフェースとなるSlackのアカウントは最低限必要です。

- 必須
- [ ] Bluemixアカウント
- [ ] Node-REDボイラー・テンプレート（Bluemixで提供）
- [ ] Watson Conversation API（Bluemixで提供）
- [ ] Slackアカウント

上記だけでもチャットボットとして充分機能させることはできますが、アプリケーションに外部APIの機能を追加したい場合は、いくつかのAPIのアカウントを準備してください。例えば、今回は以下の３つのAPIを利用しました。

- オプション
- [ ] Weather Company API
- [ ] ぐるなびAPI（オプション）
- [ ] 駅すぱあとAPI（オプション）

#作り方
　それでは、以下の手順にしたがいWatson × Slackボットを開発していきます。

```
手順1. Bluemixアカウントを取得する
手順2. Node-RED Starterボイラープレートを追加する
手順3. Node-REDにnode-red-contrib-slackerノードを追加する
手順4. Watson Conversation APIを追加する
手順5. Conversation Toolを使い対話データを学習させ、対話シナリオを構築する
手順6. Slackアカウントを作成しSlackbotを追加する
手順7. Node-REDでアプリケーションを開発する
```

**手順1. Bluemixアカウントを取得する**
最初にBluemixアカウントを取得します。以下のリンクから必要情報を入力すれば、30日間の無料トライアルアカウントを取得できます。
https://www.ibm.com/cloud-computing/jp/ja/bluemix/    
<img width="677" alt="スクリーンショット 2016-12-21 21.58.44.png" src="https://qiita-image-store.s3.amazonaws.com/0/63451/5198060c-e250-e43f-f1ab-461e9e870b86.png">

アカウントの作成方法の詳細は以下を参考にしてください。

（参考）ITPro SPECIAL 第2回 Bluemixでアプリを作ってみる
http://special.nikkeibp.co.jp/atclh/ITP/15/ibm1204/p3/index.html
（参考）IBM Bluemixフリートライアルアカウント作成手順
http://qiita.com/KenichiSekine/items/6ad49b25167b3f4cdb63
（参考）クラウドサービスIBM Bluemixを無料で使うノウハウまとめ
http://qiita.com/zuhito/items/86e7ad47d14937d3e9b6

**手順2. Node-RED Starterボイラープレートを追加する**

アプリケーションの実行環境および開発環境となるNode-RED Starterボイラープレートを追加します。Node-RED Starterボイラープレートには、アプリケーション開発を行うNode-RED、サーバー・サイドJavaScriptの実行環境であるSDK for Node.jsおよびデータベースとしてCloudant NoSQL DBが含まれています。
<img width="1053" alt="スクリーンショット 2016-12-22 0.24.40.png" src="https://qiita-image-store.s3.amazonaws.com/0/63451/1949dd8e-ac01-3c67-c423-a3dbf8942712.png">

Node-REDをはじめて使う方は以下を参考にしてみてください。

（参考）はじめてのNode-RED
https://goo.gl/BG1S6O
（参考）コードをほとんど書かずにNode-REDでWebアプリを作ろう
http://ascii.jp/elem/000/001/139/1139255/
（参考）Node-RED入門編
http://qiita.com/joohounsong/items/5b5241df84f910df6627

**手順3. Node-REDにnode-red-contrib-slackerノードを追加する**

デフォルトのNode-REDには、Slackと連携するためのノードが用意されていないため、以下のnode-red-contrib-slackerノードを追加する必要があります。

http://flows.nodered.org/node/node-red-contrib-slacker
<img width="770" alt="スクリーンショット 2016-12-22 1.20.38.png" src="https://qiita-image-store.s3.amazonaws.com/0/63451/1aa005f7-e7eb-1232-28ae-ad4c91926439.png">

具体的には、デプロイしたNode-REDサービスのコードをIBM Bluemix DevOps Servicesを使ってpackage.jsonファイルに以下の行を追加して再度デプロイします。

```package.json
"node-red-contrib-slack":"*"
```

<img width="1047" alt="スクリーンショット 2016-12-22 1.29.33.png" src="https://qiita-image-store.s3.amazonaws.com/0/63451/da288f72-99e4-d240-7e9f-8699489a8076.png">

IBM DevOps Servicesの基本的な使い方やNode-REDのパレットに新規にノードを追加する方法については以下を参考にしてください。

（参考）Bluemix アプリケーションをIBM DevOps Servicesを利用してチーム開発する
https://www.ibm.com/developerworks/jp/cloud/library/j_cl-teamdev-bluemix-app/

（参考）BluemixのNode-REDパレットにノードを追加する
http://qiita.com/KenichiSekine/items/b2877c90f59774a27827

（参考）Node-RED にオリジナルノードを追加する
http://dotnsf.blog.jp/archives/1037934526.html

**手順4. Watson Conversation APIを追加する**
次はいよいよWatson Conversation APIを追加します。カタログより選択して任意の名前をつけてデプロイします。デプロイ後は、さきほど準備したNode-REDサービスに接続してください。
<img width="1121" alt="スクリーンショット 2016-12-22 1.43.56.png" src="https://qiita-image-store.s3.amazonaws.com/0/63451/d22d4613-5d70-9431-2b24-ce01d7b5892b.png">

**手順5. Conversation Toolを使い対話データを学習させ、対話シナリオを構築する**
Watson Conversation APIのデプロイが完了したら、Launch toolをクリックし、Conversation Toolを起動します。
<img width="1079" alt="スクリーンショット 2016-12-22 1.48.55.png" src="https://qiita-image-store.s3.amazonaws.com/0/63451/39f1bae0-6a5c-a627-9392-6b9225baceb3.png">

Conversation Toolが起動しますので、新規にワークスペースを作成します。今回は、駅コンシェルジュBOTというワークスペースを作成しました。
<img width="784" alt="スクリーンショット 2016-12-22 1.51.48.png" src="https://qiita-image-store.s3.amazonaws.com/0/63451/c4b55270-d435-76a5-1a3f-120fa96a2d62.png">

右上の[View Details]をクリックし、Workspace IDをコピーします。このIDは後ほどNode-REDアプリケーションからWatson Conversation APIを呼び出す際に使用します。
<img width="546" alt="スクリーンショット 2016-12-22 1.54.46.png" src="https://qiita-image-store.s3.amazonaws.com/0/63451/96c83f09-d7e5-092b-83e3-96567113b581.png">

まずは、Intentsを作成します。
<img width="1027" alt="スクリーンショット 2016-12-22 2.00.03.png" src="https://qiita-image-store.s3.amazonaws.com/0/63451/82b0f320-3afe-c522-bb1f-2b26df59a3d2.png">

Intentsとは要するに質問の集合体のことです。ユーザーが問いかけてきそうな質問をカテゴリに分けて複数の例文を登録します。一つのカテゴリで最低5つの例文が必要です。例文数が多ければ多いほど、例文と異なる言い回しでWatsonに質問しても、学習した特徴量からWatson側で意図を理解してくれるようになります。例えば、博多弁で「何してるの？」を表す「なんしよーと？」は以下のような例文を登録しました。

<img width="875" alt="スクリーンショット 2016-12-22 2.12.21.png" src="https://qiita-image-store.s3.amazonaws.com/0/63451/c7782be2-1e58-c640-63e5-576d876b0424.png">

すると、Watsonは博多弁の異なる言い回しの問いかけに対しても、問いかけが博多弁であると識別することができるようになりました。

<img width="230" alt="スクリーンショット 2016-12-22 2.14.54.png" src="https://qiita-image-store.s3.amazonaws.com/0/63451/1a8fc6fc-5493-9347-8370-7c23c20a27eb.png">

次にEntitiesを登録します。簡単に言うと、Entitiesとは、対話における目的語 「〜を」に該当するものです。例えば、「うどんを食べたい」という「食事」というIntentsに関する問いかけがきたときに、Watsonが「うどん」というEntitiesを識別できるようにあらかじめリストを登録しておきます。例えば今回は、以下のようなIntentsを作成しました。
<img width="1008" alt="スクリーンショット 2016-12-22 2.33.16.png" src="https://qiita-image-store.s3.amazonaws.com/0/63451/aa921d84-6d9c-6488-8b23-b7f2cb51f972.png">

最後に、Dialogです。各ノードはcondition（条件）とresponse（対応）で構成されます。ユーザーからの入力がノードで指定した条件に合わせて対応するif-thenのような機能を使って会話を組み立てて行きます。
<img width="1000" alt="スクリーンショット 2016-12-22 2.44.24.png" src="https://qiita-image-store.s3.amazonaws.com/0/63451/6de5cdde-1790-5b13-5bea-be13f238a01f.png">

Conversationツールの詳細については以下を参考にしてください。

（参考）BluemixのWatson Conversation(beta)を触ってみた
http://qiita.com/ishida330/items/f2bb85788815e183e29b
（参考）Watson Conversation 日本語環境を試してみる
https://www.change-makers.jp/technology/11268
（参考）チャットボットを簡単に作れる！Watson Conversationの色々なTips
http://qiita.com/ishida330/items/ae7277598cd3e08fc3a2

**手順6. Slackアカウントを作成しSlackbotを追加する**

Slackのアカウントを発行し、Custom Integrations (https://<Slackチーム名>.slack.com/apps/manage/custom-integrations)より、Slack Botを追加します。APIキーが発行されますのでコピーしておきます。

<img width="978" alt="スクリーンショット 2016-12-22 2.53.08.png" src="https://qiita-image-store.s3.amazonaws.com/0/63451/1d742681-6232-9c02-91a0-5a0871426c62.png">

Slack botの作成手順は以下を参考にしてください。

（参考）会話エンジンにWatson Conversationを使ったSlack botを作ってみた
http://qiita.com/tsota/items/497513585f069386626f

**手順7. Node-REDでアプリケーションを開発する**

前の手順で追加したSlackを利用するためのNodeである[node-red-contrib-slacker](http://flows.nodered.org/node/node-red-contrib-slacker)を使って、アプリケーションを開発します。Slack経由で入力されたユーザーからの自然言語のテキスト・メッセージをWatson Conversation APIが受取り、Dialogで定義した対話シナリオに基づき適切な回答をやり取りします。対話の中に「天気」、「グルメ」、「電車時刻表」に関するIntents（質問）が含まれていれば、Watson Conversation API (NLC)が識別し、質問内容に応じて外部APIを呼び出して必要な情報を取得して回答するというアプリケーションです。外部APIとして、今回は、Bluemixで提供されるWeather Company API、ぐるなびAPI、駅すぱあとAPIを追加しています。

<img width="1273" alt="スクリーンショット 2016-12-21 19.51.24.png" src="https://qiita-image-store.s3.amazonaws.com/0/63451/556caa2f-6452-502d-7b2e-443860a3f725.png">

Node-REDからの外部API連携方法については以下を参考にしてください。

（参考）Watson Conversationを使って天気予報をするSlack botを作ってみた
http://qiita.com/tsota/items/560d1b6f9c6a27aec412
（参考）ぐるなびWebサービス for Developers
http://api.gnavi.co.jp/api/
（参考）駅すぱあとWebサービス
http://docs.ekispert.com/

#まとめ
　今回は、Bluemixで提供されるWatson Conversation APIを使って、Slackボットを開発してみました。Bluemixと各種APIにより簡単に「コグニティブな」アプリケーションのプロトタイプが開発できますのでぜひみなさんもお試しください。