1. 概要と必要性
生成AIアプリケーションの開発において、モデルやプロンプト、および外部知識ベースの最適化を進める過程では、定性的な感覚だけでなく定量的な評価基準が必要です。特に検索拡張生成(RAG)システムや要約タスクにおいて、現在のシステムが目標とする品質水準に到達しているかを判定するためのメトリクスは不可欠です。本記事では、自然言語処理分野で広く採用されている ROUGE と BLEU の主要評価指標について解説し、その計算ロジックと実装方法を取り上げます。
2. 基礎的な用語定義
これらの評価指標を理解する上で、以下の言語処理の基本概念を押さえておく必要があります。
- N-gram: 連続する N 個の単語または文字の組み合わせを指します。
- Unigram (1-gram): 単一の単位としての単語。
- Bigram (2-gram): 隣接する 2 つの単語のペア。
評価は、通常、人間の専門家が作成した「正解テキスト(Reference)」と、モデルが生成した「予測テキスト(Candidate)」の間の重なり具合を測定することで行われます。
3. ROUGE メトリクス
ROUGE(Recall-Oriented Understudy for Gisting Evaluation)は、主にテキスト要約の品質評価に使用されます。正解文書に対してモデルがどれだけ重要な情報を網羅できたかを見る傾向があります。
3.1 ROUGE-1(Word Level)
単一の単語(unigram)に基づいて精度と再帰率を計算します。
例として、正解が「外面は冷たかった」で、生成テキストが「外面は本当に寒かった」としましょう。
- Recall(再帰率): 正解テキスト中のユニグラムが、予測テキストの中でどれくらい復元されているかを示します。
Recall = (一致したユニグラム数) / (正解のユニグラム総数)
- Precision(精度): 予測テキストに含まれるユニグラムが、どれだけの割合で正解にも含まれているかを示します。
Precision = (一致したユニグラム数) / (予測のユニグラム総数)
- F1-Score: Precision と Recall の調和平均であり、全体のバランスを示す指標となります。
ただし、ROUGE-1 は単語の順序や文脈を考慮しないため、意味が異なる場合でもスコアが高く出るという弱点があります。
3.2 ROUGE-2 と ROUGE-L
ROUGE-2 はビグラム(2 つの単語の組み合わせ)の一致度を評価するため、文脈の維持性をより正確に捉えます。
ROUGE-L は、両方の文章間で見られる最長の共通部分列(Longest Common Subsequence, LCS)を用います。これは単語順序をある程度保持しつつ、長い文章の評価に適しており、一般的な LLM 評価においては ROUGE-L の F1 スコアが信頼性の高い指標として用いられることが多いです。
3.3 ロースコアの実装例
Python 環境での実装例です。
from rouge_score import rouge_scorer
def calculate_rouge_metrics(reference_text: str, hypothesis_text: str):
"""
指定された二つのテキスト間で ROUGE スコアを算出します。
"""
scorer_instance = rouge_scorer.RougeScorer(
metrics=['rouge1', 'rouge2', 'rougeL'],
use_stemmer=True
)
# 評価実行
evaluation_results = scorer_instance.score(reference_text, hypothesis_text)
return evaluation_results
if __name__ == '__main__':
ground_truth = "この技術革新は社会構造に大きな変化をもたらします"
model_prediction = "この技術革新は社会制度に変革を与えます"
results = calculate_rouge_metrics(ground_truth, model_prediction)
print(f"ROUGE-1 F1: {results['rouge1'].fmeasure:.4f}")
print(f"ROUGE-L F1: {results['rougeL'].fmeasure:.4f}")
4. BLEU メトリクス
Bilingual Evaluation Understudy(BLEU)は、機械翻訳タスクの性能評価のために開発されました。モデルの生成出力が、参照訳とどの程度近いかを n-gram の適合率(Precision)に基づいてスコアリングします。短い文章の場合は簡略版ペナルティ適用が行われることもあります。
4.1 BLEU の特徴
BLEU は複数の長さと大きさの n-gram に対する修正精度を計算し、それらの幾何平均を求めます。一般的には 1 グラムから 4 グラムまでの重み付けを行うことが多く、完全な一致に近いほどスコアが高くなります(最大値は 1 に近い値ですが、実際には小数点以下 4 桁程度の値として扱われます)。
4.2 Bleu スコアの実装例
以下は NLTK ライブラリを使用した計算プロセスです。
import nltk
from nltk.translate.bleu_score import sentence_bleu, SmoothingFunction
# 必要に応じてトークナイザーデータをダウンロード
# nltk.download('punkt')
def compute_bleu_score(reference_corpus, candidate_sentence):
"""
候補文と参照コーパス間の BLEU スコアを計算します。
"""
# スムージング関数を設定してゼロ除算などを回避
smooth_method = SmoothingFunction().method1
score_val = sentence_bleu(
reference_corpus,
candidate_sentence,
smoothing_function=smooth_method
)
return score_val
if __name__ == '__main__':
ref_list = [['Neural', 'Networks', 'are', 'powerful', 'tools']]
pred_list = ['Neural', 'networks', 'make', 'powerful', 'tools']
final_score = compute_bleu_score(ref_list, pred_list)
print(f"Calculated BLEU Score: {final_score:.4f}")
5. 応用と留意事項
上記のメトリクスは一般的なテキスト生成に適していますが、業務特化型の RAG システムなど特定のユースケースでは、標準的なスコアだけでは不十分な場合があります。例えば、検索ドキュメントとの関連性を測るためのカスタム指標や、事実性と矛盾のないことを確認するための独自のテストセットを用いた検証手法も存在します。このような特殊な評価フローについては、将来的な課題として別途検討することが推奨されます。