🌐

日本語文章の感情分析APIをつくる

2021/12/27に公開

こんばんは、寒いですね
さすがに故郷は真っ白に染まっているようです
久しぶりに帰りたくなりますね

さて、年末年始と呼ばれる期間に突入してますが皆さんいかがお過ごしですか?
「年末年始、時間あるからなにかやってみたいんだよな」
そう考えてる方にちょうどいい(と思ってもらえそうな)ものを用意しました!

日本語文章の感情分析APIをつくる

というわけで本題です。
今回は日本語の文章の感情を分析するモデルを作成→デプロイしてAPIとして利用できるようにしてみよう、という話です。
ちなみに「APIまではちょっと…」という方も、モデル作成して推論結果を見るところまででも楽しめると思うので是非に。

まあ感情分析と言ってもよくあるネガティブ・ポジティブ・ニュートラルの分析です。
COTOHA APIの感情分析みたいなものを自分でつくってみましょう、という話ですね。
余談ですがCOTOHA API大好きです。こんなお手軽にいろいろなタスクが実行できるのは素晴らしいと思います。

モデルをつくる

なにはともかく、感情分析用のモデルを作成しないと始まらないですね。
https://github.com/ken11/albert-japanese-sentiment-analysis/blob/master/Create-sentiment-analysis-model.ipynb

作成方法はこちらにまとめました。
いくつか大事なポイントを解説しておきます。

ALBERT

最終的にLambdaで動かすこともふまえて、今回はこの前つくったALBERTのモデルをベースにファインチューニングしています。
お好みで他のモデルも試すとよいかと思います。

文章の感情分析タスクはtransformersでは AlbertForSequenceClassification のように 〇〇ForSequenceClassification になります。(文章分類タスクになる)

学習データ

上記ノートブックでは、学習データに株式会社リクルートが提供する"Japanese Realistic Textual Entailment Corpus" (https://github.com/megagonlabs/jrte-corpus)を利用する方法を紹介しています。
このデータセットライセンスは CC BY-NC-SA 4.0 なので営利目的には利用できません。
(あくまで勉強用のサンプルノートブックなのでこちらのデータセットを使うやり方で紹介させてもらいました)

参考: 林部祐太.知識の整理のための根拠付き自然文間含意関係コーパスの構築.言語処理学会第26回年次大会論文集,pp.820-823. 2020. (NLP 2020)[PDF][Poster]

営利目的に今回のようなことをやりたい場合は別途データセットを探してください。
自分でアノテーションして学習データセットを作成するのもよいかと思います。

その他

ほかには特に大きなポイントはない(というかいつも通りのTraining)と思ってますが、細々したところだと次の辺りでしょうか

  • data_collatorは自前で用意します
  • あとで使うとき面倒なのでTokenizerもモデルと一緒にsaveします
  • max_length は今回128にしちゃいましたが、ベースになってるモデルは512まで食えるので、お好みで変更してください

学習が終わったら推論してみてください。
それっぽい結果が出ると思います。

Lambdaにデプロイする

さて、できあがったモデルをLambdaにデプロイしてみます。
流れとしては、モデルをDockerイメージに入れておいて、そのイメージでLambda関数を作成します。

docker build & push ECR

Dockerfilelambda_function.py はこちらに置いてます。
https://github.com/ken11/albert-japanese-sentiment-analysis/tree/master/lambda

Lambdaでコンテナイメージを使う場合の公式ドキュメントはこちら

docker build してECRにpushする流れですが、先ほど作成したモデル(ノートブックのままなら ./dest の中身)を model という名前のディレクトリに保存してから docker build してください。
Dockerfile内6行目にて、 model をイメージにCOPYしています。

Lambda関数の作成

先ほどECRにプッシュしたイメージをつかってLambda関数の作成をします。

作成できたら設定から以下のようにメモリサイズとタイムアウトを変更しておきます。
メモリサイズは512MBくらいでもいけるかもしれない。

Lambda関数をテストしてみる

テストイベントを以下のように設定し、実行してみます。

正常に動作すれば以下のような結果が返ってきます。

ここでエラーになる場合は、先ほどのDockerイメージの作成のどこかが違う可能性が高いです。
イメージ内にモデルファイル群が入っているか確認してみてください。
また、公式ドキュメントにもあるように、一旦ローカルでテストしてみてもいいと思います。
その場合、curlのリクエストは

curl -XPOST "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{"body": "駅から近くて便利でした"}'

といった感じです。

API Gatewayを作成する

注意

「APIとしてこんな簡単に立てられるんだよ〜」という紹介目的のAPI Gatewayです。
GETなど今回不要なメソッドが使える・X-API-KEYしかかかってない等、若干セキュリティが甘い状態になるので、このまま使用することはオススメしません。
API Gateway + Lambdaを使ったベストプラクティスは他にたくさん記事がありますので、必要であればそういった記事を参考にしてみてください。

API Gatewayをトリガーとして追加

最後に、APIとして利用できるようにするために、API Gatewayを作成します。
作成と言っても今回はLambdaのトリガー追加からAPI Gatewayを選ぶだけです。(勉強用なので)

トリガーの追加でAPI Gatewayを選択し、タイプをREST APIとして作成します。
セキュリティは今回はAPIキーにしました。

作成すると、Lambdaの 設定 > トリガー 画面はこのようになります。
※画像は一部消しこんでます

ここに表示されている API エンドポイント が実際にリクエストするAPIのエンドポイントURLになっており、 API キー に表示されているキーを付けてリクエストすることで、APIとして利用できます。
試しにcurlで実行する場合は以下のような形です。

$ curl -XPOST -H "x-api-key:ここは上述のAPIキーを設定します" -H "Content-Type: application/json" https://あなたのAPIエンドポイントURL -d "駅から近くて便利でした"

リクエストすると結果は以下のような形で返ってきます(レスポンスをjqで整形しています)

これで無事、感情分析APIが機能していることが確認できました。
お疲れ様でした。

まとめ

以上が

  • 感情分析用のモデルの作成
  • Lambda上でのモデル実行
  • API Gatewayを使ったAPI化

という、日本語文章の感情分析APIをつくる話でした。

Lambdaのコールドスタートに引っかかると若干時間がかかりますが、それでも十分実用的な範囲ではないかと思っています。
このように、ALBERTのような軽量モデルを活かすことで、簡単に推論APIを立ち上げることが可能です。
今回はやってませんが、torch scriptやONNX化することでももっと軽量化できると思います。あるいは量子化等の方策をとってもいいですね。
先ほども少し述べましたがAPI Gateway + LambdaのAPI作成自体はベストプラクティス的な記事がたくさんあるので、そういったものを参考にもう少し真面目に作り込めば(用途次第では)十分使える推論APIになると思います。

今回は感情分析タスクにしてますが、もちろんこれはALBERTで対応可能なNERなどの他のタスクでも使えます。
Q&Aタスク用にファインチューニングして、Slack bot化しても面白いと思います。

ぜひ、これをきっかけにいろいろなNLPタスクを楽しんでもらえたらと思います。

Discussion