読者です 読者をやめる 読者になる 読者になる

LINE BOT: pixivコミックをおすすめしてくれる司書チャットボットを試作しました

ピクシブ株式会社 Advent Calendar 2016 4日目です。16卒エンジニアの yasu がお送りします。好きな言語はLISPです*1

先日、Google Apps ScriptとLINE Messaging APIを利用して、会話BOTを開発した記事を公開しました

今回はLINE上で動くコミック司書ボットを試作しました。チャット上で、インタラクティブにやりとりするために、LINE Messaging APIのテンプレート機能を使っています。また、ユーザの発言解析にMicrosoft Cognitive Service LUISを使っています。

f:id:tamanobi:20161202173324j:plain

pixivコミックのおすすめを教えてくれる司書を作りました

弊社には、pixivコミックというコミック総合サイトがあります。pixivコミックで読める作品の数は約2300件(2016/12/02現在)にも及びます。

大量のコミックの中から、お気に入りの作品を見つけるのはなかなか骨が折れます。私のために、おすすめコミックを紹介してくれる司書がいたらどんなに良いことでしょう。そのような司書を夢見てチャットボットを試作しました。ユーザの発言に応じて、pixivコミックに載っているコミックを紹介してくれるチャットボットです。残念なことに試作品なので、外部公開はしていません。

f:id:tamanobi:20161202171113p:plain

チャットボットがコミックをおすすめしてくれる様子

作成したチャットボットはユーザの発言を解析して、作品をおすすめしてくれます。司書に話しかけるように、「怖い話が読みたい」と言ってみます。ボットが「こんなのはどう?」といって怖い話を推薦してくれました。表示されたカードから、作品ページへ直接移動できるためスムーズにコミックを読むことができます。

なぜチャットボットを作るのか? チャットボットを作る動きが盛ん

今年は、チャットボットに関わる発表やハッカソンが非常に多かった年です。例えば、Microsoft Bot Frameworkや、LINE Messaging APIhachidoirなどがリリースされました。ボットと会話をしたいという夢をもつ僕には最高の年です。

私たちがコミュニケーションを取るときには、基本的に自然言語を使います。いままでコンピュータに何か作業をさせる場合には、用意されたプログラミング言語を使う必要がありました。一方チャットボットでは、限られた範囲ではありますが自然言語による会話を通じて、コンピュータに作業を依頼することができます。

限られた範囲でも、チャットを用いてさまざまな操作(例:自然言語で検索)ができるとすれば、利用するユーザを引き込める可能性があります。たとえば、ウェブサイトのどこにボタンがあるのかわからないとか、使い方がわからないユーザがいるでしょう。

具体的には、「◯◯さんのアポ、何時から何時までとっておいて!」とか、今日の人気コミック、何かなー?と、チャットボットに話しかけることで、ボットがその裏の煩雑な作業をやってくれることが期待できます。

世界的にも徐々に関心を集めつつあるチャットボット

チャットボットは、まだまだ人気とは言えませんが、去年から少しずつ関心を集めているようです。以下のグラフは、Google Trendsで、チャットボットとボットフレームワークについて調べてみた結果です。つい先月、MicrosoftがAzure Bot Servicesを発表したことから、チャットボットのプレゼンスはもっと高くなるでしょう。

チャットボットは、誰でも使える新しいインタフェースか

日常的に行っている会話を介して、コンピュータにさまざまなことを依頼できるボットは、お問い合わせのシステムとして活躍が見込まれています。日本の銀行でもチャットボットが導入されているようです。

まだまだ音声応対をすべてボットで行うという施策は浸透していないようですが、テキストベースでの応対を行ったり、音声応対は人間のオペレーターにまかせて、リアルタイム会話分析で、オペレーターを支援する情報を画面に表示したりする運用が行われています。

今回試作したチャットボットでは、ユーザとボットが直接会話を行います。あくまでもボットの応対になるため、誰でも違和感なく使えるものではありませんが、スマートフォンを持っていて、LINEでテキストを送信できる人には使えるシステムです。

チャットボット試作で困ったこと:自然言語を解析するならLUISを使おう

チャットボットは、日常的に使う言葉で利用できることがメリットなのですが、チャットボットを作る側としては悩みの種になります。自然言語の構造は単純ではないため、正規表現や形態素解析だけでは意図を把握するのに限界があります。

そんなときは、Microsoft Cognitive Services*2の一つであるLUIS: Language Understanding Intelligent Serviceを使うと便利です。LUISというのは、自然言語を解析して意図の種類を示すタグにディスパッチしてくれるツールです。たとえば「天気を教えて!」や「天候はどうだろう?」という自然言語をgetWeatherというタグにマップできます。自分で正例を覚え込ませたり、誤判定を修正したりすることがウェブ上でできるため、気軽に試せます。

今回作ったチャットボットでは、「ランキング見せてください」や「○○っていう漫画ありませんか?」という言葉がそれぞれ意図を表すタグにマップされます。

LUISでは、GETパラメタにユーザの入力に載せてHTTPリクエストするとJSONで該当するタグの尤度を返します。非常にシンプルなAPIなので、cURLやブラウザから簡単にデバッグできて便利でした。

このLUISを用いることで、自然言語を意図に変換することができます。ちなみに、LUISの利用には無料枠が用意されているので、試しに使ってみる程度であれば料金を請求されません。利用される方は、Cognitive Servicesの料金を必ず参照し、ご自身の責任で利用してください。

LUISの試し方は、Microsoft Bot Frameworkと簡単連携! LUISで自分だけのAIを作ってみた - BITA デジマラボLUIS (Language Understanding Intelligent Service) 日本語対応 ~ 解析エンジン作成&利用方法 – 青い空の向こうへ にわかりやすくまとまっているので、参照してみてください。

チャットボットのプラットフォーム:LINE Messaging APIを使う

チャットボットを動かすには、当然プラットフォームが必要です。今回はカルーセルが使えるLINEを使いました。LINEは通常上から下へテキストがレイアウトされますが、カルーセルを使うと横に展開されます。いくつかある候補の中からユーザに選んでもらうときに一覧性が高く、有用です。

LINE Messaging API

LINE Messaging APIは、カルーセルを始めとするテンプレートが充実しています。確認ボタンや画像付きカードなどは表現力が高く使いやすいです。詳細な説明は公式ドキュメントに譲ります。

個人的には、普段LINEを友人同士で使っているときには見られないカルーセルがとてもお気に入りです。

pixivコミックおすすめチャットボットの機能

LINE Messaging APIとMicrosoft Cognitive Services LUISを使って作られたチャットボットは以下の機能があります。最後にデモ動画を紹介します。

  • コミック検索
  • 注目漫画
  • ランキング
  • 作品の詳細情報取得

司書チャットボットで、コミックを探すデモンストレーション

まとめ

本記事では、LINEをプラットフォームとして、LUISという自然言語解析APIを使って、pixivコミックの作品を勧めてくれるチャットボットを作った話を紹介しました。インタフェースとしてのチャットボットは利用に特別な操作が必要ないため、幅広く人々にリーチできる可能性を秘めていると思っています。

LINE Messaging APIや、Microsoft Cognitive Servicesに興味が湧いた人は下の公式ドキュメントを参照してみてください。

参考資料

引き続きAdvent Calendarお楽しみください!

明日のピクシブ株式会社 Advent Calendar 2016の担当者は、私と同じ16卒エンジニアのkpです。お楽しみに!

*1:shibuya.lispが終わってしまうと聞いて残念な思いでいっぱいです

*2:Microsoftの提供する Cognitive Servicesは、「人工知能アルゴリズムのコレクション」と紹介されている

Firebase Cloud Messaging (FCM) を利用してお手軽に通知を送る

ピクシブ株式会社 Advent Calendar の@3日目です。今日はスマホアプリエンジニアの chocomelon がお送りします。

最近、弊社のプロジェクトではネイティブアプリのプッシュ通知に Firebase を使っています。導入方法は色々な方々が紹介しているので今さら感はありますが、弊社ではこんな感じで使っていますという事例を絡めて紹介できればと思います。

記事の内容的には Firebase で送るプッシュ通知の概要は知っていて、これから導入を検討している方や、Firebase を使ったプッシュ通知が実際どんな形で使われているか興味がある方にオススメです。

Firebase Notification と Firebase Cloud Messaging

Firebase で送る通知は、Firebase Notification を使ってGUIから送る方法と Firebase Cloud Messaging (以下FCM) を使って送る2つの方法があります。弊社では FCM を使って通知を送っています。

Firebase Notifiation は送る内容、ターゲット、タイミング等を Notifications Console GUI からの操作でき、お手軽に通知を送ることができます。

画像:Notifications Console GUI f:id:chocomelonchan:20161201104525p:plain

ただ Firebase Notification はAPIは存在せず、定期実行をしたい場合などに不便です。現状API経由で通知したい場合は、FCM しかないので FCM を使っています。

FCM には Notification Message と Data Message があります。Notification Message の場合、Android は端末がバッググラウンドの状態にある時に処理のハンドリングができず、正確な通知の開封率が計測できなかったため Data Message を使用しています。詳しくは Firebase のドキュメントを参照してください。

特定のトピックを購読しているユーザーに対して通知を送る

pixiv アプリでは、新規ユーザー向けにどの通知が刺さるかちょこちょこABテストしています。そのうちのひとつに pixiv のイラストデイリーランキングが更新されたタイミングで通知を送っているので例として紹介します。

サーバ側の処理

サーバ側ではランキングが更新されたタイミングで FCM に以下のデータを投げつけてアプリに通知を送っています。通知を受信したアプリは"data"内の値にもとづいて通知を生成します。

data.json

{
    "to": "/topics/illust_daily_ranking",
    "data": {
        "title": "pixiv",
        "body": "ランキング更新!トレンド作品をチェック!",
        "target_url": "pixiv://ranking/illusts"
    },
    "content_available": true
}

content_availableに関しては、iOS のために設定しています。content_availableは APNs でいう content-available に相当しています。iOSアプリでは、この値が true の場合、アプリがバックグラウンドにいたり、終了した状態でも通知を受け取ることができます。Android では、デフォルトでアプリがバッググラウンドの状態でも通知が届きます。

実際の送信処理は以下のようになります。さきほどの json を FCM に投げます。

curl -H "Authorization: key=XXXXXAPIKEYXXXXX" -H "Content-Type: application/json" -d @data.json https://fcm.googleapis.com/fcm/send

アプリ側の処理 (Androidの場合)

アプリ側ではトピックを購読する処理と受信したときの処理を書きます。以下はAndroidの例です。長くなるので細かい設定の話は省きます。詳しくは Firebase のドキュメントを参照ください。

トピックの購読処理

FirebaseMessaging.getInstance().subscribeToTopic("illust_daily_ranking");

受信時の処理。

@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
    Map<String, String> data = remoteMessage.getData();
    RemoteMessage.Notification notification = remoteMessage.getNotification();
    String title = data.get("title");
    String body = data.get("body");
    String targetUrl = data.get("target_url");
    // 略... NotificationManagerを使って通知をnotifyしたりする。
}

jsonで渡したデータはRemoteMessageのgetData()でKey-ValueのペアでMapされた形で取得できます。 取得したタイトルやメッセージbodyのデータ使って、NotificationManager経由で通知を送ります。

ユーザー個別に通知を送る

pixiv のアプリで新規ユーザー向け通知の最適化のために、ユーザーがしたアクション(ブックマークやフォロー)をもとにオススメ作品を送るという通知を試験的にしています。

これを実現するために、新規ユーザー個別の通知にユーザー毎に一意になるようなトピックを使っています。トピックの生成がおそらく上限が設定されていないので、トピックで購読させた方がトークン管理やユーザーが別の端末を使っている場合も特に気にしなくて良いです。

トピックが被って別のユーザーの通知がきてしまわないようにサーバ側で生成したトピックを受け取って購読しています。

サーバ側の処理

  • 準備
    • ユーザー毎に一意のトピックを返すAPI
  • 通知処理
    • 通知対象のユーザーをデータベースから抽出
    • 抽出したユーザーからオススメを生成
    • FCM 経由でアプリに通知

アプリ側の処理

  • サーバ側のAPIからトピックをもらい購読

まとめ

通知をお手軽に試すのに Firebase Notification は非常に良いかなと思います。ただ少しカスタマイズしたい場合などは FCM を使うと良いかと思います。ぜひみなさんも試してみてください!