GPチップを開発する(JavaでCOTOHA API)


このページについて

ミニ四駆をご存じでしょうか。
単3電池2本と親指サイズのモーターながら凄まじいスピードで走る自動車模型で、
親子で楽しめることから、1980年代の登場より現在も愛されているおもちゃです。

このミニ四駆を題材としたアニメ「爆走兄弟レッツ&ゴー!!」(1994年~1998年)の中で「GPチップ」というパーツが登場します。
レースの状況や、マシンの持ち主からの掛け声・感情をもとに、マシン自らが判断して走行出来る様にするというAIパーツです。
これにより、レース中にレーサーやマシンに起きた出来事がレース展開にドラマティックに反映される様に描かれています。

当時少年だった私にとって夢の様なパーツでしたが、2020年現在、COTOHA APIで作れるのではないか?と思い、試してみました。

COTOHA APIとは?

自然言語処理・音声処理を対象としたAPIプラットフォームです。
言語処理の基本である音声認識、構文解析のみでなく、照応解析や感情分析、文章類似度など、多様な処理ニーズをAPIで手軽に利用出来るようにしてくれています。

機能概要

ミニ四駆は車です。
前進や右折などの「動作」と、加速の良さなどの「性能」が要素になります。
COTOHA GPチップを搭載する事で、以下の機能が備わることを目指します。

  • 持ち主の指示や檄によってマシンの動作を変える
  • 持ち主の発言から感情を推定しマシンの性能を変える

実装

環境 サービス/バージョン
実行環境 Windows10
開発環境 eclipse Pleiades
開発言語 Java 11
Framework SpringBoot 2.1.3

準備:COTOHA APIを使えるようにする

以下のページを頼りにしました。感謝。

  • COTOHA API の構文解析 を Java で利用してみる
    • API認証から構文解析のString Jsonの取得まで解説してくれています。
    • JSONのパースに対する記事もありますが、jsonschema2pojoで汎用的に作成出来る様にしていく方針がおすすめです。
  • jsonschema2pojoでResponce用のPOJOを作成する
    • サンプルレスポンスを貼り付けて実行することで当該API用のオブジェクトプログラムを生成してくれます。
    • 出力されたプログラムそのままJavaプロジェクトに持っていくだけでOKです。

1.持ち主の指示や檄によってマシンの動作を変える

  • 事前にマシンの動作と代表的な指示のパタンを定義します。
  • 持ち主の発言を入力として文タイプAPIにかけ、発言が「命令」かどうかを判定します。
  • 命令だった場合、発言を類似性判定APIにかけ、マシンの知っている指示のどれにあてはまる(と思われる)かを判定します。

1.1.マシンの動作と代表的な指示パタンを初期登録する

以下の様に、動作と指示語の組をマスタクラスに登録しておきます。

動作 初期登録しておく指示例
加速する 加速しろ、行け、負けるな、頑張れ、抜け
減速する 減速しろ、待て、前を譲れ
前進する 走れ、動け
後進する 下がれ、バックしろ
停止する 止まれ、ストップだ
右に寄る 右だ、右に寄れ
左に寄る 左だ、左に寄れ
右折する 右に曲がれ
左折する 左に曲がれ
前の機体の後ろに移動する 引っ張ってもらえ、ついていけ
後ろの機体の前に移動する 引っ張れ、連れて行け、抜かせるな
必殺技の動きをする バスターターンだ

1.2.文タイプを特定する

文タイプAPIでは、入力された文が「叙述/質問/命令」のいずれにあてはまるかを返却します。
さらに小分類として「挨拶/情報提供/約束/...」など行為種別を返却します。
「叙述-情報提供」と「命令」の2種類が「指示」に相当する場合が多く、この2種類が返ってきた場合に動作判定へ移る仕様としました。

1.3.どの動作をすべきか判定する

類似性判定APIでは、入力された2文間に対して意味ベースでの類似度を返却します。
例えば、「踏ん張れ」と発言した場合、事前に登録した語の中で最も類似度スコア(MAX1.0)の高い語は「頑張れ」の0.98321015です。
この結果、マシンは「加速する」動作を選択します。

2.持ち主の発言から感情を推定しマシンの性能を変える

モータや電池など、物理的なセッティングによる性能に対して、それをどの程度引き出すことが出来るかを制御する、という考え方になります。

  • 事前にマシンの性能と感情の関係を定義しておきます。
  • 持ち主の発言を感情分析APIにかけ、結果をもとに性能を更新します。

2.1.感情と性能のマッピングを定義する

感情分析APIではポジティブ/ニュートラル/ネガティブと以下の感情ラベルを返却します。
性能は最高速/加速/コーナリングの3要素。また、レッツ&ゴーでは2チームで複数台のマシンが走行する形式が多いため、独走or並走の嗜好性も持たせるようにします。

感情 最高速 加速度 コーナリング 独走主義 並走主義
ニュートラル - - - - -
ポジティブ UP UP - - -
ネガティブ - DOWN UP UP DOWN
喜ぶ UP - - DOWN UP
怒る UP UP DOWN UP DOWN
悲しい DOWN UP DOWN UP DOWN
不安 - DOWN UP DOWN UP
恥ずかしい DOWN UP UP DOWN UP
好ましい UP DOWN UP - -
- DOWN UP - -
興奮 UP UP DOWN UP DOWN
安心 DOWN - UP DOWN UP
驚く - UP DOWN - -
切ない DOWN - UP DOWN UP
願望 UP - DOWN UP DOWN

2.2.発言を入力として性能を更新する

  • 感情分析APIに発言を入れて結果を受け取ります。
  • 各性能の初期値を0.5(50%)、UPを踏む度に5%上昇、DOWNを踏む度に5%減少させます。
  • 上限は1.0(100%)、下減は0.2(20%)とします。

デモ

ソースはGitHubに上げています。
JavaでCOTOHA APIを使ってみたい方はサンプルプログラムとして参考ください。

マシンの動作を決める

http://localhost:8080/instruction?sentence="入力文" でPOST


{
  "result" : {
    "modality" : "imperative",
    "dialog_act" : [ "directive" ]
  },
  "status" : 0,
  "message" : ""
}

0.95615417:行けバックブレーダー:つれて行け:前の機体の前に移動する
0.9904602:行けバックブレーダー:ついていけ:前の機体の後ろにつく
0.99924904:行けバックブレーダー:行け:加速する

マシンの性能を更新する

http://localhost:8080/instruction?sentence="入力文" でPOST

俺はごめんだぜ、このレースに勝って最高の賞金と名誉を手に入れてみせる!

Positive
ごめん:悲しい
勝って:P
最高:P
名誉を手に入れてみせる:P

文全体の「Positive」判定と「ごめん」の感情が性能に反映されます。
※「P」はポジティブの極性(根拠情報)と思うため性能には特に反映させない。
※「ごめんだぜ」はどちらかというと「嫌」が正しい分類な気もしますが、今回はやむなし。

{
"maxSpeed": 0.55,
"acceleration": 0.75,
"cornering": 0.40,
"runaway": 0.60,
"parallelRunning": 0.40
}

何回か色々な言葉を投げかけた結果。この様に性能がチューニングされていく。

課題

たくさんありますが、いくつか書いておきます。

  • 主語を理解する(「自分」への命令であることを特定出来るとより良い)
  • 他者を認識する(「トライダガーについていけ」など)
  • 誤りを学習する(判定結果に対して「違う、加速だ」など追加の指示を与えることで、登録語を増やしたり減らしたりする)
  • 類似度判定に逐一APIを呼ぶため遅い(実用に向けてはもっと方法を考える必要がある)

おわりに

土屋博士は言いました。
「マシンは子供達が成長させる。子供達を無視して【より速いマシン】は誕生しない」
2020年現在、マシンへの情熱はタイヤやローラーなど物理的なキッティングが主流となっています。
今後、言葉を使ったキッティングが加わる様になると、より熱い展開が生まれそうですよね。

関連動画

実際にマシンを走らせるためには、今回の技術の他に
コースを認識して自走させたり、音声認識からマシン動作へ反映させる仕組みが必要になります。
こちらに対しては、以下の様な試みがある様です。

1.車載カメラからコース形状を認識して自走させる

2.音声認識を用いてマシンの動作を制御する