ちょっと話題の記事

私の文章が「暗い」かどうかはAmazon Comprehendにハッキリしてもらう ~Analysis jobsで20000字を感情分析してみた~

あかるいぶんしょう くらいぶんしょう そんなの ひとのかって そうはいってもきになるので きかいがくしゅうをつかって しらべてみました
2019.11.13

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

皆さん、元気いっぱいな文章を書いていますか?

▲ 私は最近書けていません!

折角の芸術の秋(まだ秋ですか?)ですし、時には己のリビドーを大爆発させて思いのままに文章を綴るのも良いのではないでしょうか。1年後くらいに恥ずかしくて床を転がるくらいのものがベターです。
何を言っているか分からないと思った皆さんこんにちは。
何を言っているのかが分かってしまった皆さんもこんにちは。AWS事業本部のShirotaです。

自分が元気いっぱいな文章を書けているか気になったらこのまま続けてお読み下さい。
そうでない場合も読んで頂ければ幸いです。
元気に参りましょう!

Amazon Comprehendが日本語対応しましたね

2019年11月6日、Amazon Comprehendが日本語対応したのはまだ記憶に新しいかと思います。
弊社のブログに、分かりやすく今回のアップデートと早速のやってみたが紹介されておりますので併せてご覧下さい。

[アップデート]Amazon Comprehendで日本語テキストの分析ができるようになりました

このアップデートもあり、改めてAmazon Comprehendについて興味が湧きました。
まず、話の前提としての「Amazon Comprehendって何ができるサービスぞ?」という所なのですが、Amazon Comprehendは機械学習を利用した自然言語処理(NLP)ができるサービスです。
できる事の詳細に関しては以下弊社のブログに分かりやすくまとまっているのでそちらも併せてご覧下さい。

自然言語処理サービスの Amazon Comprehend についてまとめてみた #reinvent

簡単にまとめると、機械学習を用いて文章を分析する事により、文章に用いられている単語の種類や重要度、言語の種類、文章に含まれる感情の分析などができるサービスです。
これらは特にユーザー側で設定する事なく、分析したい文章を放り込むとすぐにAmazon Comprehendで分析する事が可能です。勿論、カスタマイズをする事もできるのでコンテキストを学習させたりなどの幅を広げる事も可能です。

さて。今回私は、その中でも「感情の分析」についてAmazon Comprehendを活用してみたいなと思いました。
感情の分析はどのような時に役立つかと言われると、例えば商品のレビューなどの文章を分析する事で、どのような人がその商品に対してどのようなイメージを持っているかと言った事を調査するのに役立ちます。その後のレコメンデーションなどにも繋がって来るかと思われます。
……という、至って真面目かつ有用な利用方法がある機能なのですが、今回はちょっと個人的な検証に利用してみました。

うわっ…私の文章、暗すぎ…?

私は、趣味で文章を書く事があります。
その際に、 どうしても明るくならない事が多いな と感じていました。
まぁ明るくならないのは自分自身の湿地帯のようなパーソナリティーやどんよりとした嗜好が絡んでいる為仕方ないな、と思ってはいたのですがあくまでもこれは感じ方の問題が大きく起因するのではないでしょうか。
つまるところ、「機械学習で分析してみて、自分の文体がどう分析されるか」を見てから自分の文章が本当に暗いのかを考えても良いのではないかと考えた訳です。

簡潔にまとめるとAmazon Comprehendが「明るいね!」と判断すれば「明るいんじゃない?」と主張する事にするし、「暗いわ〜」と言えば「やっぱ暗いのか〜」と納得して生きていく事にしたいと思います。

まずはサクッと感情分析を試す

そもそも、Amazon Comprehendがどのように感情を分析してくれるのかを見る必要があります。
これは、自分の中での感情分析の乖離を測るためです。
例えば、自分の中では「とてもポジティブな気持ちで書いたよ!」と思ったものがAmazon Comprehendに「めっちゃネガティブですね」と言われたら、そもそもの価値観の基準のズレが大きすぎてAmazon Comprehendの分析を参考にする事が難しくなります。それだけズレた人間ではないと信じていますが

今回は、2019年11月13日の時点でAmazon Comprehendが提供されているシンガポールリージョンでAmazon Comprehendを利用してみました。

Real-time anaylysisをやってみる

まずは、文章を短時間で分析してくれるReal-time anaylysisを使ってみました。

ポジティブな文章を分析する

以下の文章を分析してみます。

生ハムの原木かわいいな

「かわいい」というポジティブに捉えられそうな単語が入っているので、この文章はポジティブだと分析される筈です。
実際にやってみた結果が以下になります。

▲ めっちゃポジティブ

ポジティブが0.98と ほぼ1に近い 値をだしています。
また、ニュートラルが僅かに0.01、ネガティブに至っては0.00でMixed(上記三つに分類されない、「複雑な」感情の区分)も0.00であり、ここからも すこぶるポジティブな文章である事が分かります

ネガティブな文章を分析する

以下の文章を分析してみます。

インフルの注射やだ!!!!!!!!!!!!!!!!!!!!!やだ!!!!!!!!!!!!!!去年痛かった!!!!!!泣いた!!!!やだぁ!!!!!!!!!!!

エクスクラメーションがうっとおしいですが、とにかくネガティブだと思われる文章です。
「やだ」「痛かった」「泣いた」辺りからぶっちぎりネガティブだと分析されると思います。
実際にやってみた結果が以下になります。

▲ ネガティブの権化

今度は、先ほどとは対照的にネガティブが0.91で大半を占めました。
ニュートラルが残りのほとんどである0.08で、ポジティブとMixedが0.00と、 ネガティブを煮詰めた文章である事が分かりました 。インフルエンザの注射、嫌です。

ニュートラルな文章を分析する

以下の文章を分析してみます。

コンビニプリンにスティックシュガーを振りかけ、ライターで炙ると自宅でクレームブリュレの上に乗っているパリパリカラメルジェネリックのようなものが食べられます。暇な人はお試しあれ

ニュートラルな文章とは、感情の入る余地が少ない説明などの文章が該当するのではないか?と考えてやってみました。 実際にやってみた結果が以下になります。

▲ 想定通り、良い感じにニュートラル

ニュートラルが大半の0.96を占めました。
ポジティブが0.03でネガティブも0.00、Mixedも0.00の為、これは良い感じに感情の振れ幅がない文章なのではないでしょうか。すごくクレームブリュレが食べたかった時にしてはニュートラルな文章でした。

少し長めの文章たちをAnalysis jobsで分析する

まずは短文をReal-time anaylysisで分析してみました。
次に、今までより長めの文章を分析させたいと思います。
今回の本題である「自分の文章」の感情分析をやります。

▲ 既に色々「重たい」

複数の文章をまとめて分析させる場合は、 Analysis jobs を使うと便利です。

まずは、20000字強のテキストを分割し、分割したファイルを任意のS3の配下にまとめます。

▲ 分けても多い

ここでテキストファイルについては注意する事が2点あり、
- 各ファイルのテキストデータは5000バイト未満にしておく
- エンコードはUTF-8

という条件が必要になります。
この条件に関しては公式ガイドに、以下のような記載があります。

Text A UTF-8 text string. Each string must contain fewer that 5,000 bytes of UTF-8 encoded characters.
Type: String
Length Constraints: Minimum length of 1.
Required: Yes

DetectSentiment

ややこしい事に、Real-time anaylysisの文章を入力する欄の下部には5000文字のカウンターが表示されています。
ですが、ここで 日本語で 5000文字分の文章を入力すると、以下のようなエラーが出ます。

▲ めっちゃオーバーしてる

日本語が大体3バイトで句読点が2バイトと考えると、正確には文字数ではなくバイト数で計算している事が分かります。
また、ファイルのバイト制限をオーバーしてジョブを実行した場合には以下のようなエラーが出ます。

▲ テキスト5000バイト+1レコード分の120バイトで5120バイトになっていると思われる

次に、ジョブの設定を行います。

まずは、ジョブの名前・分析するタイプ・言語を設定します。
Real-time anaylysisと違い、 分析するタイプと言語を設定してあげる必要があります。

▲ 今回は感情を分析したいのでSentimentを選択

オプションで、ジョブの暗号化を設定することもできます。

次に、インプットするデータを選択します。
英語だとサンプルの文章も選択できるようです。
今回は、用意したテキストファイルのあるフォルダをファイルごとに分析するように設定しました。

▲ 1行ごとの文章の分析もできる

分析結果をアウトプットするS3の場所も指定します。ここも、暗号化する事が可能です。

インプットとアウトプットでS3への操作をする為、Amazon Comprehend用のIAMRoleが必要になります。
元々用意できていた場合はそのIAMRoleを指定する事ができ、新たにIAMRoleを作成する事も可能です。

▲ ロールの接尾辞を入力する

参考までに、上記で作ったIAMRoleは以下のようになっていました。

▲ Amazon Comprehend用

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
                "s3:GetObject"
            ],
            "Resource": [
                "arn:aws:s3:::test-comprehend-201911/*"
            ],
            "Effect": "Allow"
        },
        {
            "Action": [
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws:s3:::test-comprehend-201911"
            ],
            "Effect": "Allow"
        },
        {
            "Action": [
                "s3:PutObject"
            ],
            "Resource": [
                "arn:aws:s3:::test-comprehend-201911/*"
            ],
            "Effect": "Allow"
        }
    ]
}

オプションで、VPCを指定する事ができます。
今回は特に指定していないのですが、VPCを設定する事によってS3とAmazon Comprehend間の通信をAWS内で完結させる事ができ、よりセキュアにサービスを利用する事ができるようになります。

Amazon Comprehend のバッチジョブで Amazon Virtual Private Cloud のサポートを開始

分析結果

上記の設定で、ジョブを作ってみました。

▲ 5分足らずで分析が終わった。重たくないですね!

分析結果は、Outputの欄にリンクが貼ってあるのですぐにダウンロードしにいけます。
さて、気になる分析結果は以下のようになりました。

{"File": "ss1-1.txt", "Sentiment": "NEGATIVE", "SentimentScore": {"Mixed": 0.0003575540613383055, "Negative": 0.5195407867431641, "Neutral": 0.22960934042930603, "Positive": 0.25049227476119995}}
{"File": "ss1-2.txt", "Sentiment": "NEUTRAL", "SentimentScore": {"Mixed": 0.0008225794299505651, "Negative": 0.014718678779900074, "Neutral": 0.8301620483398438, "Positive": 0.15429677069187164}}
{"File": "ss10-1.txt", "Sentiment": "POSITIVE", "SentimentScore": {"Mixed": 0.011807125993072987, "Negative": 0.049472905695438385, "Neutral": 0.1053217202425003, "Positive": 0.8333982229232788}}
{"File": "ss11-1.txt", "Sentiment": "NEGATIVE", "SentimentScore": {"Mixed": 0.000987705308943987, "Negative": 0.8080809712409973, "Neutral": 0.15175016224384308, "Positive": 0.03918112814426422}}
{"File": "ss11-2.txt", "Sentiment": "NEGATIVE", "SentimentScore": {"Mixed": 0.0052656084299087524, "Negative": 0.5076167583465576, "Neutral": 0.3121073246002197, "Positive": 0.17501021921634674}}
{"File": "ss12-1.txt", "Sentiment": "NEUTRAL", "SentimentScore": {"Mixed": 0.00012602329661604017, "Negative": 0.09212929010391235, "Neutral": 0.8758189678192139, "Positive": 0.0319257415831089}}
{"File": "ss12-2.txt", "Sentiment": "NEGATIVE", "SentimentScore": {"Mixed": 0.00016779669385869056, "Negative": 0.560806393623352, "Neutral": 0.3309524357318878, "Positive": 0.10807337611913681}}
{"File": "ss13-1.txt", "Sentiment": "POSITIVE", "SentimentScore": {"Mixed": 1.8348746380070224e-05, "Negative": 0.2616693377494812, "Neutral": 0.069643534719944, "Positive": 0.6686687469482422}}
{"File": "ss13-2.txt", "Sentiment": "POSITIVE", "SentimentScore": {"Mixed": 0.0146995410323143, "Negative": 0.27028393745422363, "Neutral": 0.35428377985954285, "Positive": 0.36073270440101624}}
{"File": "ss14-1.txt", "Sentiment": "NEGATIVE", "SentimentScore": {"Mixed": 0.00016070136916823685, "Negative": 0.9696281552314758, "Neutral": 0.023434273898601532, "Positive": 0.006776872090995312}}
{"File": "ss14-2.txt", "Sentiment": "NEGATIVE", "SentimentScore": {"Mixed": 0.1434447169303894, "Negative": 0.7733371257781982, "Neutral": 0.04313770309090614, "Positive": 0.04008043557405472}}
{"File": "ss15-1.txt", "Sentiment": "POSITIVE", "SentimentScore": {"Mixed": 0.00014548520266544074, "Negative": 0.3432433009147644, "Neutral": 0.09023992717266083, "Positive": 0.5663712024688721}}
{"File": "ss2-1.txt", "Sentiment": "POSITIVE", "SentimentScore": {"Mixed": 0.0007815341232344508, "Negative": 0.2801942229270935, "Neutral": 0.26950663328170776, "Positive": 0.4495176076889038}}
{"File": "ss3-1.txt", "Sentiment": "POSITIVE", "SentimentScore": {"Mixed": 0.0002845681447070092, "Negative": 0.3956320285797119, "Neutral": 0.104324109852314, "Positive": 0.499759316444397}}
{"File": "ss4-1.txt", "Sentiment": "NEGATIVE", "SentimentScore": {"Mixed": 0.00010147953435080126, "Negative": 0.9187396168708801, "Neutral": 0.033565789461135864, "Positive": 0.047593098133802414}}
{"File": "ss5-1.txt", "Sentiment": "NEGATIVE", "SentimentScore": {"Mixed": 0.0006797260721214116, "Negative": 0.4080265164375305, "Neutral": 0.23661746084690094, "Positive": 0.3546762764453888}}
{"File": "ss5-2.txt", "Sentiment": "POSITIVE", "SentimentScore": {"Mixed": 2.693852366064675e-05, "Negative": 0.007345946040004492, "Neutral": 0.0076324837282299995, "Positive": 0.9849945902824402}}
{"File": "ss6-1.txt", "Sentiment": "NEGATIVE", "SentimentScore": {"Mixed": 0.020605891942977905, "Negative": 0.8465614318847656, "Neutral": 0.018544329330325127, "Positive": 0.1142883226275444}}
{"File": "ss7-1.txt", "Sentiment": "NEGATIVE", "SentimentScore": {"Mixed": 0.0007003318751230836, "Negative": 0.7054428458213806, "Neutral": 0.262533575296402, "Positive": 0.03132328391075134}}
{"File": "ss8-1.txt", "Sentiment": "MIXED", "SentimentScore": {"Mixed": 0.8548907041549683, "Negative": 0.006573369260877371, "Neutral": 0.12070000916719437, "Positive": 0.017835915088653564}}
{"File": "ss9-1.txt", "Sentiment": "NEGATIVE", "SentimentScore": {"Mixed": 0.000423750898335129, "Negative": 0.9410349130630493, "Neutral": 0.04943814128637314, "Positive": 0.009103151969611645}}

コンソールで感情分析をした時には丸められてしまう値や、どの感情の値が一番大きかったかなども分かるようになっています。すごい。

今回分析したテキストファイルは21個中、

  • ポジティブ: 7
  • ネガティブ: 11
  • ニュートラル: 2
  • Mixed: 1

となりました。Mixedが一番多かった文章があったのですが、そんな複雑な物を記述した記憶がないのでびっくりです。
自分で思っていたよりも案外ポジティブじゃないの!とはしゃいでいたのですが、一番ポジティブが多かった文章でも、以下のようなデータが出ていたりしました。

{"File": "ss13-2.txt", "Sentiment": "POSITIVE", "SentimentScore": {"Mixed": 0.0146995410323143, "Negative": 0.27028393745422363, "Neutral": 0.35428377985954285, "Positive": 0.36073270440101624}}

ポジティブが約0.36だったのですが、 ニュートラルが0.35・ネガティブが0.27 と中々に拮抗している中でポジティブが一番多かっただけだったりするケースもありました。突き抜けてポジティブじゃないオチ。

その辺をざっくり無視して考えてみると、ネガティブが一番強い文章が 全体の52.4パーセント程 存在していた事が分かりました。 半分を多いと捉えるか少ないと捉えるかは人次第ですかね

ありがとうAmazon Comprehend

分析の結果、2回に1回くらいしか自分が「暗い」文章を書いていない事が明るみに出ました。
ありがとうAmazon Comprehend。主観より明るい人間だと示してくれて。

また、20000字強あった文章も5分足らずで分析できる事が分かり、これは文章の分析が捗るなと思いました。
いずれはこれらの分析を元に、自分らしい文章を自動で生成してくれるようになったら色々楽になるし何もしなくても良くなるなのではないでしょうか。

自分の文章が「明るい」か「暗い」か、気になった方は是非、日本語対応したAmazon Comprehendをお試し下さい。