Python＋Streamlitで感情分析アプリをコミュニティクラウドにデプロイする

### はじめに

<a href="https://streamlit.io/"><img src="https://streamlit.io/images/brand/streamlit-logo-primary-colormark-darktext.png" width="200"></a>

[Streamlit](https://streamlit.io/) は、Webアプリの手早い構築とサービス展開（deploy）を可能にするフレームワークです。

[Python](https://www.python.org/) ができることなら、たいていなんでも Web アプリ化できます。[Pillow/PIL](https://pillow.readthedocs.io/en/stable/) や [OpenCV](https://opencv.org/)による画像処理も、[Janome](https://janome.mocobeta.dev/ja/) や [NLTK](https://www.nltk.org/)を使った自然言語処理も、[OpenAI](https://openai.com/ja-JP/) や [Hugging Face](https://huggingface.co/) を活用した AI 処理も、Streamlit のコマンドをちょこちょこ加えるだけで Web アプリになっちゃいます。ハードコアな Web フレームワークと異なり、複雑なルーティングやテンプレート、HTML や HTTP や CSS などの詳細を知る必要はありません。

その代わり、お仕着せな UI しか使えないというデメリットはあります。しかし、自分の成果やアイデアを友人、共同研究者、同僚などと手軽に共有したいのなら、こんなに便利なものはありません。

アプリは、Python アプリ共有サイトといった感じの Streamlit コミュニティクラウドから無償で公開、運用できます。そうしたアプリの中で目立って興味深いものは [Gallery](https://streamlit.io/gallery)（ギャラリー）で紹介されているので、試してみてください。


### デモ

というわけで、ここでは [Hugging Face](https://huggingface.co/) 収録のモデルを使った感情分析アプリを作り、Streamli コミュニティクラウドから公開します。

本アプリは [`https://sat-sentiment.streamlit.app/`](https://sat-sentiment.streamlit.app/) からアクセスできます。次に画面例を示します。

<!-- 1206 x 544 -->
![デモ画面](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2712175/d3f18229-fb65-44e5-a098-1dc7abe2142d.png)

右パネル下の入力フィールドに和文テキストを入れ、`＞`をクリックすれば、分析結果を上部に表示します。

> 2025-03-11: `requirements.txt` の問題を修正しました。

#### サービス休止

Streamlit コミュニティクラウドは、しばらくアクセスのないアプリを退蔵します。そうした状態だと次の画面が表示されるので、青い「再稼働してね」ボタンをクリックします。

<!-- 596 x 268 -->
![休止画面](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2712175/9318f4d5-967d-4c95-92d3-011ff515aa4c.png)

復旧にはやや時間がかかります。


### 感情分析アプリ

コードを次に示します。同じコードは [Github](https://github.com/stoyosawa/streamlit/) にもあるので、行番号なしの版はそちらからどうぞ。

```python
  1  import streamlit as st
  2  from transformers import pipeline
  3
  4
  5  MODEL = 'Mizuiro-sakura/luke-japanese-large-sentiment-analysis-wrime'
  6  MODEL_URL = 'https://huggingface.co/Mizuiro-sakura/luke-japanese-large-sentiment-analysis-wrime'
  7  MAX_LENGTH = 200
  8
  9  messages = {
 10      'title': 'AI 感情分析（Transformers 使用）',
 11      'usage': f'入力した日本語文に書かれた感情を判定します。感情の種類は*喜び、悲しみ、期待、驚き、怒り、恐れ、嫌悪 、信頼*の8種類で、文中で最も支配的なものが表示されます。使用しているモデルは[`{MODEL}`]({MODEL_URL})です。',
 12      'sentiments': '喜び、悲しみ、期待、驚き、怒り、恐れ、嫌悪、信頼'.split('、'),
 13      'prompt': '日本語の文を入力してください'
 14  }
 15
 16
 17  @st.cache_resource
 18  def get_model(model=MODEL):
 19      try:
 20          pipe = pipeline('sentiment-analysis', model=model)
 21      except Exception as e:
 22          st.markdown(e)
 23      return pipe
 24
 25
 26  with st.sidebar:
 27      st.markdown('本アプリケーションは、[『作ってわかる［入門］Streamlit』](https://gihyo.jp/book/2025/978-4-297-14764-8)の第3章で紹介したものです。コードの説明やクラウドへの展開方法などはそちらを参照してください。')
 28      st.image('http://image.gihyo.co.jp/assets/images/cover/2025/9784297147648.jpg')
 29
 30
 31  pipe = get_model()
 32  st.title(messages['title'])
 33  st.markdown(messages['usage'])
 34
 35  sentence = st.chat_input(messages['prompt'], max_chars=MAX_LENGTH)
 36  if sentence is not None:
 37      result = pipe(sentence)
 38      label_number = int(result[0]['label'][-1:])
 39      sentiment = messages['sentiments'][label_number]
 40      st.markdown(f'{sentence} >> **{sentiment}**')
```

#### 感情分析モデル

感情分析部分はシンプルです。まず、`transformers` パッケージをインポートし（2行目）、日本語テキストでの感情分析をやってくれるモデルの名称（5行目）を `transformers.pipeline()` にセットする（20行目）ことで準備をします。そして、分析対象のテキストが容易できたら、解析します（37行目）。

ここで利用しているのは、水色 桜さんがチューニングしたモデルです。ご本人が Qiita の記事、[“8つの感情を分析できるように言語モデル LUKE をファインチューニングしてみた”](https://qiita.com/Mizuiro__sakura/items/aa13593b239f91a51486)、で中身を解説しているので、細かい話はそちらをどうぞ。

#### requirements.txt

このアプリがインポートする外部パッケージは `transformers` だけですが（2行目）、中では `sentencepiece` と `torch` が使われます。初回起動時にこれらをインストールするよう、次のような`requirements.txt` ファイルを用意し、アプリコードと同じディレクトリに置きます。

```
# requirements.txt for sentiment_analysis.py
sentencepiece
transformers
torch
```

`streamlit`（1行目）はデフォルトで用意されているので、記述する必要はありません。

`requrements.txt` は `pip` の機能の1つです。詳細は `pip` ドキュメントの [“Requirements File Format”](https://pip.pypa.io/en/stable/reference/requirements-file-format/) を参照してください。Streamlit 固有の話題は [“App dependencies for your Community Cloud app”](https://docs.streamlit.io/deploy/streamlit-community-cloud/deploy-your-app/app-dependencies) にあります。

#### Streamlit

Streamlit によるユーザインタフェースの主要部分は35～40行目です。

`st.chat_input()`（35行目）で入力フィールドを生成します。スクリプトのどこにコードを置いても、フィールドは画面下に配置されます（そういうデザイン）。第1引数には、入力をうながす文（ここでは「日本語の...」）を指定します。

![250301-sentiment-input.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2712175/e2e7b8be-ae3d-426c-889b-2f2c727a65a3.png)

Streamlit は、キー入力などのイベントが発生するとスクリプトを最初から再実行することで画面を描き替えるという、どことなく強引さを感じる方法でイベントを処理します。ユーザ入力のない初期状態では、関数は `None` を返します。そのため、36行目以降は処理されません。

入力があり、再実行されると35行目の戻り値の `sentence` にその文字列が代入され、36行目以降が実行されます。つまり、`transformers.pipeline()` が呼び出され、その結果が表示（40行目）されます。

`transformers.pipeline()` の戻り値の構造は上記の[水色 桜さんの記事](https://qiita.com/Mizuiro__sakura/items/aa13593b239f91a51486)を参照してください。

#### キャッシング

再起動すると、変数値や状態がリセットされます。それでは、モデルを読んで構築するといった手間暇のかかる処理を、ユーザ入力のあるたびに繰り返さなければなりません。

そこで、17行目の `@st.cache_resource` デコレータでデータをキャッシュします。

このデコレータで修飾された関数（ここでは18行目の `def get_model()`）は、呼び出されると引数と`return` 値のペア（辞書）をキャッシュします。同じ引数で再度呼び出されたときは、関数ブロックを実行することなく、キャッシュの値を取り出して返します。

再起動をくぐり抜けても前の状態（変数とその値）を保持するメカニズムは、Streamlit ドキュメントの[“Advanced concepts of Streamlit”](https://docs.streamlit.io/get-started/fundamentals/advanced-concepts) で説明されています。


### アプリケーションの展開方法

Streamlit コミュニティクラウドにアプリを展開するには、ソースを Github に置き、Streamlit のアカウントと連携させます。

1. Streamlit アカウントを作成します（Google あるいは Github を介したソーシャルサインインも可能）。
2. Streamlit アカウントを Github アカウントと連携します。
3. Streamlit アカウントから、Github レポジトリを選択することで、アプリ作成をします。

Streamlit コミュニティクラウドでは、それぞれのアプリに独自のドメイン名を（`<nane>.streamlit.app`の`<name>`部分が選べる）が付与されます。個人名部分の取得ははやい者勝ちです。

これだけです。一度連携すれば、Github を `push` などでアップデートするたびに、自動的にアプリが更新されます。

設定はストレートなのでそう迷うことはないはずですが、詰まったらドキュメントの[“Welcome to Streamlit Community Cloud”](https://docs.streamlit.io/deploy/streamlit-community-cloud)を参照してください（[“Get started”](https://docs.streamlit.io/deploy/streamlit-community-cloud/get-started)から始めます）。



### おわりに

と、駆け足で Streamlit の魅力を紹介しました。

この記事は、技術評論社の許可を得て[『作ってわかる［入門］Streamlit 〜 Pythonによる実践Webサービス開発』](https://gihyo.jp/book/2025/978-4-297-14764-8)（2024年2月刊）から理解・分解・再構築して作成したものです。

> 2025-03-21: Streamlit による[ブラックジャック（トランプゲーム）実装の記事](https://qiita.com/stoyosawa/items/4c8ccc9e1791eb338bc0)も追加しました。

ご購入はこちらから：【[Honto](https://honto.jp/ebook/pd_34122316.html)，[amazon.co.jp](https://www.amazon.co.jp/dp/4297147645)，[ヨドバシ](https://www.yodobashi.com/product/100000086602699652/)，[楽天ブックス](https://books.rakuten.co.jp/rb/18113489/)】

<img src="http://image.gihyo.co.jp/assets/images/cover/2025/9784297147648.jpg" width="200">