BERT Fine-tuning
「Naive BayesとSVMでベースラインができた。次はBERTで文脈を理解するモデルを作ろう。」
田中VPoEが説明する。
「BERTは事前学習済みの言語モデルで、文脈を考慮したテキスト理解ができる。Fine-tuningで少量のデータでも高精度な分類が可能だ。」
BERTの仕組み
入力: [CLS] この 商品 は 返品 できます か [SEP]
↓
トークン埋め込み + 位置埋め込み + セグメント埋め込み
↓
Transformer Encoder × 12層(BERT-base)
↓
[CLS]トークンの出力ベクトル(768次元)
↓
分類ヘッド(線形層 + Softmax)
↓
予測ラベル: "返品・交換"
Fine-tuning実装
from transformers import (
AutoTokenizer, AutoModelForSequenceClassification,
TrainingArguments, Trainer
)
from datasets import Dataset
import numpy as np
# モデルとトークナイザー
model_name = "cl-tohoku/bert-base-japanese-v3"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForSequenceClassification.from_pretrained(
model_name, num_labels=5
)
# データセット準備
def tokenize_function(examples):
return tokenizer(
examples['text'],
padding='max_length',
truncation=True,
max_length=128,
)
train_dataset = Dataset.from_dict({
'text': X_train.tolist(),
'label': y_train.tolist(),
})
train_dataset = train_dataset.map(tokenize_function, batched=True)
eval_dataset = Dataset.from_dict({
'text': X_test.tolist(),
'label': y_test.tolist(),
})
eval_dataset = eval_dataset.map(tokenize_function, batched=True)
# 学習設定
training_args = TrainingArguments(
output_dir='./results',
num_train_epochs=3,
per_device_train_batch_size=16,
per_device_eval_batch_size=32,
learning_rate=2e-5,
weight_decay=0.01,
evaluation_strategy='epoch',
save_strategy='epoch',
load_best_model_at_end=True,
metric_for_best_model='f1',
)
# 評価関数
from sklearn.metrics import f1_score, accuracy_score
def compute_metrics(eval_pred):
logits, labels = eval_pred
predictions = np.argmax(logits, axis=-1)
return {
'accuracy': accuracy_score(labels, predictions),
'f1': f1_score(labels, predictions, average='weighted'),
}
# 学習実行
trainer = Trainer(
model=model,
args=training_args,
train_dataset=train_dataset,
eval_dataset=eval_dataset,
compute_metrics=compute_metrics,
)
trainer.train()
Fine-tuningのポイント
| パラメータ | 推奨値 | 理由 |
|---|---|---|
| 学習率 | 2e-5 〜 5e-5 | 事前学習の重みを壊さない |
| エポック数 | 3〜5 | 過学習を防ぐ |
| バッチサイズ | 16〜32 | GPU メモリに応じて調整 |
| max_length | 128〜512 | タスクに応じて設定 |
| warmup | 総ステップの10% | 学習初期の安定化 |
推論
def predict_category(text, model, tokenizer):
"""テキストのカテゴリを予測"""
inputs = tokenizer(
text, return_tensors='pt',
padding=True, truncation=True, max_length=128,
)
outputs = model(**inputs)
probs = torch.softmax(outputs.logits, dim=-1)
predicted_class = torch.argmax(probs, dim=-1).item()
confidence = probs[0][predicted_class].item()
label_map = {0: '商品問合せ', 1: '返品・交換', 2: '配送', 3: 'アカウント', 4: 'その他'}
return {
'category': label_map[predicted_class],
'confidence': round(confidence, 3),
}
# 使用例
result = predict_category("注文した商品がまだ届きません", model, tokenizer)
print(result) # {'category': '配送', 'confidence': 0.95}
まとめ
| 項目 | ポイント |
|---|---|
| BERT | 事前学習済み言語モデル、文脈理解が可能 |
| Fine-tuning | 少量データ(数百〜数千件)でも高精度 |
| 学習率 | 2e-5が標準、大きすぎると事前学習が壊れる |
| 日本語 | cl-tohoku/bert-base-japanese-v3 を使用 |
チェックリスト
- BERTの仕組み([CLS]トークン、Fine-tuning)を説明できる
- Transformers Trainerを使った学習を実装できる
- 適切なハイパーパラメータを選択できる
- 学習済みモデルで推論を実行できる
次のステップへ
BERT Fine-tuningを理解した。次はLLM Zero-shotによるテキスト分類を学ぼう。
推定読了時間: 30分