世界で一番ポジティブな文章を見つけ出す

[Ateam Lifestyle Advent Calendar 2020](https://qiita.com/advent-calendar/2020/ateam-lifestyle)の24日目は、
株式会社エイチームライフスタイル WEBエンジニア @masatomasto124 が担当します！

## はじめに

先日、エイチームグループ全体でハッカソンが開催されました。
私もエンジニアとして参加しており、`Google Natural Language API`に触れる機会がありました。
その際に生じた疑問の解消が今回のテーマです。

## Google Natural Language APIとは?

`Google Natural Language API`は、Googleが提供している機械学習を使用した自然言語処理を行うAPI郡です。 
学習済みのモデルがすでに用意されているので機械学習の専門知識がなくてもお手軽に利用することが出来ます。 
こちらには様々な機能が用意されていますが、ハッカソンで利用したのは`analyzeSentiment`という感情分析を行うメソッドです。 `analyzeSentiment`は文章を解析して、文章全体の感情(`score`)と感情の強さ(`magnitude`)を数値化してくれるものです。

### APIレスポンス

  ```json
  {
    "documentSentiment": {
      "score": 0.2,
      "magnitude": 3.6
    },
    ...
  ```

### レスポンスフィールドの説明

  >
  >・score: -1.0（ネガティブ）～1.0（ポジティブMAX）のスコアで感情が表されます。これは、テキストの全体的な感情の傾向に相当します。
  >・magnitude: 指定したテキストの全体的な感情の強度（ポジティブとネガティブの両方）が 0.0～+inf の値で示されます。
  >

## 本題

レスポンスフィールドの説明を読んだとき、私に電流が走りました。
`score`が`1.0（ポジティブMAX）`で`magnitude`が`+inf`になるの文章。。。それすなわち「世界で一番ポジティブな文章」と言えるのではいか？そして「世界で一番ポジティブな文章」を見つけ出し公開することで、世界から争いがなくなり、平和が訪れるのではないか？

かなり前置きが長くなってしまいましたが今回やることは。。。

**『世界で一番ポジティブな文章を見つけ出す！』**

です！！！

## 仕様の理解

何はともあれ、まずは仕様の理解から。。。[公式サイト](https://cloud.google.com/natural-language/docs/basics?hl=ja#sentiment_analysis)を覗いてみます。

何やら`magnitude`に関して気になる記述がありました。

+ [感情のレスポンスフィールド](https://cloud.google.com/natural-language/docs/basics?hl=ja#sentiment_analysis_response_fields)

  >テキスト内で感情（ポジティブとネガティブの両方）が表現されるたびにテキストの magnitude の値が増加しま>す。そのため、長いテキスト ブロックで値が高くなる傾向があります。

+ [感情分析の値の解釈](https://cloud.google.com/natural-language/docs/basics?hl=ja#interpreting_sentiment_analysis_values)

  >ドキュメントの感情分析の magnitude は、そのドキュメントに感情的な内容がどのくらい含まれているかを示します。この値は、ドキュメントの長さに比例する傾向があります。

ふむふむ。。。`magnitude`の値には`文章の長さ`が関係してくる。そして、`感情表現`の`回数`も影響する。。。  
私に電流が走りました。
『`score`が`1.0`となる表現を見つけ、その表現を繰り返すことで`magnitude`が`+inf`になるのではないか？』
方針が決まりました。

## 整理

方針が決まったところで今回の目標である『世界で一番ポジティブな文章を見つけ出す』を達成するために必要な条件を整理してみます。

  1. `score`が`1.0（ポジティブMAX）`となる表現を見つけること
  2. `magnitude`が`+inf`となる回数を見つけること

以上の2つを順にクリアして行きたいと思います。

## scoreが1.0となる表現を探す

一旦、デモサイトを使って`score`が`1.0（ポジティブMAX）`となる表現を見つけていこうと思います。

```
# 入力 文章
私は今までになく最高に幸せです。

# 結果
"score": 0.9
"magnitude": 0.9
```

```
# 入力 文章
I am extremely happy.

# 結果
"score": 0.9
"magnitude": 0.9
```

・・・見つからん。

上記以外にも幾つか試して見ましたが、なかなか見つかりません。  

しばらくして、私に電流が走りました。
『感情を含む文章データを集めて、`Google Natural Language API`を叩きまくればいい！』

## APIの利用料金について

「APIを叩きまくればいい！」と思ったものの、後先考えずにAPIを叩きまくると破産します。 
というわけで、先に利用料金を調べます。

[公式サイト](https://cloud.google.com/natural-language/pricing?hl=ja#pricing_units)を覗いて見ます。

>分析のためにこの API に送信される各ドキュメントのユニット数は、少なくとも 1 ユニットとなります。ドキュメントに 1,000 文字を超える Unicode 文字が含まれている場合（空白文字や、HTML / XML タグなどのマークアップ文字も含まれます）、複数ユニット（1,000 文字 = 1 ユニット）としてカウントされます。
>...
>略
>...
>Natural Language の使用料は、使用された API の機能とその機能を使用して評価されたユニットの数に基づいて、月単位で計算されます。次の表に、請求月に分析されたユニットの総数に基づく 1,000 ユニットあたりの料金を示します。

| 機能                 | 0～5,000 | 5,000～1,000,000 | 1,000,000～5,000,000 | 5,000,000～20,000,000 |
| -------------------- | -------- | ---------------- | -------------------- | --------------------- |
| 感情分析             | 無料     | $1.00            | $0.50                | $0.25                 |

なるほど。。。1,000文字 = 1ユニットとして月額計算がなされる。
そして、毎月5000ユニットまでは無料。5000ユニットを超えると、1000ユニット単位で課金されていく。

ここでざっと計算、私にはGPCの無料クレジットが31,279円残っています。
大体、300,000ユニットは無料で実行できそうです。 
※ 1ドル = 103.61 円

## データ収集

感情を含む文章データを集める為にWEBサイトをクローリングしようかとも考えましたが、すでにデータがあるのでは？とGoogleさんにお伺いすると。。。  
見つかりました！！

<http://ai.stanford.edu/~amaas/data/sentiment/>

なにやら、約25,000件の映画レビューが含まれているとのこと。 
ダウンロードしたデータセットの中からポジティブなレビューを使用して`Google Natural Language API`を可能な限り叩いていこうと思います。

## 下準備

レビューの評価が高く、且つ、文章量が多ければポジディブな表現が見つかりやすいのではと考えました。 
そのため下準備として以下の条件でレビューをソートします。

1. レビューの評価
2. ファイルサイズ

## いざ、分析！しかし

ソート結果を50件単位で感情分析にかけていきます。 
`crul`コマンドでAPIにアクセスして結果をテキストファイルにリダイレクトさせます。 
そしてすべて終わったところで、`grep`で検索を行っていきます。

まずは、上位50件を感情分析にかけます。

```sh
crul ...
...
grep '"score": 1.0' *txt
```

見つかりません。。。気を取り直して次の50件！

```sh
crul ...
...
grep '"score": 1.0' *txt
```

見つかりません。。。気を取り直して一気に100件いってみよう！

```sh
crul ...
...
grep '"score": 1.0' *txt
```

見つかりません。。。気を取り直して次の(略

しばらくして。。。私に電流が走りませんでした。  

## まとめ

その後も分析を続け約4700件のレビューを試しましたが、`score`が`1.0（ポジティブMAX）`になる表現を見つけることできませんでした。 
どうやら今の私の力では（技術力 + 財力）では『世界で一番ポジティブな文章』を見つけることは叶わないようです。
しかし、まだ挑戦は始まったばかりです！この先も挑戦を続けいつの日か『世界で一番ポジティブな文章』を見つけて公開したいと思います！！