事前学習済みモデルで感情識別をしてみた

## はじめに

この記事は[慶應義塾大学理工学部のアドベントカレンダー その8日目](https://adventar.org/calendars/7773)です。

今日はHuggingFaceで公開されている事前学習済みモデルを使ってみた話です。

## HuggingFaceとは
[HuggingFace](https://huggingface.co/)とは主に自然言語処理系のエコシステムで以下の特徴があります。

- オープンソースのプログラムを用いて構築されたモデルを
    - 学習できる
    - 他のユーザーに配布することができる
    - APIとして使用できる
- 各モデルにコミュニティがあり
    - プルリクエストを送ることが出来る
    - 質問などディスカッションを行うことができる

個人的にはKaggleやGitHubのようなプラットフォームと近しいものだと印象を受けました。今回は題目の通り感情識別ができるアプリを作ってみたのですが、僕自身は自然言語処理について詳しく分からないので**事前学習済みモデル**を使用しています。orz

## 作ってみたアプリ

声で日記を録音して保存できるアプリに、感情識別機能をHuggingFaceの事前学習済みモデルを用いて実現してみました。

シンプルなアプリですがGitHubでコードを公開しているので良ければ見てみてください。

https://github.com/fummicc1/Viary


<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/300444/48e5eecc-057f-0efe-b0bc-3a52b596fe4f.gif" width=360>


僕は一番できる技術分野がモバイル系のアプリ開発なのでモバイルアプリを紹介していますが、バックエンドでpythonを動かしているのでクライアントは任意のもので良いと思います。

APIは公開しているので下のURLで遊ぶことができます。サーバーが弱いので沢山アクセスするとお亡くなりになります…
(一応GitHub Actionsで毎日18時に生存確認しているので24時間くらい経てば直っていると思いますw)


https://voice-diary.net/text2emotion?lang=ja&text=今日は朝ごはんを食べ忘れた



## 使ってみたモデル
### 感情識別モデル

[j-hartmann/emotion-english-distilroberta-base](https://huggingface.co/j-hartmann/emotion-english-distilroberta-base)を使用しました。

### 日本語→英語の翻訳

（上で紹介した感情識別モデルが英語のみの対応であったため、日本語の文章を英語に翻訳してから感情識別モデルに入れるということをしています。）

[Helsinki-NLP/opus-mt-ja-en](https://huggingface.co/Helsinki-NLP/opus-mt-ja-en)を使用しました。


## 感想

### ネガ / ポジを超えた識別は難しい問題

「悲しい」「楽しい」「悔しい」のような明らかな感情表現が文章中に出てこないとニュートラルになったり、ポジティブ / ネガティブかは正しく判別できるが悲しいのか怒っているのかという感情識別は定かではないという印象を受けました。

#### 例

- 「こんにちは僕はfummicc1です」

![Screenshot 2022-12-06 at 23.44.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/300444/652a0628-45c2-32f7-dc66-8bb3e0fa0b5e.png)

:::note info
ただの自己紹介なのでニュートラルで良さそう
:::


- 「今日は1日中家にいたがずっと座っていたのでかなり**疲れた**なので今日は早く寝たい」

![Screenshot 2022-12-06 at 23.46.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/300444/9062c7f3-d9fd-522c-8b32-045ff3c40688.png)

:::note info
全体的にネガティブな感情が選出されていて、sadnessがトップ→良さそう :)
:::

- 「今日は1日中家にいたがずっと座っていた。今日は早く寝たい」

![Screenshot 2022-12-06 at 23.50.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/300444/925d59af-ce71-9328-2bb5-aed0d4e4671c.png)


:::note alert
全体的にネガティブな感情が選出されていて、fearがトップ→微妙
sadnessやdisgustの方が好ましい
:::

### 多少長い文章でも大丈夫

#### 例

- 今日は1日中家にいたがずっと座っていたのでかなり疲れたなので今日は早く寝たい。でも、明日は晴れる予定らしい。今年もあと3週間。冬休みが待ち遠しい。今年は紅白を観るのが楽しみ。家で引きこもっていたい。

![Screenshot 2022-12-07 at 0.01.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/300444/bfe0de09-f582-4ab9-8962-390957116979.png)


というか翻訳の精度が高いです。すごい


### 精度面は編集機能があれば気にならない

精度が良くない部分やバグがある部分は編集できるようにして気にならないようにしました。むしろ「日記を書く→AIが考えた感情を見る→それを踏まえて自分の感情を修正する」の流れができると個人的に日記を書く一つのスパイスになると感じたので良かったです。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/300444/d1419ea7-267b-2a45-1280-07282086d86a.gif" width=300>


## 余談: モバイルとバックエンドの技術的紹介

### フロントエンド

[Flutter](https://flutter.dev/)を使っています。
Dartでモノレポするライブラリに[melos](https://melos.invertase.dev/)というのがあってそれも試しに使ってみました。

### バックエンド

NestJSを使ってみました。ただ、バックエンドの実装がリクエストを受け取ってpythonを実行するだけというシンプルなロジックなのでもっと複雑なことをしてみたいです。

:::note info
サーバーに関してはAmazon Lightsailで固定額のものを運用しています。安心 :)
:::


## さいごに

軽い記事になってしまいましたが、個人的に使っていく予定のアプリなので今後も開発続けてみようと思います。もし興味持ってくれればIssueやPR大歓迎です:)

https://github.com/fummicc1/Viary

最後まで読んでいただきありがとうございました〜。次は9日目です。