「問い合わせメールを自動でカテゴリ分けしたい」「レビューのセンチメントを一括でラベル付けしたい」――こうした分類タスクは、従来であれば数千件のラベル付きデータを集めて専用の分類器を学習させる必要がありました。LLM時代の2026年ではZero-Shot分類で80〜90%、Few-Shotで85〜95%の精度が数時間で実現できます。本記事では、LLM自動分類システムの設計、実装、評価、コスト最適化まで、現場で使える実践パターンをまとめます。
LLMによるテキスト分類の利点
LLMによるテキスト分類の最大の利点は、ラベル付き学習データがなくても動くことです。従来のBERTベースの分類器は、最低でも数百件、理想的には数千件のラベル付きデータを必要としました。対してLLMは、カテゴリの定義を自然言語で渡すだけで、その日のうちに分類パイプラインを動かせます。
さらに、カテゴリ体系の柔軟性も大きな強みです。「新しいカテゴリを追加したい」「閉じられたクラスを分割したい」といった変更が、プロンプトの更新だけで完了します。従来モデルの場合は再学習が必要で、数日単位の作業でした。もちろんLLMには推論コストという弱点がありますが、多くの業務分類タスクでは「すばやく運用開始できる」ことの価値の方が勝ります。
分類システムの設計パターン
LLM分類システムの設計パターンは、大きく3つに分類できます。
| パターン | 精度 | コスト | 実装難易度 | データ要件 | 適した場面 |
|---|---|---|---|---|---|
| Zero-Shot分類 | 80〜90% | 中 | 易 | なし | PoC、少量データ、ラベル不足 |
| Few-Shot分類 | 85〜95% | 中(プロンプト長増) | 易 | 5〜20例 | 定常運用、中精度要件 |
| ファインチューニング分類 | 92〜99% | 低(推論)、高(学習) | 中 | 数百〜数千例 | 大規模・高精度要件 |
| 軽量モデル蒸留 | 90〜97% | 非常に低 | 高 | LLM出力から自動生成可 | 大量データ、コスト最優先 |
実務ではまずZero-Shotで動かし、精度が足りなければFew-Shotに進み、それでも足りなければファインチューニングを検討する、という段階的アプローチが失敗しにくいやり方です。Zero-Shot実装は驚くほどシンプルで、次のように書けます。
from openai import OpenAI
client = OpenAI()
CATEGORIES = ["billing", "technical", "account", "other"]
def classify(text: str) -> str:
prompt = (
f"以下の問い合わせを次のカテゴリに分類してください: {', '.join(CATEGORIES)}\n"
f"カテゴリ名のみを返してください。\n\n問い合わせ: {text}"
)
resp = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": prompt}],
temperature=0,
)
return resp.choices[0].message.content.strip()
分類スキーマの設計
分類の精度は、スキーマの設計品質に大きく依存します。曖昧なカテゴリ定義は、LLMの混乱を招き、精度を下げます。スキーマ設計時のチェックポイントを以下にまとめます。
| チェック項目 | 確認ポイント |
|---|---|
| カテゴリ数 | 多すぎない(理想は20以下、それ以上は階層化) |
| カテゴリ定義 | 1〜2文で境界を明確に記述 |
| カテゴリ間の排他性 | 重複なく、網羅的(MECE) |
| 不明カテゴリ | "other"等の逃げ道を用意 |
| 複数ラベル | 単一 or 複数の設計を明示 |
| 信頼度スコア | 低信頼度のケースを人手レビューに回す設計 |
Structured Outputを併用すると、カテゴリ名の表記ゆれや幻覚を防げます。以下はPydanticでの分類スキーマ定義例です。
from enum import Enum
from pydantic import BaseModel, Field
from typing import List
class TicketCategory(str, Enum):
BILLING = "billing"
TECHNICAL = "technical"
ACCOUNT = "account"
OTHER = "other"
class Classification(BaseModel):
category: TicketCategory
confidence: float = Field(ge=0.0, le=1.0, description="分類の確信度")
reasoning: str = Field(description="判断理由(50字以内)")
tags: List[str] = Field(default_factory=list, max_length=5)
精度の評価と改善
分類精度を定量的に評価しないまま運用を始めると、数か月後に「誰も気付かないうちに精度が下がっていた」という事態に陥ります。最低でも100件、理想的には500件のゴールドデータを用意し、Accuracy・F1スコア・混同行列を定期的に計算する仕組みを入れてください。
import json
from collections import defaultdict
def evaluate(gold_path: str, classify_fn):
tp = defaultdict(int)
fp = defaultdict(int)
fn = defaultdict(int)
total = 0
correct = 0
with open(gold_path) as f:
for line in f:
case = json.loads(line)
pred = classify_fn(case["text"])
gold = case["label"]
total += 1
if pred == gold:
tp[gold] += 1
correct += 1
else:
fp[pred] += 1
fn[gold] += 1
accuracy = correct / total
f1_per_class = {
c: (2 * tp[c]) / (2 * tp[c] + fp[c] + fn[c] + 1e-9)
for c in set(list(tp) + list(fp) + list(fn))
}
return {"accuracy": accuracy, "f1": f1_per_class}
精度を上げるには、(1)カテゴリ定義を明確にする、(2)Few-Shot例を増やす、(3)曖昧ケースの判断基準をプロンプトに追加する、(4)Chain-of-Thoughtで推論過程を出させる、の4つが効果的です。特に「よく誤分類されるケース」を学習データとしてFew-Shotに含めると、精度が一気に改善します。
大量データの効率的処理
数万件、数十万件のテキストを分類する場合、単純にLLMをループで呼び出すとコストと時間の両方で破綻します。実務での対策は次の4つです。
- バッチAPIの活用――OpenAIやAnthropicのバッチAPIは、即時性を犠牲にする代わりに50%程度のコスト削減が可能です
- セマフォによる並列化――asyncioで並列実行しつつ、レート制限を守る設計にします
- プリフィルタ――正規表現やキーワードマッチで明らかに分類できるものはLLMを呼ばずに処理します
- 軽量モデル蒸留――LLMで大量にラベリングしてから、その結果で軽量モデル(DistilBERT等)を学習させ、推論は軽量モデルで行います
特にバッチAPIは活用率が低いため、コスト削減の余地が大きい手段です。リアルタイム性が不要なバックオフィス処理では、積極的に使うべきです。
まとめ
LLMによる自動分類は、ラベル付きデータが少ない、カテゴリ体系が頻繁に変わる、急いで運用開始したい、といった課題に強い選択肢です。精度と運用コストのトレードオフを見ながら、Zero-Shot → Few-Shot → ファインチューニング → 蒸留、と段階的に進化させる設計が合理的です。関連記事として構造化出力、プロンプトエンジニアリング入門、LLMとは、ファインチューニング実践もあわせてご参照ください。
よくある質問(FAQ)
Q1. LLMでテキスト分類はどのくらいの精度が出ますか?
A. Zero-Shotで80〜90%、Few-Shot(5例)で85〜95%程度の精度が期待できます。ファインチューニングを行えば95%以上も可能です。ただし分類タスクの難易度やカテゴリ数により大きく変動するため、ゴールドデータで実測することが必須です。
Q2. LLM分類と従来のML分類モデルの違いは?
A. LLMはラベル付き学習データなしで分類でき(Zero-Shot)、カテゴリの追加・変更が容易です。従来のMLモデルは大量のラベル付きデータが必要ですが、推論コストが低く高速です。大量処理では従来MLが有利な場合もあるため、LLMでラベリング後に軽量モデルに蒸留する設計も有効です。
Q3. 分類の精度を上げるには?
A. カテゴリの定義を明確にする、具体的な分類例(Few-Shot)を提供する、曖昧なケースの判断基準を指示に含める、Chain-of-Thoughtで推論過程を出力させる、の4つが効果的です。特に誤分類されやすいケースをFew-Shot例として追加すると、精度が劇的に改善することがあります。