Amazon Aurora MySQL 5.7 互換版で Comprehend 感情分析を試してみる

昨年の **[JAWS-UG 名古屋 AWS re:Invent2019 大復習（＋忘年会）](https://jawsug-nagoya.doorkeeper.jp/events/100999)**で**「RDS / Aurora 関連アップデート」**と題して LT 登壇をしたのですが、その中で表題の内容についても触れました。

 - **[RDS / Aurora 関連アップデート \[4-1\] Aurora Machine Learning](https://speakerdeck.com/hmatsu47/aurora-guan-lian-atupudeto?slide=11)（Speaker Deck）**
   - スライドのページタイトル、Typo してて恥ずかしい

本日、JAWS DAYS 2020 オンラインライブ視聴の裏側で**「[JAWS DAYS 2020 [オンラインハンズオン] はじめての自然言語処理（NLP） powered by LINE API Expert](https://jaws-ug.doorkeeper.jp/events/105090)」**が行われていたことで冒頭の LT 登壇を思い出したので、今回は日本語を使って試してみました。

---

**【参考リンク】**

 - **[Amazon Aurora の新機能 – データベースから直接機械学習を使用する](https://aws.amazon.com/jp/blogs/news/new-for-amazon-aurora-use-machine-learning-directly-from-your-databases/)（Amazon Web Services ブログ）**
 - **[Using Machine Learning (ML) with Aurora MySQL](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/mysql-ml.html)（AWS Documentation）**

# 1. 準備

今回は表題のとおり Aurora MySQL 5.7 を使います（現在は PostgreSQL 互換版でも使えるようになっているようです）。

まずは IAM ロールを Aurora クラスターに追加します。
![ac01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123899/82d82738-43f8-6e49-3c22-5071beb746ac.png)
※この記事を書いている時点ではまだプレビュー中です。
![ac02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123899/e35977c8-12fe-5862-611a-31e8c4aa7fe4.png)
追加されました。
![ac03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123899/c27dd322-3f63-6ae0-d35d-aef3b11dc0c6.png)
そして、IAM でこのロールの ARN を調べます。
![ac04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123899/514a410b-a81c-c836-594c-40f47fdc9192.png)
![ac05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123899/ecf7aa23-6620-3751-5324-feb0de166fea.png)
Aurora のクラスターパラメータグループ（なければ新規作成）で`aws_default_comprehend_role`にさきほどの ARN を設定します。
![ac06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123899/f5cdb8da-ef55-2e2f-2bc2-edef1e2950a8.png)
このクラスターパラメータグループを対象の Aurora クラスターに適用します。
![ac07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123899/97548ba9-6c9b-f5f4-e404-fec034e4bca4.png)
なお、これらのほかに、以下のいずれかが必要です（Aurora から Comprehend にリクエストを送るため）。

 - NAT ゲートウェイの設置＋Aurora クラスター（各ノード）からのルーティング
 - パブリックアクセス有効化

今回はテストのためパブリックアクセスを有効化しています。
![ac08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123899/8a979dc7-d894-80ed-2d67-97a267aecdba.png)

# 2. 試してみる

わたし自身が年末年始に 2019 年の振り返りと 2020 年の抱負として書いた、以下の Qurnch 記事の文章から、セクションごとの文章について感情分析を行ってみます。

 - **[ちょっと早いけど 2019 年を振り返る](https://hmatsu47.qrunch.io/entries/BJSxQ19Dpt073VJk)（Qrunch）**
 - **[2020 年、今年は何をする？](https://hmatsu47.qrunch.io/entries/IFzHGfSqONQGUQZ0)（Qrunch）**

まずデータベース・テーブルを用意します。

```sql:DB・テーブル定義
mysql> CREATE DATABASE mltest CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;
Query OK, 1 row affected (0.01 sec)

mysql> USE mltest;
Database changed
mysql> CREATE TABLE sentiment_test (
    ->   id INT AUTO_INCREMENT PRIMARY KEY,
    ->   heading VARCHAR(100),
    ->   analyze_text VARCHAR(500)
    -> );
Query OK, 0 rows affected (0.03 sec)
```

まず、2019 年の振り返りについてデータを挿入していきます。

```sql:2019年データ挿入
mysql> INSERT INTO sentiment_test SET
    ->   heading='引っ越し',
    ->   analyze_text='たぶん驚かれるでしょうが、まだ終わってません（笑）。早い 時期に今年中の旧居撤収は諦めました。なぜか…は続きを読んでいただければ、大体 像 がつくかと。';
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO sentiment_test SET
    ->   heading='SRE 活動',
    ->   analyze_text='はい、こちらも一旦頓挫しました。やはり「兼業 SRE」は無理 があります。メンバーが落ち着いて勉強する余裕などありませんでした。途中で「再起動」したものの、前途多難であります。';
Query OK, 1 row affected (0.04 sec)
（以降省略）
```

分析結果を見てみます。

```sql:2019年分析結果
mysql> SELECT heading,
    ->   aws_comprehend_detect_sentiment(analyze_text, 'ja') AS sentiment,
    ->   aws_comprehend_detect_sentiment_confidence(analyze_text, 'ja') AS confidence FROM sentiment_test;
+-----------------------------------------------------------------+-----------+--------------------+
| heading                                                         | sentiment | confidence         |
+-----------------------------------------------------------------+-----------+--------------------+
| 引っ越し                                                        | NEUTRAL   | 0.9790685176849365 |
| SRE 活動                                                        | NEGATIVE  | 0.9979338645935059 |
| 登録セキスペ                                                    | NEUTRAL   | 0.9953206181526184 |
| その他の資格・検定関連                                          | NEGATIVE  | 0.9806546568870544 |
| IT イベント・カンファレンス・勉強会への参加                     | NEUTRAL   | 0.9641426801681519 |
| 各種アウトプット                                                | NEUTRAL   | 0.9664930701255798 |
| MySQL（Aurora MySQL 互換含む）に関する技術                      | NEUTRAL   | 0.9988293051719666 |
| MySQL 以外のデータストアに関する技術                            | NEGATIVE  |  0.968559741973877 |
| AWS 環境のアカウント分離                                        | MIXED     | 0.8833306431770325 |
| まとめ                                                          | NEUTRAL   | 0.9767121076583862 |
+-----------------------------------------------------------------+-----------+--------------------+
10 rows in set (0.34 sec)
```

うっ、NEGATIVE が多い…。しかも confidence の値も高いので、自信を持って（？）判定されてるようです。

気を取り直して、今度は 2020 年の抱負で試してみます。

```sql:2020データ挿入
mysql> TRUNCATE TABLE sentiment_test;
Query OK, 0 rows affected (0.03 sec)

mysql> INSERT INTO sentiment_test SET
    ->   heading='引っ越し',
    ->   analyze_text='2018 年の 10 月に引っ越しました…引っ越したはず…ですが、まだ旧居の片づけが終わらず。早く片付けねば…とは思うものの、今年もプライベートの時 間が忙しくなりそうなので、無理せず少しずつ進めます。';
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO sentiment_test SET
    ->   heading='会社の SRE 活動',
    ->   analyze_text='メンバー再構成で再起動はしたものの、相変わらず兼業メンバ ーばかりなので、うまくいくイメージが全く持てません（笑）。ただ、「SRE」という名 称にこだわらず、地道な改善を足掛かりにサイト（サービス）の信頼性を確保する（確保しつつスケールさせていく）意識は一部の参加メンバーのおかげで少しずつ定着しつつあるので、1 年では難しいと思いますが地道にやっていきます。とりあえず、1/25 は SRE NEXT 2020 に参加します。※個人スポンサーのところに紛れ込んでいます。';
Query OK, 1 row affected (0.04 sec)
（以降省略）
```

分析結果を見てみます。

```sql:2020年分析結果
mysql> SELECT heading,
    ->   aws_comprehend_detect_sentiment(analyze_text, 'ja') AS sentiment,
    ->   aws_comprehend_detect_sentiment_confidence(analyze_text, 'ja') AS confidence FROM sentiment_test;
+-----------------------------------------------------------------+-----------+--------------------+
| heading                                                         | sentiment | confidence         |
+-----------------------------------------------------------------+-----------+--------------------+
| 引っ越し                                                        | NEUTRAL   | 0.8793296813964844 |
| 会社の SRE 活動                                                 | NEUTRAL   | 0.5283552408218384 |
| 登録セキスペ                                                    | NEUTRAL   | 0.9994049072265625 |
| その他の資格・検定関連                                          | NEUTRAL   | 0.9416397213935852 |
| IT イベント・カンファレンス・勉強会への参加                     | NEUTRAL   | 0.8604051470756531 |
| 各種アウトプット                                                | NEUTRAL   | 0.9865009188652039 |
| 技術的なものへの取り組み                                        | NEUTRAL   | 0.9960585832595825 |
| さいごに                                                        | NEUTRAL   | 0.9857586622238159 |
+-----------------------------------------------------------------+-----------+--------------------+
8 rows in set (0.42 sec)
```

NEGATIVE はなくなりましたが、POSITIVE もまったくない NEUTRAL おじさんと判定されてしまいました。

---

LT ではネタ的に扱ってしまいましたが、分析基盤から SQL で蓄積データの取り込みと同時に Comprehend を呼び出すことで効率的な分析ができるようになります。

ただし、調子に乗って使っているうちに課金が積み上がる可能性がありますので、ご利用は計画的に…。