感情解析API「Empath」の実力はいかに？実際に試してみた結果をレビュー

この記事は[Ateam Hikkoshi samurai Inc.× Ateam Connect Inc. Advent Calendar 2020](https://qiita.com/advent-calendar/2020/hikkoshizamurai-connect) 24日目の記事です。

エイチームコネクト技術開発部の @keki が担当いたします。

# はじめに
皆さん、音声データから感情を認識できたら、いろいろと活用できる場がありそうだと思いませんか？

私が所属しているエイチームコネクトはコンタクトセンターの部隊。
常日頃、大量の音声データが飛び交う場所なので、特に活用できる場は多そうです。

ということで、今回は感情解析API「Empath」を使って、いくつかの音声を感情解析してみました。
実装自体はとても簡単にできるので、興味がある方はぜひ試してみてくださいね。

# 感情解析API「Empath」について
音声の物理的な特徴量をもとに感情を解析するAPIです。
サイト上からマイクに向かって話して感情解析も行ってくれます。

サイトURLはこちら
https://webempath.net/lp-jpn/

# 実装手順

## 【手順1】 Empathサイトにてユーザー登録

感情解析API「Empath」を使うには、まずユーザー登録が必要です。

基本は無料で使えますが、1ヶ月の無料枠（API利用回数）を超えるとその月は使えなくなるので注意が必要です。

以下のサイトの中段にある、「お申し込みはコチラ」ボタンからユーザー登録を行なってください。
https://webempath.net/lp-jpn/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117041/50b11759-cd69-4a12-b62c-a6778c89893c.png)

## 【手順2】 API Keyの取得

ユーザー登録が完了すると、管理画面にログインできるようになります。

管理画面上のAPI Keyメニューから、Keyの登録と取得を行います。

![スクリーンショット 2020-12-09 8.05.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117041/f120cac4-b72d-c5c0-c0e3-3dfe00881aa4.png)

## 【手順3】 開発（コーディング）

上記で取得したAPI Keyとwavファイルをパラメータに、指定URLに対してPOSTするだけです。

以下、サンプルコードです。
Pythonで記載していますが、行なっていることはシンプルなので、他の言語で書いてもOKです。

利用した環境は、

* macOS Catalina 10.15.7
* python 3.7.6
* request 2.22.0

です。

```python:sample.py
import requests

url ='https://api.webempath.net/v2/analyzeWav'

apikey = 'YOUR API KEY'
payload = {'apikey': apikey}

wav = "/file/to/path/sample.wav"
data = open(wav, 'rb')
file = {'wav': data}

res = requests.post(url, params=payload, files=file)
print(res.json())
```

なお、Empath指定の音声ファイルの形式でないと、エラーが返ってきます。
音声ファイルは以下の形式のデータを指定するようにしてください。

* PCM WAVE形式　16bit
* データサイズが1.9MB以下
* PCM_FLOAT、PCM_SIGNED、PCM_UNSIGNEDのいずれかのフォーマット
* 録音時間が5.0秒未満
* サンプリング周波数が11025Hz
* チャンネル数が1（モノラル）

音声の変換は、以下のツールを使って行うのが便利です。

▼ Audacity
https://www.audacityteam.org/

## 【手順4】 実行

pythonコマンドで上記ファイルを実行します。

```
$ python sample.py
```

実行すると、以下のような結果が返ってきます。

「平常心」「怒り」「喜び」「悲しみ」「元気さ」といった項目に対して、0〜50の数値で、結果を返してくれます。

```
{'error': 0, 'calm': 24, 'anger': 3, 'joy': 3, 'sorrow': 18, 'energy': 0}
```

### 結果の見方

|項目|説明|
|:----|:----|
|calm（平常心）|0〜50で結果を返す。数値が大きいほど、平常心。小さいと感情の乱れがある。|
|anger（怒り）|0〜50で結果を返す。数値が大きいほど怒っている。|
|joy（喜び）|0〜50で結果を返す。数値が大きいほど喜んでいる。|
|sorrow（悲しみ）|0〜50で結果を返す。数値が小さいほど悲しんでいる。|
|energy（元気さ）|0〜50で結果を返す。数値が大きいほど元気である。|

「平常心」の項目がどれくらいの数値か？をベースに、
その他の項目の動きを見るのが良さそうですね。

## 【注意点】 v1とv2の違いについて

Empath APIには、v1とv2が存在します。

結論、それぞれの違いは「エラー発生時の情報量」のみです。

例えば、音声ファイル形式が不正な場合（このエラーが一番多い）、
v1だと、エラーコードしか返さないのに対して、v2だとエラーの内容も返してくれます。

また、エラーの粒度もv2の方が細かいです。
例えば、音声ファイル形式不正の場合、v1の場合は全てエラーコード「1001」で返すのに対し、
v2の場合はケースに応じて「1001 〜 1017」で分類してくれます。

v1とv2は、POSTするURLを変更するだけで使い分け可能ですので、v2を使った方が良いでしょう。

### 【例】 誤ってmp3を指定した場合のエラー

v1の場合

```
$ python sample.py
{'error': 1001}
```

v2の場合

```
$ python sample.py
{'error': 1016, 'msg': 'could not get audio input stream.'}
```

# 検証結果

では、実際に検証した結果をご紹介します。

## サンプル音源について

サンプル音源は、以下のサイトからダウンロードさせていただきました。
http://pro-video.jp/voice/announce/

※ コンタクトセンターに所属しているんだから、実際の音声で試してよ。という声も聞こえてきそうですが、個人情報保護の観点から、今回は見合わせますのであしからず...

## 【検証1】 ナレーション風の音声

### 使用した音声（上記URLからダウンロード）
![スクリーンショット 2020-12-09 8.50.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117041/b766fd33-c093-5d09-5a11-bb987eaee4b3.png)
引用：http://pro-video.jp/voice/announce/

※ 冒頭の「無添加のシャボン玉せっけんならもう安心」の部分だけを切り出して使用しています。

### 特徴
* はきはきと、元気に発声している音声。
* 声の上ずり等は無く、比較的安定した音量で発声している音声

### 結果

```
$ python sample.py
{'error': 0, 'calm': 8, 'anger': 0, 'joy': 32, 'sorrow': 8, 'energy': 24}
```

|項目|結果|
|:----|:----|
|calm（平常心）|8|
|anger（怒り）|0|
|joy（喜び）|32|
|sorrow（悲しみ）|8|
|energy（元気さ）|24|

怒りの要素がゼロ、喜びや元気さの数値が大きいのは納得がいく結果です。
平常心の数値が意外と少ないのと、僅かながら悲しみの要素が含まれている点は、やや疑問です。

もしかしたら音質にもよるのかもしれません。

## 【検証2】 ちょっと悲しげな音声

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117041/6e8f7dff-c6fe-c4a5-fdc2-203decf3c8de.png)
引用：http://pro-video.jp/voice/announce/

※ 短い音声なので、特に切り出しは行っていません。

### 特徴
* 悲しげな声
* やや、セリフがかった声か？

```
$ python sample.py
{'error': 0, 'calm': 9, 'anger': 20, 'joy': 18, 'sorrow': 1, 'energy': 37}
```

|項目|結果|
|:----|:----|
|calm（平常心）|9|
|anger（怒り）|20|
|joy（喜び）|18|
|sorrow（悲しみ）|1|
|energy（元気さ）|37|

悲しげな声を選んだはずですが、なぜか「悲しみ」の要素はわずか1。
そして、怒りの要素が20、喜びの要素が18という結果に。

なぜこのような結果になったのかは謀りかねますが、
声優さんがアニメで発声する声だから、こういった結果になったのかもしれません。

## 【検証3】 背景に音楽が流れれている音声

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117041/d6d365bf-dd84-dc2d-b293-7698e5a3aadf.png)
引用：http://pro-video.jp/voice/announce/

※ 冒頭の「当社の概要と業務についてご紹介いたします」の部分だけを切り出して使用しています。

### 特徴
* アナウンサー風の声
* バックミュージックが流れている

```
$ python sample.py
{'error': 0, 'calm': 24, 'anger': 3, 'joy': 3, 'sorrow': 18, 'energy': 0}
```

|項目|結果|
|:----|:----|
|calm（平常心）|24|
|anger（怒り）|3|
|joy（喜び）|3|
|sorrow（悲しみ）|18|
|energy（元気さ）|0|

アナウンサー風の声なので、平常心が24、元気さが0という数値なのは納得。
バックミュージックの影響はあまり感じないです。

# 所感＆まとめ

## 精度について
結果、AIが算出してくれる数値なので、人間が結果を推測するのには限界がありますが、ある程度の傾向といったレベルで見ると、大枠ずれてはいないように感じます。

この結果を、別のAIモデルに投入し、この数値と、コンタクトセンターでの成約率との相関性を見る。等を行うと良いのかもしれませんね。

## その他懸念
また、現状検証した中で致命的だったのが、最大で5秒までの音声ファイルしか対応していない点です。

有料版に切り替えることで制限が外れる可能性も高いと思いますが、容量無制限の従量課金制であれば、「社員のモチベーション管理」等で使う用途はありそうだなと感じました。

# 次回予告
この記事は、[Ateam Hikkoshi samurai Inc.× Ateam Connect Inc. Advent Calendar 2020](https://qiita.com/advent-calendar/2020/hikkoshizamurai-connect) 24日目の記事です。

明日25日クリスマスは、フロントエンドに強い @hinora さんが記事を書いてくれます。
お楽しみに！！

# 参考・引用元

* [感情解析API「Empath」](https://webempath.net/lp-jpn/)
* http://pro-video.jp/voice/announce/