iOSアプリのレビュー を Amazon Comprehend にかけてみる

## はじめに

[AWSでつくる AIプログラミング入門](https://www.amazon.co.jp/dp/4798059056)を参考にして AWsのAPI系サービスを理解するために、[Amazon Comprehend](https://aws.amazon.com/jp/comprehend/) を試した結果です。

![AWSでつくる AIプログラミング入門](https://images-na.ssl-images-amazon.com/images/I/51YqcibBkYL.jpg)



この記事は Amazon Comprehend の2020年1月11日時点の動作に基づいたものです。

## 感想

- 感情分析 の 混在 / 肯定的 / 否定的 / 中立的 は精度はいい感じ。
- キーフレーズ抽出 は利用用途のアイデア次第。何かに使えそうな予感。
- エンティティ認識 は感情的なネガティブな書き込みが多いレビューには不向きと感じた。
- 構文解析 は日本語に非対応
- カスタムエンティティは日本語に非対応
- カスタム分類子は日本語に非対応

カスタムエンティティもしくはカスタム分類子で日本語を扱えると用途が広がりそう。「AWSでつくる AIプログラミング入門」では日本語を英語に変換することで日本語に非対応の機能を利用していたので、同じ様にするのはアリかもしれない。

## 機能と言語の対応状況

公式ドキュメントの[Languages Supported in Amazon Comprehend](https://docs.aws.amazon.com/comprehend/latest/dg/supported-languages.html#supported-languages-feature)にある通りです。

![supported-languages-feature.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/145742/a8c64a6a-19c1-8d8f-832a-09f13962fc4d.png)

## 書いてみたプログラム

```python
#!/usr/bin/env python
#-*- coding:utf-8 -*-

import boto3
import urllib.request
import sys
import xml.etree.ElementTree as ET

appStoreReviewUrl = "https://itunes.apple.com/jp/rss/customerreviews/id=[アプリID]/sortBy=mostRecent/xml"

def main():
    comprehend = boto3.client('comprehend', 'us-west-2')

    ns = {'atom': 'http://www.w3.org/2005/Atom', 'im': 'http://itunes.apple.com/rss'}
    
    # RSS フィードから直接読み込む
    # feed = ET.fromstring(urllib.request.urlopen(appStoreReviewUrl).read())

    # 保存したファイルから読み込む場合
    feed = ET.parse("app_review.xml").getroot()

    # for entry in feed:
    for entry in feed.findall("atom:entry", ns):
        entry_id = entry.find("atom:id", ns).text
        updated = entry.find("atom:updated", ns).text
        title = entry.find("atom:title", ns).text
        # voteSum = entry.find("im:voteSum", ns).text
        # voteCount = entry.find("im:voteCount", ns).text
        rating = entry.find("im:rating", ns).text
        version = entry.find("im:version", ns).text
        author= entry.find('atom:author', ns).find("atom:name", ns).text
        content_type = entry.find("atom:content", ns).get("type")
        content_text = entry.find("atom:content", ns).text

        print ('{}:'.format(entry_id))
        print ('    version: {}'.format(version))
        print ('    Title  : {}'.format(title))
        print ('    author : {}'.format(author))
        print ('    updated: {}'.format(updated))
        print ('    rating : {}'.format(rating))
        print ('')
        print (content_text)

        print ('')
        print ('detect_sentiment:')
        sentiment_result = comprehend.detect_sentiment( Text = content_text, LanguageCode = 'ja')
        print (sentiment_result['Sentiment'])
        for key, value in sentiment_result['SentimentScore'].items():
            print('    {:10} {}'.format(key, value))

        print ('')
        print ('detect_key_phraes:')
        phrase_result = comprehend.detect_key_phrases ( Text = content_text, LanguageCode = 'ja' )
        report = {}
        for phrase in phrase_result['KeyPhrases']:
            text, score = phrase['Text'], phrase['Score']
            report[text] = '    {:<018} {}'.format(score, text)
        for line in sorted(report.values(), reverse=True):
            print (line)

        print ('')
        print ('detect_entities:')
        entity_result = comprehend.detect_entities ( Text = content_text, LanguageCode = 'ja' )
        for entity in entity_result['Entities']:
            print('    {:>03} {:20} {:20} {:<018}'
            .format(entity['BeginOffset'], entity['Text'], entity['Type'], entity['Score']))


        print ('------------------------------')


if __name__ == "__main__":
    main()
```

Amazonのアプリで取得できた結果から1件だけ抜粋したもの。

```
5384646599:
    version: 15.1.0
    Title  : 少し不便になった
    updated: 2020-01-10T02:37:47-07:00
    rating : 2

絞り込みの際に昔は複数選択した後に検索出来たけどアップデートされてから絞り込みを一つ選択したら直ぐに 検索されるから不便
昔みたいに複数選択してから検索出来る様にして欲しい

detect_sentiment:
NEGATIVE
    Positive   0.0031569302082061768
    Negative   0.8614339828491211
    Neutral    0.1352967917919159
    Mixed      0.00011228274524910375

detect_key_phraes:
    0.9999854564666748 一つ
    0.9999847412109375 後
    0.9999784231185913 絞り込みの際
    0.9999392032623291 絞り込み
    0.9999331235885620 昔
    0.9992663264274597 複数
    0.9427456259727478 不便 昔

detect_entities:
    040 一つ                   QUANTITY             0.7542048692703247
```