即戦力化　ディープラーニング実習（第四週）

# 【第４週】文章の分類と感情の判定 (txt2cls)

講義目録：<a href="https://qiita.com/takenakayoichi/items/3b7435f4b155a181e39f">即戦力化　ディープラーニング実習 </a>

## はじめに

第4週では、**テキストのジャンル分類と感情分析**というタスクに取り組みます。

これは、入力された文章が「どんな内容か」「どんな気持ちを含んでいるか」を判断する、AIによる“読解”のような処理です。

たとえば：

- 「この文章はニュース？商品説明？小説？」  
- 「このレビューはポジティブか？ネガティブか？」  
- 「この文章から、怒りを感じられるか？　喜びを感じられるか？」

といった問いに対して、AIが**カテゴリ（ラベル）を出力**します。  
このような形式のタスクを **txt2cls（テキストから分類へ）** と呼びます。

なお、文章がポジティブかネガティブかを判定する分析を **sentiment analysis（センチメント分析・極性分析）**、  
怒り・悲しみ・喜びなどの情動を分類する分析を **emotion classification（感情分類）** と呼びます。  

> 日本語ではどちらも「感情分析」と訳されがちですが、  
> - **sentiment analysis** は「評価の方向性（肯定／否定）」に注目し、  
> - **emotion classification** は「感情の種類（喜怒哀楽など）」に注目します。  
>  
> 本記事では両者を明確に区別して扱います。

今週も、日本語の感情分析モデルやジャンル分類モデルをHugging Faceからダウンロードし、Google Colabで体験してもらいたいと思います。


---
## 1. 実習の目的

- テキスト分類（ジャンル分類・感情分析）の基本を理解する  
- Hugging Faceの日本語分類モデルを使って予測を行う  
- 感情分析(emotion classification)を行う

今回のタスクであるtext2clsは、分類結果を**数値**や**ラベル**で出力する点に注目してください。  
生成や翻訳とは違い、**正解がある**タスクであるため、今後のモデル評価や精度検証にもつながる重要なテーマです。

---
## 2. ジャンル分類を試してみよう

早速ですが、文章の「話題・ジャンル」を推定・分類するタスク──  
**ジャンル分類（text topic classification）** を体験してみましょう。


今回使用するのは、NVIDIAが公開している多言語対応モデル：

👉 [`nvidia/multilingual-domain-classifier`](https://huggingface.co/nvidia/multilingual-domain-classifier)

このモデルは、日本語を含む**50以上の言語**に対応しており、26種類のトピック（例：ニュース、スポーツ、医療、金融など）に分類してくれます。  

> 🔎 分類されるジャンル一覧（26種類）はモデルページをご参照ください：  
> [https://huggingface.co/nvidia/multilingual-domain-classifier](https://huggingface.co/nvidia/multilingual-domain-classifier)

BERT系列の事前学習モデル `DeBERTaV3` をベースにしており、高い精度が期待できます。

### 🔧 Colabでの実行例

```python
!pip install transformers
import torch
from torch import nn
from transformers import AutoModel, AutoTokenizer, AutoConfig
from huggingface_hub import PyTorchModelHubMixin

class CustomModel(nn.Module, PyTorchModelHubMixin):
    def __init__(self, config):
        super(CustomModel, self).__init__()
        self.model = AutoModel.from_pretrained(config["base_model"])
        self.dropout = nn.Dropout(config["fc_dropout"])
        self.fc = nn.Linear(self.model.config.hidden_size, len(config["id2label"]))

    def forward(self, input_ids, attention_mask):
        features = self.model(input_ids=input_ids, attention_mask=attention_mask).last_hidden_state
        dropped = self.dropout(features)
        outputs = self.fc(dropped)
        return torch.softmax(outputs[:, 0, :], dim=1)

# 設定
config = AutoConfig.from_pretrained("nvidia/multilingual-domain-classifier")
tokenizer = AutoTokenizer.from_pretrained("nvidia/multilingual-domain-classifier")
model = CustomModel.from_pretrained("nvidia/multilingual-domain-classifier")
model.eval()
```

✅ 入力例
ここまでが前準備です。続いて分類する文書を入力します。
「新型のiphoneが発売された」なら、何に分類されるでしょう？

```python
# 入力テキスト
text = "新型のiphone が発売されました。"
inputs = tokenizer([text], return_tensors="pt", padding="longest", truncation=True)
outputs = model(inputs["input_ids"], inputs["attention_mask"])

# 分類結果
predicted_classes = torch.argmax(outputs, dim=1)
predicted_domains = [config.id2label[class_idx.item()] for class_idx in predicted_classes.cpu().numpy()]
print(predicted_domains)
```

✅ 出力例：ネットと通信になりました。
```python
['Internet_and_Telecom']
```

📝 試してみよう
いろいろな文で試してみましょう。

```python
text = "新型imac が発売されました。"
text = "昨日のサッカー日本代表戦では劇的なゴールが決まりました。"
text = "糖尿病の早期発見と生活習慣の改善が重要とされています。"
```
それぞれ、どのようなラベルが返ってくるのでしょう？

💡 まとめ
- ジャンル分類は、文章がどの分野・話題に属するかを自動で推定するタスクです。
- 今回使用したモデルは、多言語対応かつ幅広いカテゴリ（26種類）をカバーしています。

## 3. センチメント分析モデルを使ってみよう

次に、文章がポジティブかネガティブかを判定するタスク── **sentiment analysis（センチメント分析）** を実際に体験してみましょう。

今回使用するのは、Hugging Face 上で公開されている次のモデルです：

👉 [`christian-phu/bert-finetuned-japanese-sentiment`](https://huggingface.co/christian-phu/bert-finetuned-japanese-sentiment)

このモデルは、
- 日本語 BERT モデルである [`cl-tohoku/bert-base-japanese-v2`](https://huggingface.co/cl-tohoku/bert-base-japanese-v2) をベースとし、
- **Amazonの日本語商品レビュー**データでファインチューニングされています。

そのため、**ユーザーの主観が表れやすい文章（レビューや投稿）に対して高い精度**を発揮します。

では早速試してみましょう。

```python
!pip install -q transformers fugashi ipadic
!pip install unidic-lite
from transformers import pipeline

# パイプラインの作成（テキスト分類用）
classifier = pipeline(
    "text-classification",
    model="christian-phu/bert-finetuned-japanese-sentiment",
    tokenizer="christian-phu/bert-finetuned-japanese-sentiment"
)

# テスト文
text = "このイヤホン、音質も良くてコスパ最高でした！"

# 推論実行
result = classifier(text)
print(result)
```

このモデルはAmazonレビューを学習しているため、テスト文もそれに近い「ユーザー評価風の文章」にしています。

google colabへのリンクも記しておきます。[即戦力DL第４週](https://colab.research.google.com/drive/1_7HhDHOE5BGBsMpsPA91yRV_zDh4MlYn?usp=sharing)


✅ 出力例
```python
[{'label': 'positive', 'score': 0.9978}]
```

このように、入力文が「positive」か「negative」か、そして 0〜1 の範囲の スコア（信頼度） が返されます。

このスコアは、モデルがそのラベルをどれだけ妥当と判断しているかを示す値になります。

見た目には確率のように思えますが、これは各ラベルに対する「相対的な重要度」を表す softmax 関数の出力です。
そのため、確率的な意味（事象の発生確率）としては解釈できない点に注意してください。

### 実習

実際のレビューやSNS投稿のような文を入力してみて、どのようなラベルが返るかを観察してみましょう。

💡 まとめ
- sentiment analysis は、テキストに込められた「ポジティブ・ネガティブの極性」を判定するタスクです。

- 今回使用したモデルは、日本語のAmazonレビューを学習したBERTに基づき、高い信頼性を持ちます。

- 出力されるスコアを活用することで、「どれくらい強くポジティブ／ネガティブなのか」を定量的に評価することも可能です。

---
## 4. emotion classification（感情の種類分析）モデルを使ってみよう

ここでは、文章から「どんな種類の感情が含まれているか？」を分類するタスクである  
**emotion classification（感情の種類分析）** を実行します。

### 💡 1クラス分類と多クラス分類

まずは、**1クラス分類（single-label classification）** と **多クラス分類（multi-label classification）** の違いを整理しておきましょう。

- **1クラス分類**：入力に対して、もっともふさわしい「1つのラベル」だけを予測する方式です。  
  例）「ポジティブ or ネガティブ」のいずれかを出力する sentiment analysis（感情極性判定）

- **多クラス分類**：入力に対して、**複数のラベルが同時に成立する**可能性がある方式です。  
  例）「怒り」と「悲しみ」が同時に含まれるような感情混在テキストの判定

今回扱う **emotion classification（感情の種類分析）** は、後者の **多クラス分類** に該当します。

---

### 🔸 Plutchikの基本8感情とは？

心理学者 Robert Plutchik（ロバート・プルチック）は、人間の基本感情を以下の8種類に整理しました：

- **Joy（喜び）**
- **Trust（信頼）**
- **Fear（恐れ）**
- **Surprise（驚き）**
- **Sadness（悲しみ）**
- **Disgust（嫌悪）**
- **Anger（怒り）**
- **Anticipation（期待）**

これらは「プルチックの感情の輪（Plutchik’s Wheel of Emotions）」として知られ、感情分類タスクにおける代表的な基盤になっています。

Plutchik理論に基づく8つの基本感情のうち、**複数が同時に出現しうる**ことを前提としており、  
一つの文に「喜び」と「期待」などの感情が同時に含まれる可能性もあることを推定できます。


### 🔍 使用するモデルについて

今回使用するのは、arXivに掲載された次の論文で紹介された日本語モデルです：

📄 論文タイトル：  
[**Performance Evaluation of Emotion Classification in Japanese Using RoBERTa and DeBERTa**](https://arxiv.org/abs/2505.00013)

この論文では、日本語でPlutchikの8感情を分類するために、DeBERTaなどの事前学習済みモデルを活用した手法を評価しています。

モデル本体はこちら：  
👉 [`YoichiTakenaka/deverta-v3-japanese-large-Joy`](https://huggingface.co/YoichiTakenaka/deverta-v3-japanese-large-Joy)

### ⚙️ 実行準備

本節のemotional classificationはgoogle colabの別URLに記載しています。
[感情の種類分析](https://colab.research.google.com/drive/1ZftoeYEGh_vwBYq14dn1C9GXtTlGNdYf?usp=sharing)


では、前準備を始めましょう。
```python
!pip install deberta-emotion-predictor
from deberta_emotion_predictor import DeBERTaEmotionPredictor
predictor = DeBERTaEmotionPredictor()
```

そして、感情を推定します。
```python
result = predictor.predict_emotions("めっちゃ楽しい☆彡")
predictor.show_emotions(result)
```

✅ 出力結果の例

```python
めっちゃ楽しい☆彡: 喜び
```
⚙️ 入力例２

一度に多数の文を入力することもできます。

```python
# 一度に実行
sample_texts = [
    "そうだ 京都、行こう。",
    "がんばるひとの、がんばらない時間。",
    "わたしらしくをあたらしく",
    "ピースはここにある。",
    "結婚しなくても幸せになれるこの時代に、私は、あなたと結婚したいのです。",
    "これからの地球のために一肌、脱ぎました。",
    "自分は、きっと想像以上だ。",
    "ハローしあわせ。",
    "日本を、1枚で。"
]
res_df = predictor.predict_emotions(sample_texts)
```

✅ 出力結果の例１
```python
そうだ 京都、行こう。: 期待
がんばるひとの、がんばらない時間。: 期待
わたしらしくをあたらしく: 期待
ピースはここにある。: 喜び, 期待
結婚しなくても幸せになれるこの時代に、私は、あなたと結婚したいのです。: 期待
これからの地球のために一肌、脱ぎました。: 喜び, 期待
自分は、きっと想像以上だ。: 驚き
ハローしあわせ。: 喜び
日本を、1枚で。: 期待
```
✅ 出力結果の例２

なお、各感情値のスコアはデータフレームに格納されています。

```python
print(res_df)

#出力は省略します
```


📝 実習
以下のような文を入力して、どの感情が強く出てくるかを観察してみましょう：
```python
text = "明日プレゼンがあるので不安で仕方ない……"
text = "推しが卒業して悲しい"
```

💡 まとめ
Emotion classification では「どの感情が現れているか」を多ラベルで分類します。

本モデルは Plutchikの8感情（Joy, Sadness, Fear など）を対象とし、複数の感情が同時に存在する可能性を可視化します。

可視化結果は、心理学・感情分析・商品レビュー分析などさまざまな応用に役立ちます。

## 📌 今週のまとめ

第4週では、テキスト分類（txt2cls）をテーマに、3種類の分類タスクを体験しました。

### ✅ ジャンル分類（text topic classification）
- 多言語対応モデル `nvidia/multilingual-domain-classifier` を使い、文章が「スポーツ」「金融」「健康」など、どのジャンルに属するかを推定しました。
- 事前学習済みのDeBERTaモデルをベースにしており、日本語を含む50以上の言語に対応可能です。

### ✅ 感情極性分類（sentiment analysis）
- モデル `christian-phu/bert-finetuned-japanese-sentiment` を使い、日本語レビュー文に対して「ポジティブ or ネガティブ」の2択を判定しました。
- 出力はソフトマックススコアであり、「どれだけ強くポジティブか／ネガティブか」も確認できました。

### ✅ 感情の種類分類（emotion classification）
- 論文に基づいたモデル `YoichiTakenaka/deverta-v3-japanese-large-Joy` を使って、Plutchikの基本8感情（喜び、悲しみ、驚きなど）を分類しました。
- 多クラス分類（multi-label classification）として実装されており、1文に複数の感情が同時に含まれる可能性を可視化できました。

---


## 🔭 次回予告

次回（第5週）では、**チャットボットと意味ベクトル**に挑戦します。  

おつかれさまでした！次週もお楽しみに ✨