Ragasにおけるコンテキスト評価指標：Context RecallとContext Precision

## はじめに

こんにちは！今回はRAG（Retrieval-Augmented Generation）システムの評価フレームワークである「Ragas」の重要な評価指標、Context RecallとContext Precisionについて解説します。これらの指標は、RAGシステムで検索されたコンテキスト（文脈情報）の質を評価する上で非常に重要です。

## Ragasとは？

Ragasは、RAGシステムの性能を評価するためのフレームワークです。RAGとは、大規模言語モデル（LLM）の回答生成プロセスに外部知識を組み込む手法で、これにより情報の正確性と最新性を向上させることができます。

Ragasでは、以下のような指標を用いてRAGシステムを評価します：
- Context Recall
- Context Precision
- その他（Faithfulness、Answer Relevancyなど）

今回は特にContext RecallとContext Precisionに焦点を当てます。

## Context Recall

### 概念

Context Recallは、「ground_truth（正解）の内容がどれだけ検索されたコンテキスト群（contexts）によってサポートされているか」を測る指標です。

### 計算プロセス

1. 大規模言語モデルを使用して、ground_truthをn個の観点（statements）に分解します
   - 例：ground_truth「佐藤は研究開発部のメンバーです」から観点「佐藤は研究開発部の所属である」を生成

2. 各観点について、検索されたコンテキスト（contexts）中に裏付けとなる情報があるかを判断します
   - 例：この観点は「佐藤は研究開発部のエンジニアで、最近新製品の開発を担当しています」というコンテキストで裏付けられます

3. ground_truthの観点のうち、コンテキストで裏付けられる観点の割合をContext Recallスコアとします
   - 例：上記の場合、1/1 = 1.0のスコアになります

つまり、Context Recallは「正解情報がどれだけ検索結果によってカバーされているか」を示す指標です。

## Context Precision

### 概念

Context Precisionは、検索されたコンテキスト群（contexts）のうち、どれだけの割合がground_truthに関連しているかを測るだけでなく、関連性の高いコンテキストがより上位にランク付けされているかも評価します。

### 計算プロセス

1. contexts内の各コンテキスト（context_i）に対して、questionとground_truthに基づいて関連性を判断します
   - 関連がある場合は1点、ない場合は0点

2. 各コンテキストについて、そのコンテキストとそれより前のコンテキストのスコア合計を分子、コンテキストの順位を分母として、precision値を計算します
   - 例：context_1「ニュートンは万有引力を発見した」が不関連（0点）、context_2「佐藤は研究開発部のエンジニアである」が関連あり（1点）の場合
   - context_1のprecision = 0/1 = 0
   - context_2のprecision = 1/2 = 0.5

3. 各コンテキストのprecision値の合計を、関連あり（1点）と判定されたコンテキストの数で割り、Context Precisionを計算します
   - 例：(0 + 0.5) / 1 = 0.5

この計算はAverage Precisionアルゴリズムに基づいており、検索システムの評価でよく使われる手法です。関連性の高いコンテキストが上位にランク付けされるほど高いスコアになります。

## Ragasの実装コード

以下は、RagasのContext Precision実装の核となる部分です：

```python
def _calculate_average_precision(self, verifications: t.List[Verification]) -> float:
    score = np.nan

    verdict_list = [1 if ver.verdict else 0 for ver in verifications]
    denominator = sum(verdict_list) + 1e-10
    numerator = sum(
        [
            (sum(verdict_list[: i + 1]) / (i + 1)) * verdict_list[i]
            for i in range(len(verdict_list))
        ]
    )
    score = numerator / denominator
    if np.isnan(score):
        logger.warning(
            "Invalid response format. Expected a list of dictionaries with keys 'verdict'"
        )
    return score
```

この関数は、各コンテキストの関連性判定（verdicts）を受け取り、Average Precisionを計算します。verdict_listは各コンテキストが関連あり（1）か関連なし（0）かを示すリストです。

Context Precisionの判定にはLLMを使用します：

```python
class ContextPrecisionPrompt(PydanticPrompt[QAC, Verification]):
    name: str = "context_precision"
    instruction: str = (
        'Given question, answer and context verify if the context was useful in arriving at the given answer. Give verdict as "1" if useful and "0" if not with json output.'
    )
    input_model = QAC
    output_model = Verification
    examples = [
        (
            QAC(
                question="アインシュタインについて教えてください",
                context="アインシュタイン（1879年3月14日 - 1955年4月18日）はドイツ生まれの理論物理学者で、相対性理論の開発で知られています。彼は1921年にノーベル物理学賞を受賞しました。",
                answer="アインシュタインは1879年3月14日生まれのドイツ出身の理論物理学者で、相対性理論で有名です。彼は1921年にノーベル物理学賞を受賞しました。",
            ),
            Verification(
                reason="提供されたコンテキストは回答を導き出すのに役立ちました。コンテキストにはアインシュタインの生涯と貢献に関する重要な情報が含まれており、それが回答に反映されています。",
                verdict=1,
            ),
        ),
        # 他の例...
    ]
```

このプロンプトを使用して、LLMは各コンテキストが回答に有用だったかどうかを判断します。

## 実用例

### Context Recallの例

**質問**: 「田中部長の部署はどこですか？」

**Ground Truth**: 「田中部長は営業部に所属しています」

**検索されたコンテキスト**: 
1. 「田中部長は2010年から営業部のトップを務めています」
2. 「営業部は昨年、売上目標を20%上回りました」

**分析**:
- Ground Truthの観点: 「田中部長は営業部に所属している」
- コンテキスト1は観点を裏付ける: ✓
- Context Recall = 1/1 = 1.0（完全にカバー）

### Context Precisionの例

**質問**: 「日本の首相は誰ですか？」

**Ground Truth**: 「岸田文雄氏が現在の日本の首相です」

**検索されたコンテキスト**:
1. 「東京は日本の首都です」（不関連=0）
2. 「岸田文雄氏は2021年10月から日本の首相を務めています」（関連あり=1）
3. 「岸田首相は外交政策に力を入れています」（関連あり=1）

**計算**:
- context_1: 0/1 = 0
- context_2: 1/2 = 0.5
- context_3: (1+1)/3 = 2/3 ≈ 0.67
- Context Precision = (0 + 0.5 + 0.67) / 2 = 0.585

## Context RecallとContext Precisionの重要性

これらの指標を組み合わせることで、RAGシステムの検索性能を総合的に評価できます：

- **高Context Recall + 低Context Precision**：必要な情報はほとんど検索されているが、不要な情報も多く含まれている
- **低Context Recall + 高Context Precision**：検索された情報は関連性が高いが、必要な情報の多くが欠けている
- **高Context Recall + 高Context Precision**：理想的な状態。必要な情報が網羅され、かつ関連性の高い順にランク付けされている

## まとめ

Ragasの評価指標であるContext RecallとContext Precisionは、RAGシステムの検索性能を評価する上で非常に重要です。

- **Context Recall**：ground_truthの内容がどれだけcontextsでカバーされているか
- **Context Precision**：contextsの中でground_truthに関連するものがどれだけあり、かつ適切にランク付けされているか

これらの指標を理解し適切に使用することで、RAGシステムの性能向上につなげることができます。特に日本語のコンテンツでRAGを実装する際にも、これらの指標は言語に依存せず有効です。

RAGシステムをより詳細に評価したい場合は、Ragasの公式ドキュメントや実装コードを参照することをお勧めします。

この記事がRAGシステムの評価に取り組む皆様のお役に立てば幸いです！