Transformersを使った自然言語処理の実践ガイド

## はじめに

自然言語処理（NLP）は、機械学習の中でも特に重要な分野の一つです。近年、Hugging Faceの`transformers`ライブラリを使うことで、NLPタスクを簡単に実装できるようになりました。本記事では、`transformers`ライブラリを使って、文書分類、自然言語推論、意味的類似度計算、固有表現認識、要約生成などのタスクを解いていきます。

| モデル名                                      | タスク               | 説明                                                                 |
|-----------------------------------------------|----------------------|----------------------------------------------------------------------|
| llm-book/bert-base-japanese-v3-marc_ja        | 文書分類             | テキストの極性（ポジティブ/ネガティブ）を予測する。                  |
| llm-book/bert-base-japanese-v3-jnli           | 自然言語推論         | 2つの文の論理関係（含意、矛盾、中立）を推論する。                    |
| llm-book/bert-base-japanese-v3-jsts           | 意味的類似度計算     | 2つの文がどれだけ似ているかを数値化する。                            |
| llm-book/bert-base-japanese-v3-unsup-simcse-jawiki | 意味的類似度計算     | 文の埋め込みを計算し、コサイン類似度で文の類似度を測定する。          |
| llm-book/bert-base-japanese-v3-ner-wikipedia-dataset | 固有表現認識         | テキスト中の固有名詞（人名、地名、組織名など）を抽出する。            |
| llm-book/t5-base-long-livedoor-news-corpus    | 要約生成             | 長いテキストを短く要約する。                                          |
| abeja/gpt2-large-japanese                     | テキスト生成         | 与えられたテキストに基づいて、次のテキストを生成する。                |

## 1.1 Transformersを使って自然言語処理を解いてみよう

まず、`transformers`ライブラリをインストールします。以下のコマンドで必要なパッケージをインストールしましょう。

```bash
!pip install transformers[ja,sentencepiece,torch]
```

### 1.1.1 文書分類

文書分類は、テキストがどのカテゴリに属するかを予測するタスクです。以下のコードでは、日本語の文書分類モデルを使って、テキストの極性（ポジティブ/ネガティブ）を予測します。

```python
from transformers import pipeline

text_classification_pipeline = pipeline(
    model="llm-book/bert-base-japanese-v3-marc_ja"
)

positive_text = "世界には言葉がわからなくても感動する音楽がある。"
print(text_classification_pipeline(positive_text)[0])

negative_text = "世界には言葉がでないほどひどい音楽がある。"
print(text_classification_pipeline(negative_text)[0])
```

**Output:**

```python
{'label': 'positive', 'score': 0.9993619322776794}
{'label': 'negative', 'score': 0.963624894618988}
```

### 1.1.2 自然言語推論

自然言語推論（NLI）は、2つの文の論理関係を推論するタスクです。以下のコードでは、日本語のNLIモデルを使って、文の関係を予測します。

```python
nli_pipeline = pipeline(model="llm-book/bert-base-japanese-v3-jnli")

text = "二人の男性がジェット機を見ています"
entailment_text = "ジェット機を見ている人が二人います"
print(nli_pipeline({"text": text, "text_pair": entailment_text}))

contradiction_text = "二人の男性が飛んでいます"
print(nli_pipeline({"text": text, "text_pair": contradiction_text}))

neutral_text = "2人の男性が、白い飛行機を眺めています"
print(nli_pipeline({"text": text, "text_pair": neutral_text}))
```

**Output:**

```python
{'label': 'entailment', 'score': 0.9964311122894287}
{'label': 'contradiction', 'score': 0.9990535378456116}
{'label': 'neutral', 'score': 0.9959145188331604}
```

### 1.1.3 意味的類似度計算

意味的類似度計算は、2つの文がどれだけ似ているかを数値化するタスクです。以下のコードでは、日本語の意味的類似度モデルを使って、文の類似度を計算します。

```python
text_sim_pipeline = pipeline(
    model="llm-book/bert-base-japanese-v3-jsts",
    function_to_apply="none",
)

text = "川べりでサーフボードを持った人たちがいます"
sim_text = "サーファーたちが川べりに立っています"
result = text_sim_pipeline({"text": text, "text_pair": sim_text})
print(result["score"])

dissim_text = "トイレの壁に黒いタオルがかけられています"
result = text_sim_pipeline({"text": text, "text_pair": dissim_text})
print(result["score"])

from torch.nn.functional import cosine_similarity

sim_enc_pipeline = pipeline(
    model="llm-book/bert-base-japanese-v3-unsup-simcse-jawiki",
    task="feature-extraction",
)

text_emb = sim_enc_pipeline(text, return_tensors=True)[0][0]
sim_emb = sim_enc_pipeline(sim_text, return_tensors=True)[0][0]
sim_pair_score = cosine_similarity(text_emb, sim_emb, dim=0)
print(sim_pair_score.item())

dissim_emb = sim_enc_pipeline(dissim_text, return_tensors=True)[0][0]
dissim_pair_score = cosine_similarity(text_emb, dissim_emb, dim=0)
print(dissim_pair_score.item())
```

**Output:**

```python
3.5703563690185547
0.0416213721036911

0.8568587899208069
0.458870530128479
```

### 1.1.4 固有表現認識

固有表現認識（NER）は、テキスト中の固有名詞（人名、地名、組織名など）を抽出するタスクです。以下のコードでは、日本語のNERモデルを使って、テキスト中の固有表現を抽出します。

```python
from pprint import pprint

ner_pipeline = pipeline(
    model="llm-book/bert-base-japanese-v3-ner-wikipedia-dataset",
    aggregation_strategy="simple",
)

text = "大谷翔平は岩手県水沢市出身のプロ野球選手"
pprint(ner_pipeline(text))
```

**Output:**

```python
[{'end': None,
  'entity_group': '人名',
  'score': np.float32(0.99823624),
  'start': None,
  'word': '大谷 翔平'},
 {'end': None,
  'entity_group': '地名',
  'score': np.float32(0.9986874),
  'start': None,
  'word': '岩手 県 水沢 市'}]
```

### 1.1.5 要約生成

要約生成は、長いテキストを短く要約するタスクです。以下のコードでは、日本語の要約生成モデルを使って、記事の要約を生成します。

```python
text2text_pipeline = pipeline(
    model="llm-book/t5-base-long-livedoor-news-corpus"
)

article = "ついに始まった３連休。テレビを見ながら過ごしている人も多いのではないだろうか？　今夜オススメなのは何と言っても、NHKスペシャル「世界を変えた男 スティーブ・ジョブズ」だ。実は知らない人も多いジョブズ氏の養子に出された生い立ちや、アップル社から一時追放されるなどの経験。そして、彼が追い求めた理想の未来とはなんだったのか、ファンならずとも気になる内容になっている。 今年、亡くなったジョブズ氏の伝記は日本でもベストセラーになっている。今後もアップル製品だけでなく、世界でのジョブズ氏の影響は大きいだろうと想像される。ジョブズ氏のことをあまり知らないという人もこの機会にぜひチェックしてみよう。 世界を変えた男　スティーブ・ジョブズ（NHKスペシャル）"
print(text2text_pipeline(article)[0]["generated_text"])
```

**Output:**

```python
今夜はNHKスペシャル「世界を変えた男 スティーブ・ジョブズ」をチェック!
```

### 1.2 Transformersの基本的な使い方

`transformers`ライブラリの基本的な使い方として、トークナイザとモデルのロード、テキスト生成を行います。

```python
from transformers import AutoTokenizer, AutoModelForCausalLM

# トークナイザのロード
tokenizer = AutoTokenizer.from_pretrained("abeja/gpt2-large-japanese")
print(tokenizer.tokenize("今日は天気が良いので"))

# モデルのロード
model = AutoModelForCausalLM.from_pretrained("abeja/gpt2-large-japanese")

# テキスト生成
inputs = tokenizer("今日は天気が良いので", return_tensors="pt")
outputs = model.generate(
    **inputs,
    max_length=15,
    pad_token_id=tokenizer.pad_token_id
)
generated_text = tokenizer.decode(outputs[0], skip_special_tokens=True)
print(generated_text)
```

**Output:**

```python
今日は天気が良いので外でお弁当を食べました。
```

## まとめ

本記事では、`transformers`ライブラリを使って、文書分類、自然言語推論、意味的類似度計算、固有表現認識、要約生成などのNLPタスクを実装しました。`transformers`を使うことで、複雑なモデルを簡単に利用できることがわかります。ぜひ、この記事を参考にして、さまざまなNLPタスクに挑戦してみてください。

---

この記事は、`transformers`ライブラリを使った自然言語処理の実践的なガイドとして、さまざまなタスクを紹介しました。各タスクに対応するモデルとその機能を理解し、実際にコードを動かすことで、NLPの世界をより深く理解できるでしょう。

参考資料：
- [https://github.com/ghmagazine/llm-book](https://github.com/ghmagazine/llm-book)