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

# 【第3週】文章の分類と感情の判定

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



## はじめに

第4週では、**大規模言語モデル（LLM）を使った「翻訳」と「要約」**に挑戦します。  
翻訳と要約は、AIの中でも特に実用性が高いタスクです。たとえば：

- 英語ニュース記事を日本語に翻訳する  
- 論文の要点を数行で要約する  
- 長文メールを要点だけ抽出する  

こうした処理はすべて、テキストを入力してテキストを出力するという点で、**txt2txt（テキスト変換）タスク**に分類されます。

今回は、前週と同様に Google Colab 上で Hugging Face の日本語対応モデルを活用し、以下の内容を体験します。

- 翻訳と要約の違いを理解する  
- プロンプトの工夫によって出力結果がどう変わるかを体験する  
- 実用的な長文要約の精度や限界を知る  
 
前週までは「自由な文章の生成」に焦点を当てましたが、今週はより「目的を持ったテキスト変換」に進みます。  
「正確さ」や「情報圧縮」といった観点から、モデルの出力をどう評価するか、という視点も重要になってくるのですが、まずは動かしてみなければ始まりませんよね。

それでは、Colabの準備を整えて、翻訳と要約の世界へ進んでいきましょう！

<a href="https://colab.research.google.com/drive/11nJMOPYEXup8Vrl6q40JXp2ElymDZUeW?usp=sharing">今週のコード </a>

---

## 1. 実習の目的

- 英語の文章を日本語に翻訳する  
- 長文テキストを数行で要約する  

今回の実習では、単なる「続きの生成」ではなく、与えられた情報を**翻訳や要約という目的に応じて再構成**する力を、モデルに発揮させます。  
そのためには、**適切なプロンプト設計**が鍵になります。

Google Colab 上で動かしながら、**指示の仕方ひとつで出力が大きく変わる**ことを体験してみましょう。

---

## 2. 英語→日本語の翻訳を試してみよう（Mitsuaモデル）

今回は、軽量でColabでも使える翻訳モデルとして、  
[`Mitsua/elan-mt-bt-en-ja`](https://huggingface.co/Mitsua/elan-mt-bt-en-ja) を使います。  

まずは、英語から日本語への翻訳を体験してみましょう。

```python
!pip install transformers sentencepiece

from transformers import MarianMTModel, MarianTokenizer

# モデル名を指定
model_name = "Mitsua/elan-mt-bt-en-ja"

# モデルとトークナイザのロード
tokenizer = MarianTokenizer.from_pretrained(model_name)
model = MarianMTModel.from_pretrained(model_name)

# 翻訳関数
def translate_en_to_ja(text):
    inputs = tokenizer.encode(text, return_tensors="pt")
    outputs = model.generate(inputs, max_length=512, num_beams=4, early_stopping=True)
    translated = tokenizer.decode(outputs[0], skip_special_tokens=True)
    return translated

# 翻訳テスト
english_text = "Artificial intelligence is changing the world."
japanese_text = translate_en_to_ja(english_text)
print("英文:", english_text)
print("日本語訳:", japanese_text)
```
### ✅ 出力例
```
英文: Artificial intelligence is changing the world.
日本語訳: 人工知能が世界を変えている。
```

うん、翻訳できましたね。

---

## 🔄 自分で翻訳してみよう

コードの中の英語文 `english_text` を次のように変更して、翻訳結果を楽しんでみましょう。

- `"The cat is sleeping under the table."`
- `"This technology will change education forever."`
- `"Do you believe in AI?"`

どんな日本語が返ってくるか、試してみてください。

---

### 🧪 名言の翻訳も試してみよう？

ついでに、次のような「歴史的に有名なフレーズ」も翻訳してみたくなりませんか？

- `"The Earth was blue."`  
　👉 「地球は青かった」──これは、1961年に人類初の有人宇宙飛行を成し遂げた旧ソ連の宇宙飛行士、**ユーリイ・ガガーリン**の名言として知られています。

- `"Government of the people, by the people, for the people."`  
　👉 **ゲティスバーグ演説**（アメリカ・リンカーン大統領）の一節、「人民の、人民による、人民のための政治」

ですが…  
実際にこのような**文学的・象徴的なフレーズ**を翻訳モデルに投げると、  
うまく訳してくれないことが多いです 😅

### ❗ なぜうまく訳せないのか？

- 比喩や文化的背景を考慮しない「逐語訳」になりやすい
- 有名な訳例（定訳）を知らずに、ただの構文変換になる

このような「創造性・文脈理解」が求められるタスクは、  
まだまだ人間や高度なAI（ChatGPTなど）でないと難しいようです。

でも、失敗も含めて「生成AIの限界」を知るのは良い学びとなるでしょう。


---

## 3. 実習：日本語→英語の翻訳（チャレンジ編）

では、次に **日本語から英語へ翻訳** するモデルを使ってみましょう。  
使うモデルはこちらです👇

👉 [`Mitsua/elan-mt-bt-ja-en`](https://huggingface.co/Mitsua/elan-mt-bt-ja-en)  
※このモデルも、先ほどと同じ「Mitsua」チームによるものです。


## 🔍 実習課題：

1. Hugging Faceのページから `Mitsua/elan-mt-bt-ja-en` の使い方を調べよう  
2. Colabで動かして、次の日本語を英訳してみよう：

```text
今日は天気がいいので、散歩に出かけました。
```

## 🔍 実習のヒント：`MarianTokenizer` の使い方を調べてみよう

実習課題では、`MarianTokenizer` を使用します。

以下の公式ドキュメントを参考にすると、`MarianTokenizer` の使い方やサンプルコードが掲載されています。

- [Hugging Face Transformers Documentation: MarianMT](https://huggingface.co/docs/transformers/model_doc/marian)

上記の例では、"Helsinki-NLP/opus-mt-en-roa" というモデルが使われています。
これを "Mitsua/elan-mt-bt-ja-en" に変更すれば動く、かも？


### ✅ 正解コード例（※自分で考えてから見ると力になります！）

```python
from transformers import MarianMTModel, MarianTokenizer

model_name = "Mitsua/elan-mt-bt-ja-en"
tokenizer = MarianTokenizer.from_pretrained(model_name)
model = MarianMTModel.from_pretrained(model_name)

def translate_ja_to_en(text):
    inputs = tokenizer.encode(text, return_tensors="pt")
    outputs = model.generate(inputs, max_length=512, num_beams=4, early_stopping=True)
    return tokenizer.decode(outputs[0], skip_special_tokens=True)

japanese_text = "今日は天気がいいので、散歩に出かけました。"
english_translation = translate_ja_to_en(japanese_text)
print("英訳:", english_translation)
```

###出力例
```
英訳: I went for a walk because the weather was nice today.
```

---

## 4. 日本語の文章を要約してみよう（mT5-smallベース）

文章要約も、**テキストからテキストへ変換する「txt2txt」タスク**のひとつです。  
特に、日本語ニュースや長文レポートを **数行で要点をまとめる** ことは、AIにとっても高度で実用的な課題です。

ここでは、日本語の要約モデルとして次のものを使います：

👉 [`tsmatz/mt5_summarize_japanese`](https://huggingface.co/tsmatz/mt5_summarize_japanese)

このモデルは、Googleの `mT5-small`（多言語T5）をベースに、  
日本語のニュース記事（XL-Sum）でファインチューニングされた要約専用モデルです。  
**軽量かつ精度も高く、Colabでそのまま動かせます。**

---

### ✅ Colabで実行できるサンプルコード

```python
# 1. transformersとsentencepieceのインストール（最初の1回だけ）
!pip install transformers sentencepiece

# 2. モデルとトークナイザの読み込み
from transformers import AutoTokenizer, AutoModelForSeq2SeqLM

model_name = "tsmatz/mt5_summarize_japanese"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForSeq2SeqLM.from_pretrained(model_name)

# 3. 要約対象の長文（自由に書き換えてOK）
text = """
宇宙航空研究開発機構（JAXA）は、新たな月探査機「TSUKIMI（ツキミ）」の打ち上げに成功しました。
この探査機は、月面における地下水の存在を調査することを目的としており、
地球からおよそ38万キロメートル離れた月の軌道上に到達しました。
JAXAによると、今後数週間にわたり月面の地質を分析する予定です。
"""

# 4. 入力には "summarize: " という指示文をつける
input_text = "summarize: " + text

# 5. トークナイズしてモデルに渡す
inputs = tokenizer.encode(input_text, return_tensors="pt", max_length=512, truncation=True)

# 6. 要約を生成
summary_ids = model.generate(inputs, max_length=128, min_length=5, length_penalty=2.0, num_beams=4, early_stopping=True)

# 7. デコードして表示
summary = tokenizer.decode(summary_ids[0], skip_special_tokens=True)
print("✅ 要約結果：", summary)
```

### ✅ 出力例
```
✅ 要約結果：  宇宙航空研究開発機構(JAXA)は25日、月面の地質を調査する新たな月探査機を打ち上げたと発表した。

```

要約できましたか？

では、自分でも要約してみてください。

---

## 📝 自分でも要約してみよう

上記コード中の `text = """ ... """` を次のように書き換えて、  
さまざまな文章の要約を試してみましょう。

```python
text = """
日本の経済は現在、回復基調にあります。消費支出は堅調で、企業の設備投資も増加傾向にあります。
一方で、円安や物価高など、家計への影響も懸念されています。
日銀は引き続き金融緩和政策を維持する方針です。
"""
```


## ⚙️ パラメータを変えてみよう

要約モデルの出力は、**生成時のパラメータ**によって変化します。  
いくつかの値を変えて、どんな風に結果が変わるかを観察してみましょう。

### パラメータの説明

| パラメータ       | 説明                                         | 例                       |
|------------------|----------------------------------------------|--------------------------|
| `max_length`     | 出力される要約文の最大トークン数             | `64`, `128`, `256`       |
| `min_length`     | 出力の最低長さを保証（短すぎ防止）           | `5`, `10`, `20`          |
| `length_penalty` | 長さに対するペナルティ。大きいほど短くなる傾向 | `1.0`, `2.0`, `0.8`      |
| `num_beams`      | ビームサーチ幅（大きいほど品質が安定）        | `2`, `4`, `8`            |

---

### ✅ では、パラメータを変更して実行してみましょう。

分かりやすいよう、短い要約の生成例を記します。

以下のように、`generate()` 関数の引数を変更して要約を生成してみましょう。

```python
summary_ids = model.generate(
    inputs,
    max_length=20,
    min_length=15,
    length_penalty=4.0,
    num_beams=4,
    early_stopping=True
)
summary = tokenizer.decode(summary_ids[0], skip_special_tokens=True)
print("✅ 要約（調整後）:", summary)
```

### ✅ 出力例
```
✅ 要約結果： 宇宙航空研究開発機構(JAXA)は25日、
```

あちゃぁ。長さは短くなりましたが、途中で切れてしまいましたね。

悪い結果でしたが、パラメータが変更されたことはわかったかと思います。

では、パラメータの違いで、どれくらい長く・短く・詳細な要約が出るかを比べてみてくださいね。

---

## 🔚 まとめ

第3週では、**翻訳**と**要約**という、実用性の高い2つのテキスト変換タスクに挑戦しました。

---

### ✅ 英訳：日本語⇄英語の翻訳を体験

- `Mitsua/elan-mt-bt-en-ja` と `Mitsua/elan-mt-bt-ja-en` という2つの翻訳モデルを使い、
  - 英語 → 日本語
  - 日本語 → 英語
  の双方向の翻訳を体験しました。
  
- モデル名を変えるだけで切り替え可能な仕組みを知り、  
  Hugging Face のモデルを活用する手順を身につけました。

- また、「地球は青かった」や「人民の、人民による…」といった象徴的フレーズが  
  **そのまま翻訳できないこともある**という、生成AIの限界も確認できました。

---

### ✅ 要約：長文から要点を抽出する力

- `tsmatz/mt5_summarize_japanese` を使い、日本語ニュース記事を要約するタスクに挑戦しました。

- `summarize:` というプレフィックスの必要性や、  
  `max_length`, `num_beams`, `length_penalty` などの**生成パラメータの調整**が出力にどのように影響するかを体験しました。

- また、**途中で切れる要約や、不自然な出力**が出るケースを通じて、  
  実務応用における注意点も理解しました。

---

## 💡 翻訳と要約の違いを整理しよう

| タスク   | 入力の意味 | 出力の特徴                 | 求められるモデルの性質         |
|----------|------------|----------------------------|--------------------------------|
| 翻訳     | 意味を変えずに「別の言語」で表現 | 原文の忠実な言い換え             | 対訳データで学習されたモデル     |
| 要約     | 意味を圧縮し、「短く伝える」     | 要点を残した情報の抽出・圧縮     | 内容把握＋再構成力が求められるモデル |

---

## 🔭 次回予告

次回（第4週）では、**文章の分類と感情の判定**に挑戦します。  
これもまた、入力テキストから**意味的な属性を抽出するタスク**です。

- その文章はどんなジャンル？（分類）
- ポジティブ？ネガティブ？（感情判定）

翻訳や要約とは異なり、**「数値やラベルで表す」分類系タスク**へと進んでいきます。

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

---