AutoMLで文学作品（日本語）の分類をしてみた

（[ブログ記事](https://mhiro216.hatenablog.com/entry/2019/08/05/192000)からの転載）

[先日の記事](https://mhiro216.hatenablog.com/entry/2019/08/01/224453)で、創業記念で打ち出そうと考えているデータサイエンスコンペティションのアイデアをご紹介しましたが、

Googleの[AutoML Natural Language](https://cloud.google.com/natural-language/automl/docs/?hl=ja)が一応日本語の自然言語分類にも対応しているとのことで、同様のデータを元手に試してみました。

正確には、[ドキュメント](https://cloud.google.com/natural-language/automl/docs/languages)に以下の記載があり、

> AutoML Natural Language では現在、英語のテキストの分類がサポートされています。他の言語のテキストを使用してカスタムモデルをトレーニングすることはできますが、モデルのパフォーマンスは定まっていません。

現時点ではベータ版での利用と考えるべきですが、兎にも角にも試してみます。

### トレーニング

カスタムでモデルを作ることができるのはテキスト分類、エンティティ抽出、感情分析の3つです。
<img width="831" alt="スクリーンショット 2019-08-05 18.12.37.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122973/4eca2eb5-08e5-782e-601b-01eefd0c82f5.png">
今回は左上のテキスト分類を行います。
タスクとしてSingle-label Classification, Multi-label Classification, Sentiment Analysisの3種類から選べます。今回はSingle-label Classificationを行います。

まずはトレーニングデータをuploadします。uploadが完了すると、以下の状態になります。
<img width="1100" alt="スクリーンショット 2019-08-05 18.13.12.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122973/c4035c6b-08a7-c7d1-f778-8f5c4073d5b4.png">
トレーニングデータ投入時の注意点は以下２点でしょうか。

- 投入するCSVデータは説明変数となるtextとtargetの2列のみから成る必要がある（行idなどが入っているとエラーを吐き出す）
- textが長すぎるとエラーとなりその行は無視される（"The inline document content length exceeds the 128k character limit. The content was truncated."と怒られる）

今回はtextが文学作品の本文になるので、特に2点目のエラーの発生が避けられず、[先日の記事](https://mhiro216.hatenablog.com/entry/2019/08/01/224453)とapple to appleの比較にはなっていません。

しかし細かいことは無視して、トレーニングを開始します（こういうところを強引に突き進めるのがAutoMLの強みのはず！）。

### 評価（バリデーションデータ）

トレーニングは１時間ほどで完了しました。
最近の大手ITベンダーの提供する機械学習系APIによるトレーニングとの比較で言うと遅い感覚もありますが、それだけモデルやパラメタのチューニングに時間をかけていると想像します。

評価指標は今はprecisionとrecallしか表示されません。F1値すら表示されませんが、これらもいずれ対応してくるでしょう。
バリデーションデータに対する評価結果は以下の通り。
<img width="879" alt="スクリーンショット 2019-08-05 14.01.28.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122973/cfe517c6-e221-19cf-bee0-ef587308f58c.png">
precision, recallともに97.923%、つまりF1値としても97.923%…
タスクが簡単なのもありますが、恐るべき精度の高さです。

### 評価（テストデータ）

一縷の望み？として、過学習の可能性が残されています。
モデルをAPI Callして推論を行うことができるので、テストデータに対して推論を行なってみます。

推論を行うスクリプトを作成するにあたりサービスアカウントキーを発行する必要があります。
発行したキーの参照方法をググると、キーファイルのjsonへの参照を行うのに、環境変数に書き込むかスクリプト中に直書きするかの2つの方法が示されていますが、
自分はいずれもうまくいかず、以下スクリプトでようやく動きました。

```python
from google.cloud import automl_v1beta1
from google.oauth2 import service_account

KEY_FILE = '{your json}'
credentials = service_account.Credentials.from_service_account_file(KEY_FILE)

def get_prediction(content, project_id, model_id):
    prediction_client = automl_v1beta1.PredictionServiceClient(credentials=credentials)

    name = 'projects/{}/locations/us-central1/models/{}'.format(project_id, model_id)
    payload = {'text_snippet': {'content': content, 'mime_type': 'text/plain' }}
    params = {}
    request = prediction_client.predict(name, payload, params)
    return request

get_prediction({your content}, {your project_id},  {your model_id})
```

responseは以下のような形式で返ってきます。

```
payload {
  classification {
    score: 0.9998164772987366
  }
  display_name: "0"
}
payload {
  classification {
    score: 0.0001835411530919373
  }
  display_name: "1"
}
```

パッと見jsonな、このresponseの料理の仕方は、以下記事に詳しいので参照ください。

[https://qiita.com/iss-f/items/fcc766fca27f3685025d]

このスクリプトをテストデータ1405件に対して走らせます。
テストデータについて、Confusion Matrixを得た結果は以下の通り。
![confusion_matrix_automl.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122973/481cd6d0-d3c7-4d74-e8a2-e3438e3a9377.png)
F1値は0.907でした。
過学習はあまり認められません。AutoML、お見事です。

### まとめ

構造化データに対する高い精度で世間を賑わせているAutoMLですが、非構造化データである自然言語に対しても相当なパフォーマンスを発揮することが分かりました。

世間では、今後データサイエンティストの主な仕事は、ビジネス課題をAutoMLなどのソリューションに結びつけることにシフトしていく、などと言われていますが、
<b><font color="Red">んなこたぁ何年も前から分かってる</font></b>ことなので、モデル構築以降のフェーズでデータサイエンティストが出せる価値は何かについて、もっと考察を深めたいと思います。
考察は、行う前に前提条件を確認しておくことが必須なので、現在地点としてAutoMLのパフォーマンスについて確認してみました。

非構造化データシリーズということで、次は画像についても確認したいと思います。