1. Qiita
  2. 投稿
  3. node-red

コーディング不要で「Twitter投稿画像を解説する人工知能ボット」を開発する

  • 47
    いいね
  • 0
    コメント

 今回は、コーディングレス開発環境であるNode-REDを用いて「Twitterへ投稿された画像に何が写っているか発言する人工知能ジョークボット」を作成しましたので紹介します。本ボットは、Microsoft Cognitive ServicesのComputer Vision APIノードと、WatsonのLanguage Translater APIノードを組み合わせて開発しました。特定のハッシュタグを含む画像付きツイートが投稿されると、下の様に画像に何が写っているかの説明を返信してくれます。

sample8.png

最初にボットの動作デモを掲載します。

(1) 電車の写真

 まず、特定のハッシュタグを付けて、下の電車の画像を投稿してみます。

input2.jpg

 すると、ボットが写真に何が写っているか発言します。「旅客列車が駅に到着」とリプライし、良い感じの認識結末ですね。

sample2.png

(2) カフェの写真

 同様にハッシュタグを付けて、カフェの写真を投稿します。

input3.jpg

 ボットが「サンドイッチとコーヒー1杯」と返しました。右下のフルーツは何か分からなかったようです。

sample3.png

(3) フルーツの写真

 次に、フルーツ盛り合わせの写真を投稿します。

input8.jpg

 「プレートの上のフルーツサラダ」と返ってきました。白いお皿も正しく認識しているようですね。

sample8.png

(4) 船の写真

 大きな船、クイーンビクトリア号の写真を投稿します。

input6.jpg

 「桟橋に停泊船」と出力されました。確かに桟橋と船がありますね。手前の小さな船を認識している気もしますが、正解です。

sample6.png

(5) 庭の写真

 庭の写真を投稿します。

input5.jpg

 「レンガのビルの前にあるベンチ」と出力されました。左下の白い椅子のことですね。位置関係も理解している点が素晴らしいです。

sample5.png

(6) 夜景の写真

 夜景の写真を投稿してみます。

input7.jpg

 「日没時の夜景ビュー」と出力されました。上の方の夕焼けの色を認識して、日没時であることを判定しました。時間帯まで把握する点、凄いです。

sample7.png

(7) お弁当の写真

 お弁当の写真をアップロードしてみます。

input9.jpg

 「さまざまな食材でいっぱいのプラスチック容器」と表示されました。個々の食材を説明すると長くなるので「さまざまな食材」とまとめるざっくり感も人間らしいです。プラスチック容器であることは、光り具合から判定しているのでしょうか。凄いです。

sample9.png

(8) ランチの写真

 飯テロすいません。この写真は「さあ、今から食べるぞ。いただきます。」という状況です。

input1.jpg

 「食事が準備され、食べられるように用意」と出力されました。怖いくらい状況をよく把握していますね。

sample1.png

(9) 時計台の写真

 最後に、ロンドンのビックベンの写真を投稿してみます。

input4.jpg

 「londonの街にそびえる大きな時計塔」と出力されました。ツイート本文にロンドンと書きましたが、本情報は使わず画像のみでロンドンの写真であると回答しています。この様な人工知能APIを手軽に使える素晴らしい時代になりました。

sample4.png

活用した人工知能API

 画像から説明文の生成は、Microsoft Cognitive ServicesのComputer Vision API、和訳はBluemix版WatsonのLanguage Translater APIを利用しました。両方のAPIとも1日あたり100ツイート程度の処理量でしたら無料で利用できるため、ぜひ試してみてください。以降でNode-REDを用いた開発方法について説明します。

Node-REDへ必要な処理ノードをインストール

 今回は、Node-REDがインストールされていることを前提(例えば、Azureへのインストール方法はこちら)とし、Cognitive ServicesノードとWatsonノードをインストールします。Node-REDの右上メニュー->Manage pallette->installを選択した後、下の通り検索キーワードを入力し、必要な処理ノードをインストールします。処理ノード名は、それぞれnode-red-contrib-cognitive-servicesと、node-red-node-watsonです。

installnode2.png

installnode1.png

 ブラウザをリロードすると、左側のパレットにCognitive ServicesノードとWatsonノードが登場します。

palette.png

作成した処理フロー

 以下の様な処理フローを作成しました。Node-REDはコーディング不要で開発できるため、誰でも30分程で作成することができます。

flow.png

各処理ノードのプロパティ設定は、以下の通りです。

Twitter-inノード(特定のハッシュタグのツイートを収集)

 右側に端子があるTwitterノードは、特定のハッシュタグのツイートを収集します。

twitterin.png

 プロパティ画面では、Twitter IDの右側の鉛筆マークをクリックしてTwitterアカウントと連携させます。次に、forの部分にツイートを取得するハッシュタグを入力します。

Switchノード(画像が含まれるツイートをフィルタ)

 最初2つの黄色のSwitchノードは、Twitter-inノードから受け取ったツイートのうち、画像のURLが含まれるツイートのみに絞り込みます。

switch1.png

switch2.png

上の様に、2回に分けて変数tweet.entities.media[0].media_url_httpsに値が入っているかを判定し、値が入っているツイートのみ次の処理ノードに引き継ぎます。

Changeノード(画像のURLを他の変数に格納)

 3つ目の黄色の処理ノードであるChangeノードは、画像のURLをmsg.payloadという変数へ格納します。後続のComputer Visionノードは変数msg.payloadの値を入力値として受け付けます。

change1.png

上の様に、変数tweet.entities.media[0].media_url_httpsに格納されている画像のURLを、変数msg.payloadへコピーします。

Computer Visionノード(画像認識を行い、画像の説明文を取得)

 画像のURLをMicrosoft Cognitive ServicesのComputer Vision APIに投げ、画像を解析させ、画像の説明文(英文)を取得します。

computervision.png

 プロパティ画面では、OparationとしてDescriptionを選択します。Subscription keyの項目には、Cognitive ServicesのページやAzureポータルから取得したサブスクリプションキーを貼り付けます。(余談ですがOparationの他の項目である、タグ、年齢、性別判定なども人工知能らしさを感じる結果を得ることができますので、ぜひ試してみてください)

Language Translaterノード(英文の説明文を日本語へ翻訳)

 説明文は英文のため、その後WatsonのLanguage Translater APIに投げ、日本語化を行います。

languagetanslator.png

 プロパティには、必要に応じてBluemixの管理画面から取得したIDとパスワードを貼り付けます。言語は、英語から日本語へ翻訳するよう設定します。

Templateノード(ツイート本文を作成)

 Templateノードでは、前のノードから受け取った変数を用いて、ツイート本文を作成します。

template.png

 mustacheの記述方法を用いて、画像の説明文の日本語訳、元ツイートのURLを生成します。

Twitter-outノード(ツイートを投稿する)

 最後に、Twitter-outノードを用いて、Templateノードで作成したツイートを投稿します。

twitterout.png

 プロパティでは、Twitter-inノードと同様に、連携するTwitterアカウントを登録します。

最後に

 以上の様にNode-REDを用いることで、人工知能の技術進歩を感じることができる人工知能ボットを、簡単に開発できました。人間が見ると誤認識や誤訳も見つかりますが、人間は人間らしく、人工知能を用いた業務の自動化など、このAPIで実現出来るアイデアを生み出すことが大切と思います。
 今回はAzureとBluemixの人工知能APIを組み合わせました。各社人工知能APIは認識精度で比較されがちですが、パッケージ製品売り(翻訳ソフト等)の時代と比較すると、クラウドが主流の現代ではあまり重要ではなくなってきていると考えます。なぜなら、内部の学習モデルは日々改善され、一時期の精度の比較結果は将来大きく変化する可能性が高いからです。また今時の(?)人工知能API提供側は、複雑なアルゴリズムを実装して認識精度を向上させるのではなく、学習データを増やすことと比例して認識精度が向上するようアルゴリズムを組むと思います。そのため、ウェブ上のデータや、ユーザログを大量に持つ企業が有利です。ユーザが人工知能APIを沢山利用すると、ビジネス上でも学習モデル改善の投資優先度が上がりますし、結局、認識精度は開発者が人工知能APIをどれだけ使うかで決まるはずです。
 また、各社全く同じ機能を提供している人工知能APIはあまりなく、補完関係にあるものも多いです。そのため、人工知能APIを活用する開発者は、自身のアプリケーションのアイデアを実現するために、各人工知能APIを必要に応じて使えるように知識を付けておくことが重要です。この辺りも各社理解してSDK統一などを行い、開発者に優しく、仲良く市場を広げてほしいですね。

参考

画像付きツイートの取得方法
http://qiita.com/mayfair/items/f869d3ccf831803d64d8

ソースコード

 ソースコードは以下の通りです。Node-REDは、開発環境の右上メニュー->Import->Clipboardからソースコードを貼り付けることができます。

[{"id":"24763a2f.4aa4e6","type":"twitter in","z":"54262ffb.a09cf","twitter":"","tags":"#hashtag","user":"false","name":"ツイート取得","topic":"tweets","inputs":1,"x":170,"y":40,"wires":[["c19edaa1.235888"]]},{"id":"3dc92fdd.8217","type":"change","z":"54262ffb.a09cf","name":"画像URLをmsg.payloadへ代入","rules":[{"t":"set","p":"payload","pt":"msg","to":"tweet.entities.media[0].media_url_https","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":230,"y":180,"wires":[["8afdf582.d41988"]]},{"id":"b97b40d2.d074a","type":"switch","z":"54262ffb.a09cf","name":"画像付きツイートのみフィルタ2","property":"tweet.entities.media[0].media_url_https","propertyType":"msg","rules":[{"t":"nnull"}],"checkall":"true","outputs":1,"x":480,"y":100,"wires":[["3dc92fdd.8217"]]},{"id":"c19edaa1.235888","type":"switch","z":"54262ffb.a09cf","name":"画像付きツイートのみフィルタ1","property":"tweet.entities.media","propertyType":"msg","rules":[{"t":"nnull"}],"checkall":"true","outputs":1,"x":220,"y":100,"wires":[["b97b40d2.d074a"]]},{"id":"8afdf582.d41988","type":"Computer Vision","z":"54262ffb.a09cf","operation":"description","name":"","x":470,"y":180,"wires":[["7bb66b9a.0de714"]]},{"id":"7bb66b9a.0de714","type":"watson-translator","z":"54262ffb.a09cf","name":"","action":"translate","basemodel":"ar-en","domain":"news","srclang":"en","destlang":"ja","password":"","custom":"","domainhidden":"news","srclanghidden":"en","destlanghidden":"ja","basemodelhidden":"ar-en","customhidden":"","filetype":"forcedglossary","trainid":"","lgparams2":true,"ldparamshidden2":"true","x":190,"y":260,"wires":[["8cc62777.37eb38"]]},{"id":"eb5b43f4.e511b","type":"twitter out","z":"54262ffb.a09cf","twitter":"","name":"ツイート投稿","x":570,"y":240,"wires":[]},{"id":"8cc62777.37eb38","type":"template","z":"54262ffb.a09cf","name":"ツイート文作成","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"画像認識ボットが「{{payload}}」と言っています。 #hashtag https://twitter.com/{{tweet.user.screen_name}}/status/{{tweet.id_str}}","x":380,"y":260,"wires":[["eb5b43f4.e511b","e48e4d22.df92f"]]},{"id":"e48e4d22.df92f","type":"debug","z":"54262ffb.a09cf","name":"デバッグ表示","active":true,"console":"false","complete":"payload","x":570,"y":280,"wires":[]}]