PythonでEmotion APIを使って感情判定しよう

こんにちは。まーやです。
今日は Microsoft Azure 内の[Cognitive Services](https://azure.microsoft.com/ja-jp/services/cognitive-services/) の一つとして公開されている[Emotion API](https://azure.microsoft.com/ja-jp/services/cognitive-services/emotion/)を使って遊んでみたいと思います。

# Agenda
- Emotion API とは
- お試しアプリを作ってみよう
- 利用した感想
- まとめ

# Emotion API とは
## 概要
Microsoftが提供する分析APIの一つです。Microsoft Azure で Cognitive Services の中の一つとして提供されています。
Emotion APIに写真を送付すると、

1. 写真から人間の顔を検知する
2. 検知した人間の表情がどんな感情のものなのか数値化する

という作業を行い、返却してくれます。ただただ写っている人の感情を知りたいだけであれば、分析の知識がなくても利用できちゃいますね。

Emotion APIの仕様を以下ピックアップしてみます。

- 検知できる顔の数は1枚の画像につき64人まで
    - 卒業式の写真とかでも大丈夫そうですね！
- 取得できる感情は8種類
    - anger(怒り)
    - contempt(侮蔑)
    - disgust(嫌悪)
    - fear(恐れ)
    - happiness(幸せ)
    - neutral(普通)
    - sadness(悲しみ)
    - surprise(驚き)
- 利用できる拡張子は4種類。ただしGIFについては最初のフレーム画像のみで判定します。
    - JPEG
    - PNG
    - BMP
    - GIF
- 画像容量は4MBまで
- 画像の大きさは 36×36 ～ 4096×4096 まで
- 返却されるJSONオブジェクトは顔の面積順にソートされています

## 価格
現在は米国西部リージョンでのみ提供されています。
利用には制限ありタイプ(Basicプラン) と 制限なしプラン(Standard)の[2種類が用意されています](https://azure.microsoft.com/ja-jp/pricing/details/cognitive-services/)。
Basicプランでは指定された顔の矩形のみ検知できます。それ以外(ちょっとだけ横顔etc.)の顔を検知したい場合はStandardプランを契約する必要があります(※1)。
どちらのプランも最大10ランザクション/秒までの利用となっています。それぞれ1000トランザクションあたり以下の値段で利用することが出来ます。

- Basicプラン
    - 1000 トランザクションあたり ¥10.20
- Standardプラン
    - 1000 トランザクションあたり ¥25.50


# お試しシステムを作ってみよう
## お試しシステム概要
作成した機能は以下の通り。

1. 写真をアップロードする
2. アップロードされた画像がEmotion APIの規定サイズより大きい場合は 4096×4096 にリサイズ
3. Emotion APIの実行
4. 3で得られた結果を累計し、一番大きな数値を持った感情名を表示＆累計された感情指数をグラフ化

実際にはこんな2画面になります。
選択して・・・↓
![demo1.png](https://qiita-image-store.s3.amazonaws.com/0/60850/92388ee8-6125-aa7b-0fe2-4f0452734007.png)
表示!↓
![plt_demo.png](https://qiita-image-store.s3.amazonaws.com/0/60850/7c46bcbb-df12-55d1-959c-d3524a01d785.png)

ちなみにこの写真は2015年10月のPyLadies Tokyo 1周年記念のときに撮影した写真です。パーティの写真なのでhappiness値がずば抜けて高いですね。

## 使った技術
### Emotion API
今回の作成の要となったサービス。上述の通りです。
[APIドキュメント](https://dev.projectoxford.ai/docs/services/5639d931ca73072154c1ce89/operations/563b31ea778daf121cc3a5fa)と[APIテストコンソール](https://dev.projectoxford.ai/docs/services/5639d931ca73072154c1ce89/operations/563b31ea778daf121cc3a5fa/console)の両方が用意されているのは心強いです。
お試しシステムでは、複数人の表情データを取得した場合は、それぞれの感情値を単純にSUMしています。

### Tornado
PythonのWEBフレームワークであり非同期通信ライブラリです(今回は単純にWEBフレームワークとして利用しています)。Facebook製で軽量。Python2系でも3系でも動作OKです(今回はPython3系で作成しました)。テンプレートエンジンが入っているので、画面にPythonから値を渡したい時は指定の記法を行えば引き渡して表示されることが出来ます。html上にPythonコードも書こうと思えばかけちゃいます。
個人的に嬉しいのは[ソースコードと一緒にdemoシステムが用意されていること](https://github.com/tornadoweb/tornado)。そしてこのdemoシステムが結構豊富にそろっていることです。WebsocketやOAuthなど一通り網羅しているので参考にしやすいです。
が、あんまり流行ってない気がしてならない。私は好きなんだけどなぁ。

### Pillow
Python Imaging Library (PIL)の fork プロジェクトで、左記読んで字のごとく[Pythonの画像処理ライブラリ](https://pillow.readthedocs.io/en/3.4.x/)です。

>pip install pillow

だけで使えるようになっちゃうので大変便利です。そして画像をいじるライブラリの割にわかりやすい感じで個人的には好みです。
今回は画像のリサイズ機能のみ使用しましたが、色の反転や画像の結合、テキストの書き込みなんかもできてしまう万能ライブラリです。

### Chart.js
[グラフ描画JS](http://www.chartjs.org/docs/#chart-configuration)です。動きがかわいいこと、使い方がシンプルなこと、描画できるグラフの種類がとても豊富なので気に入っています。ラベルをクリックすることで表示のon/offが切り替えられるんですよ。

全部表示した場合↓
![on.png](https://qiita-image-store.s3.amazonaws.com/0/60850/859d1fdc-d440-e897-49ac-7e5dac56efb0.png)

happinessとneutralを非表示にした場合↓
![off.png](https://qiita-image-store.s3.amazonaws.com/0/60850/6abf2651-dc83-06d5-0a02-aab65374be1b.png)

# Emotion APIを利用した感想
利用方法はいたってシンプルで、以下の手順を踏むだけ(詳しい使い方は[こちら](https://dev.projectoxford.ai/docs/services/5639d931ca73072154c1ce89/operations/563b31ea778daf121cc3a5fa)を参照してください)。

- Azureのポータルから利用登録を行う
- 利用登録時に発行されたkeyをPOSTリクエストヘッダに設定
- 写真のURLを送付！

簡単で使いやすいですね。

色々試してみたところ、笑顔の判定(happiness)は比較的高い数字が出やすいな、と感じました(※2)。笑ってるときって普通に見ていても「笑っている」とわかりやすいですもんね。なんとなく腑に落ちました。
逆に、fearやcontemptなどの判断が難しそうな項目は判定結果もhappinessのような顕著な結果にはなりづらかったです。fearとcontemptが同じくらいの数値、とかよく見かけた気がします(※3)

複数人の感情データが取得できた場合、今回は単純に各感情毎に数値を足しあげて判定結果としましたが、例えば今回のように「写真全体としての感情判断」を取得したい場合は、今回のように各感情を足し上げるだけでよいのか、それとも得た結果から重みづけや再分析をするべきなのかは分析初心者な私には判断つきませんでした。写っている顔面積などで重みづけしても面白いかもしれませんね。

今回使った静止画版Emotion APIのほかに動画版Emotion APIもあるので、次回機会があったらこちらを試してみたいと思います。

# まとめ
- Emotion API、利用の仕方がシンプルで簡単だよ。
- Emotion APIから算出された数値の利用方法(利用アイデア)が楽しいアプリ開発のカギになるよ。


以上でした。

---------------------------------------------------------------
※1：2016/10/25 現在
※2：あくまで個人の感想です。数値化したわけではありません。
※3：使った写真があまりよくなかったのかもしれません。