DialogflowとGoogleのAIを組み合わせた『見る』チャットボット開発

  • このエントリーをはてなブックマークに追加

前回はDialogFlowとCloud Functionsでボードゲームの質問に答えてくれる単純なチャットボットを開発しました。
今回はそのチャットボットを改良してチャットボットに『見る』という事を覚えさせてみたいと思います。具体的にはボードゲームの画像を見せてあげるとそのボードゲームの名前を答えてくれるというチャットボットを開発してみたいと思います。

GoogleのAIであるCloud Machine Learning APIの紹介

機械学習のモデルとしてGoogleが事前に学習済みのモデルを公開しています。
その学習済みモデルをAPIとして以下の5つがサービスとして使用出来る物となっています。

  • Video Intelligence API
    • 動画を解析してくれるAPIです。動画内でシーンが変更された時間や動画内で出現した物に対してラベル付けを行い、どの時間帯で出現したかなどを解析してくれるサービスです。
  • Vision API
    • 画像を解析してくれるAPIです。画像内に移っている物にラベルを付けてくれたり、画像内の文字を認識してくれたり、人の画像だったら感情や何をしているかまで解析してくるサービスです。
  • Speech API
    • 音声を解析してくれるAPIです。発した言葉を文字起こししてくれるサービスです。リアルタイムで変換してくれたり、発言された言葉にタイムスタンプを付けて、どの時点での言葉なのかを解析してくれます。
  • Natural Language API
    • 言語解析APIです。文章から構文解析や場所、人、商品などの特定とラベル付け、その文章の全体的な感情を読み取る事が可能です。
  • Translation API
    • 機械翻訳APIです。英語から日本語への翻訳はもちろんさまざまな言語から言語への翻訳をしてくれるサービスです。100言語以上をサポートしており、入力された言語を特定する事も可能です。

今回は『見る』機能を付与したいので、VisionAPIを使用します。
作成するチャットボットの会話の流れとしては以下になります。

  1. インテントのboardgame_question_imageに入る質問をする
  2. 画像URLの入力を促す聞き返しの回答をする
  3. 画像URLを入力して質問してもらう
  4. 入力された画像URLを使用してVision APIを使用する
  5. 解析した結果から画像がなんの画像だったかを回答する

ではチャットボットを開発していきましょう。

DialogFlowでのインテントの作成

エージェントの作成方法や、インテントの作成方法の説明は今回は割愛させていただきます。詳しく知りたい方は前回の記事をご覧ください。
今回は以下の様なインテントを作成します。
・インテント名
boardgame_question_image

・Usersays
なんてボードゲーム?
このボードゲーム分かる?
このボードゲームは何ですか?

・Action
REQUIRED:ON
PARAMETER NAME:URL
ENTITY:@sys.url
PROMPTS:画像URLを教えてもらってもいいですか?
Fulfillment
Webhook:ON

Action内のREQUIREDをONにする事でURLのパラメータが入っていない場合に、PROMPTSで設定した聞き返しの質問をするように設定しました。
ENTITYの@sys.urlはDialogFlowが初期で持っているSystem Entitiesです、URLの情報がある場合はこのエンティティに情報が格納されます。

作成出来たらSaveを押して右上のTry it nowで試してみましょう。

作成したインテントに入った時に、URLの入力を促す回答をする所までの確認が出来ました。
後はWebhook側での処理になりますのでDialogFlowの設定は以上で完了です。

Vision APIの有効化

GoogleのAPI系はデフォルトでは無効になっているので有効にする必要があります。
Google Cloud ConsoleでVision APIを検索し、有効にします。

Cloud Functionsの設定

今回もWebHookにCloud Functionsを使用します。
まずpackage.jsonにVision APIのライブラリを追加しましょう。

package.json

{
 "name": "sample-http",
 "version": "0.0.1",
 "dependencies": {
 "@google-cloud/vision": "^0.14.0"
 }
}

今回はVision APIだけを使う予定ですが、他のAPIを使いたい場合には追加で使用したいライブラリをpackage.jsonに追加すれば使用出来る様になります。

次にindex.jsです。

index.js

exports.chatbottest = function chatbotTest(req, res) {
 let vision = require("@google-cloud/vision");
 let client = new vision.ImageAnnotatorClient();
 if (req.body.result.metadata.intentName == "boardgame_question") {
   let mes;
   if (!req.body.result.parameters.boardgame) {
     mes = "パンデミック、アグリコラ、カタンについてお答えできます。";
   }
   else if (req.body.result.parameters.boardgame == "パンデミック") {
     mes = "病原体から世界を救うボードゲームです";
   }
   else if (req.body.result.parameters.boardgame == "アグリコラ") {
     mes = "荒れ果てた土地で豊かな農場を作るゲームです";
   }
   else if (req.body.result.parameters.boardgame == "カタン") {
     mes = "未開拓のカタン島で部族を栄えさせるゲームです";
   }
   else {
     mes = "すいません、知らないボードゲームです";
   }
   res.setHeader('Content-Type', 'application/json');
   res.send(JSON.stringify({ "speech": mes, "displayText": mes }));

 }

 if(req.body.result.metadata.intentName == "boardgame_question_image"){
   let url;
   url = req.body.result.resolvedQuery;
   client.webDetection(url).then(results => {
     let labels = results[0].webDetection.webEntities;
     let gamename = getdescription(labels);
     let mes = "このゲームは"  + gamename + "です。"
     res.setHeader('Content-Type', 'application/json');
     res.send(JSON.stringify({ "speech": mes, "displayText": mes }));
 
   })
     .catch(err => {
       console.log("err:" + err)
       res.setHeader('Content-Type', 'application/json');
       res.send(JSON.stringify({ "speech": "", "displayText": "" }));
     });
 }
};

function getdescription(labels) {
 let mes;
 labels.forEach(label => {
   if (label.score > 1 && !label.description.match("game")) {
     mes = mes || label.description;
   }
 });
 return mes;
}

ソースの内容としては
2,3行目:Vision APIを使用する変数の宣言と呼び出し。
4~24行目:前回使った所です。インテント名で分岐させるように変更しています。
26~43行目:受け取ったURLをVision APIに解析させて、WebのEntitiesを取得。その後回答メッセージを作成します。
45行目~53行目:WebのEntitiesが複数存在するのでその中でもスコアが1より上でgameを含むEntity以外の物を取得しています。何度か試してみると、gameとかboard gameというEntityを取得していたのでノイズとして除外しています。

ちなみにこういった画像をVision APIにかけるとこんなEntitiesが得られます。

スコアが1以上なのがDairy cattle(乳牛)やcattle(牛)なので精度的には十分ですね。
以上で、Cloud Functionsの設定は終了です

WebHookの設定

Cloud FunctionsのHTTPトリガーからURLをコピーしてDialogFlowのWebHookに設定し、右下のSaveを押して適用しましょう。

以上でチャットボットの開発完了です!
開発したチャットボットを試してみましょう!

今回はこの2枚の画像について回答してもらいたいと思います。

上の画像は【カタンの開拓者】という、無人島を開拓するボードゲームの画像です。
下の画像は【将軍】という、武将になって日本の統一を目指すボードゲームの画像です。

まず上の画像からテストします。


成功です!
画像にもCatanという文字が入っていたので解析が簡単だったのかもしれません。
では次の画像です。こちらは文字もなくプレイしている画像なのですこし難しいかもしれません。

惜しい!
調べてみるとどうも似たようなシステムのPCゲームが出てきてしまったみたいです。
方向性的にはあっていましたが、間違えてしまいました。

チャットボットへの機能追加の先に

このようにGoogleの事前学習モデルの機械学習APIを組み合わせるだけでチャットボットに見る機能を追加する事が出来ました。開発自体は非常に容易だったのでは無いでしょうか?
今回は実施しませんでしたが、風景の写真を読み込ませ、ここはどこ?と聞くだけで場所を教えてくれるチャットボットの開発等も可能になります。
更に他のAPIと組み合わせれば、SpeechAPIで聞く事だったりNaturalLanguageAPIで感情の様な機能を開発する事も可能になってくるので興味が出た方は是非お試しください!

弊社クラウドエースでは、GCP料金を円請求書払いにできる支払い代行サービスや、GCPの技術サポートサービス、開発サービスなどを提供しております。
GCPに関する相談から、こんなチャットボットを作ってみたいという要望まで、クラウドエースに全ておまかせください!!

  • このエントリーをはてなブックマークに追加

Google のクラウドサービスについてもっと詳しく知りたい、直接話が聞いてみたいという方のために、クラウドエースでは無料相談会を実施しております。お申し込みは下記ボタンより承っておりますので、この機会にぜひ弊社をご利用いただければと思います。

無料相談会のお申込みはこちら