AutoML Natural Language API の感情分析モデルでシャニマスアイドルの台詞を分析 

#概要
本稿では、シャニマスに登場するアイドル23人の台詞をAutoML Natural Language APIの感情分析モデルを使用して分析してみます。

#シャニマスとは
2018年4月24日にサービスを開始した『THE IDOLM@STER』シリーズの育成シミュレーションブラウザゲーム
[アイドルマスターシャイニーカラーズ](https://cloud.google.com/natural-language/docs?hl=ja)
略してシャニマスです。
**とりあえずプレイしてください。**

#AutoML Natural Language API とは
GoogleがGoogle Cloudで公開している機械学習モデル構築サービス「AutoML Natural Language」に用意されたAPIで、
APIを通して分類、エンティティ抽出、感情分析、構文解析などのサービスを利用できます。
詳細は公式ドキュメントを御覧ください。
[Google Cloud　公式ドキュメント](https://cloud.google.com/natural-language/docs?hl=ja)

#AutoML Natural Language API の使用例
環境構築や事前準備等は上記公式ドキュメントのチュートリアル通りなので割愛します。

試しに下記コードを実行してみます。

```python3:AutoMLTest.py
# Imports library
from google.cloud import language
from google.cloud.language import enums
from google.cloud.language import types

client = language.LanguageServiceClient()
text = u'え……っ あ、あの……ど、どうしてこんなこと…………ひどいです……'
document = types.Document(content=text,type=enums.Document.Type.PLAIN_TEXT)
sentiment = client.analyze_sentiment(document=document).document_sentiment
print('Text: {}'.format(text))
print('Sentiment: {}, {}'.format(sentiment.score, sentiment.magnitude))
```

###結果

```
PS > python AutoMLTest.py
Text: え……っ あ、あの……ど、どうしてこんなこと…………ひどいです……
Sentiment: -0.20000000298023224, 1.600000023841858
```
実行すると、scoreとmagnitudeという値が返ってきます。

scoreは文全体の感情を示します。
-1.0 ~ +1.0の値をとり、値が大きいほどポジティブな文です。
文中にポジティブとネガティブが混在している場合は合計値が出力されるため、値が0に近い場合、文がニュートラル若しくはポジティブ/ネガティブが混在した文であると言えます。

magnitudeは、文全体に感情的な内容がどのくらい含まれているかを示します。
検出されたscoreの絶対値の合計がmagnitudeになるので、0以上の値をとり、値が大きいほど感情的な文であると言えます。
文がニュートラルであれば値は小さく、ポジティブ/ネガティブが混在した文であれば値は大きくなる傾向にあります。

今回の実行結果は、scoreが約-0.2,magnitudeが約1.6ですから、全体としてネガティブな文であると言えます。
100％ネガティブの文に見えますが(scoreとmagnitudeに差があるため)、結果はポジティブな部分もあると分析されました。
詳しくみてもおもしろそうですが、本稿では分析対象文が全体的にかなり短く、かなりくだけた文でもあるため、参考程度に留めておきます。

#分析
##対象台詞
今回分析対象とする台詞は各アイドルのアルバムで再生できる下記台詞(18種)とします。

- ホームタッチボイスA①
- ホームタッチボイスA②
- ホームタッチボイスB①
- ホームタッチボイスB②
- ホームタッチボイスC①
- ホームタッチボイスC②
- タッチボイス①～⑫

選定理由として、上記台詞はアイドルをクリック(タップ)したときに発せられる台詞で、
各ホームタッチボイス②とタッチボイス④～⑥及び⑩～⑫はゲーム内ステータスによって解禁される台詞になっています。
初期から開放されている各ホームタッチボイス①とタッチボイス①～③及び⑦～⑨は基本的に拒絶するような台詞、
各ホームタッチボイス②とタッチボイス④～⑥及び⑩～⑫は好意的な台詞という傾向が見られます。
そのため、前者をネガティブな台詞、後者をポジティブな台詞と仮定します。

###使用データ
対象台詞を下記のような形式でcsvで作成します。
positiveカラムは、ネガティブな台詞なら-1,ポジティブな台詞なら1を設定します。
実際のAPI利用時にはwordsカラムだけで問題ありませんが、後々使用するので先に作成します。
今回、全て手作業で文字起こししたため、これが一番大変でした。

| name | words| positive |
|:-----------|:------------:|------------:|
| mano | す、すみません……っ もしかして、髪の毛くしゃくしゃでしたでしょうか……？|-1|
| mano | プロデューサーさんの手、とってもあったかくて……撫でてもらうと眠くなっちゃいそうです |1|
|hiori|なっ……なんですか？ ゴミでも付いていましたか？|-1|
|hiori|なっ…… いえ、嫌なんじゃなくて…… ……恥ずかしいです|1|

##実行

下記コードで作成したcsvを読み込み、APIにリクエストを送ります。
使用例のコードをループさせただけです。

```python3

# Imports 
from google.cloud import language
from google.cloud.language import enums
from google.cloud.language import types
import pandas as pd

df = pd.read_csv('wordstext.txt', sep=",")
client = language.LanguageServiceClient()

for row in df.itertuples():
    text = row.words
    document = types.Document(content=text,type=enums.Document.Type.PLAIN_TEXT)
    sentiment = client.analyze_sentiment(document=document).document_sentiment
    print('Text: {}'.format(text))
    print('Sentiment: {}, {}'.format(sentiment.score, sentiment.magnitude))

```
実行すると、先程のような形式で結果が返ってきますので、先程のcsvと併せてなんやかんやで加工して集計しやすいようにしてやります。

| name | words| positive |score| magnitude|
|:-----------|------------:|:------------:|:------------:|:------------:|
| mano | す、すみません……っ もしかして、髪の毛くしゃくしゃでしたでしょうか……？|-1|0.200000002980232|0.200000002980232|
| mano | プロデューサーさんの手、とってもあったかくて……撫でてもらうと眠くなっちゃいそうです |1|0.200000002980232|0.5|
|hiori|なっ……なんですか？ ゴミでも付いていましたか？|-1|-0.200000002980232|0.699999988079071|
|hiori|なっ…… いえ、嫌なんじゃなくて…… ……恥ずかしいです|1|-0.300000011920928|1.10000002384185|


##結果

以下、集計結果です。
scoreの合計値が大きいほど、好意的な台詞が多く、magnitudeの値が大きいほど感情が豊か、といった感じでしょうか。(あくまで独自解釈です。)

| name | score合計値|magnitude合計値|
|:-------|------------:|--------------:|
|真乃| -1.7000000180|11.7999999896|
|灯織|-3.1000000388|11.9000000580|
|めぐる|-1.3000000343|9.0000000894|
|恋鐘|0.4000000134|10.2000000477 |
|摩美々|-3.6999999585|11.0000000746|
|咲耶|-5.4999999778|11.0999999792|
|結華|-2.4000000433|11.0000000969|
|霧子| -0.8999999912|10.7000001445|
|果穂|3.6000000759|11.8000000715|
|智代子|-2.8000000343|15.7000000999|
|樹里|-1.8000000267|11.7000000999|
|凛世| -2.2000000551|10.7000000255|
|夏葉|-5.7000000700|12.0999999866|
|甘奈| -1.0999999793|12.7000001073|
|甜花|-1.9000000580|13.4000001846|
|千雪|-2.0000000151|8.9999999555|
|あさひ|-0.9000000358|11.2000000330|
|冬優子|-3.6999999807| 8.8999999464|
|愛依|-3.3000000492|10.5000000223|
|透|-0.0000000149|5.6000000761|
|円香|-3.8999998944|6.1999999733|
|小糸|-3.3000001087|12.1000001430|
|雛菜|-0.6999999956| 7.9000000284|


各値のBEST5とWORST5はこんな感じ。

| 順位 | 全台詞score合計|ポジティブ台詞score合計|ネガティブ台詞score合計|magnitude合計|
|:--------|------------:|--------------:|--------------:|--------------:|
|1 |　果穂|　果穂|　　透|智代子
|2 |　恋鐘|　恋鐘|　果穂|甜花
|3 |　　透|あさひ|　雛菜|甘奈
|4 |　雛菜|摩美々|　霧子|小糸
|5 |　霧子|　真乃|めぐる|夏葉
|19|摩美々|　小糸|　愛依|千雪
|20|冬優子|冬優子|智代子|冬優子
|21|　円香|　夏葉|　咲耶|雛菜
|22|　咲耶|　円香|　夏葉|円香
|23|　夏葉|　咲耶|摩美々|透

全体的に納得の結果になっている気がします。
摩美々は信頼度でハッキリと反応が変わっているのが分かりますね。

円香はもちろん、咲耶、夏葉などネガティブなことでもはっきりと言葉にするタイプのアイドルはscoreがマイナス方向に大きくでているようです。

magnitudeに関しても、それなりに納得の順位ではないでしょうか。
智代子がしっかりと感情が豊かというデータが出ていて満足です。
雛菜が低いのが意外ですが、「え～～～？」の様な内容がない台詞が多いので、低い値が出ているようです。

#まとめ
**全人類シャニマスをプレイしてください。**