GPチップを開発する（JavaでCOTOHA API）

# このページについて

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

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

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

# [COTOHA API](https://api.ce-cotoha.com/contents/index.html)とは？

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

# 機能概要

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

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

# 実装

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

## 準備：COTOHA APIを使えるようにする
以下のページを頼りにしました。感謝。

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

![プレゼンテーション1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/385780/23750121-cd64-349a-f05b-4bd941da2925.png)


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

 * 事前にマシンの動作と代表的な指示のパタンを定義します。
 * 持ち主の発言を入力として[文タイプAPI](https://api.ce-cotoha.com/contents/reference/apireference.html#sentence)にかけ、発言が「命令」かどうかを判定します。
 * 命令だった場合、発言を[類似性判定API](https://api.ce-cotoha.com/contents/reference/apireference.html#similarity)にかけ、マシンの知っている指示のどれにあてはまる（と思われる）かを判定します。

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

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

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

### １．２．文タイプを特定する

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

### １．３．どの動作をすべきか判定する

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

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

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

 * 事前にマシンの性能と感情の関係を定義しておきます。
 * 持ち主の発言を[感情分析API](https://api.ce-cotoha.com/contents/reference/apireference.html#sentiment)にかけ、結果をもとに性能を更新します。

### ２．１．感情と性能のマッピングを定義する

[感情分析API](https://api.ce-cotoha.com/contents/reference/apireference.html#sentiment)ではポジティブ/ニュートラル/ネガティブと以下の感情ラベルを返却します。
性能は最高速/加速/コーナリングの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|

### ２．２．発言を入力として性能を更新する

 * [感情分析API](https://api.ce-cotoha.com/contents/reference/apireference.html#sentiment)に発言を入れて結果を受け取ります。
 * 各性能の初期値を0.5(50%)、UPを踏む度に5%上昇、DOWNを踏む度に5%減少させます。
 * 上限は1.0(100%)、下減は0.2(20%)とします。

# デモ

ソースは[GitHub](https://github.com/ketman55/CotohaApiSample/tree/master/src/main/java/com/lab/app/ketman)に上げています。
JavaでCOTOHA APIを使ってみたい方はサンプルプログラムとして参考ください。

####マシンの動作を決める

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

```text

{
  "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
}
```

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

# 今後の課題

 * 主語を理解する（「自分」への命令であることを特定出来るとより良い）
 * 他者を認識する（「トライダガーについていけ」など）
 * 誤りを学習する（判定結果に対して「違う、加速だ」など追加の指示を与えることで、登録語を増やしたり減らしたりする）
など
# おわりに

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

# 関連動画
[１．車載カメラからコース形状を認識して自走させる]((https://youtu.be/K-cZCO8WR9c))
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/385780/79715a77-ae21-c061-5c80-c9e6a27f5e07.png)

[２．音声認識を用いてマシンの動作を制御する](https://www.youtube.com/watch?v=TnGXI2CO4kY)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/385780/fc50c065-18c2-baeb-1721-62e4dd2d88d3.png)