📚 シリーズ: AI for Scienceとは? #7
本記事では、GraphRAGの検索品質をMicrosoft公式指標で評価し、日本語研究論文向けの最適な設定を導き出します。
はじめに
前回までの記事で、GraphRAGの基本構築から日本語チャンキング最適化まで解説しました。しかし、「本当にGraphRAGは従来のRAGより優れているのか?」「どの検索モードを使えばいいのか?」という疑問が残ります。
本記事では、Microsoft Research公式のベンチマーク手法を用いてGraphRAGの検索品質を定量評価し、日本語研究論文に最適な設定を明らかにします。
🎯 対象読者
- GraphRAGを本番環境で使いたい研究者・エンジニア
- RAGシステムの品質評価方法を知りたい方
- コストと品質のトレードオフを理解したい方
📋 本記事のゴール
- GraphRAGの4つの検索モードの特性を理解する
- LLM-as-Judgeによる評価手法を実装する
- 日本語研究論文に最適な設定を導き出す
🔍 GraphRAGの検索モード比較
GraphRAG 2.7.x では、4つの主要な検索モードが利用可能です。
検索モード一覧
| 検索モード | 用途 | 特徴 | コスト |
|---|---|---|---|
| Local Search | 特定エンティティの質問 | エンティティとテキストチャンクを組み合わせ | 低 |
| Global Search | データセット全体の質問 | コミュニティレポートのMap-Reduce | 高 |
| DRIFT Search | ハイブリッド検索 | グローバル→ローカルの反復深化 | 中 |
| LazyGraphRAG | コスト効率重視 | 事前要約なし、オンデマンド処理 | 最低 |
質問タイプ別の使い分け
質問タイプ → 推奨検索モード
- 「BERTの事前学習タスクは?」 → Local Search(特定エンティティに関する質問)
- 「この論文集の主要テーマは?」 → Global Search / LazyGraphRAG(データセット全体に関する質問)
- 「深層学習の理論と応用を比較」 → DRIFT Search(複合的な質問)
📊 Microsoft公式評価指標
Microsoft Researchは、GraphRAGの品質評価に3つの主要指標を使用しています。
LLM-as-Judge評価指標(3指標)
| 指標 | 英語名 | 説明 | 評価観点 |
|---|---|---|---|
| 網羅性 | Comprehensiveness | 質問のすべての側面をカバーしているか | 情報の完全性 |
| 多様性 | Diversity | 異なる視点・洞察を提供しているか | 視点の豊富さ |
| エンパワーメント | Empowerment | 読者が判断を下せるほど理解を助けるか | 実用性 |
これらの指標は、Microsoft Researchの論文 "From Local to Global: A Graph RAG Approach to Query-Focused Summarization" で定義されています。
RAGAS評価指標(補助指標)
RAGシステム専用の評価フレームワーク RAGAS も併用します。
| カテゴリ | 指標 | 説明 |
|---|---|---|
| 生成品質 | Faithfulness | 回答がコンテキストに忠実か(0-1) |
| 生成品質 | Answer Relevancy | 回答が質問に適切か |
| 検索品質 | Context Relevancy | 取得コンテキストが質問に関連するか |
| 検索品質 | Context Recall | 正解に必要なコンテキストを取得できたか |
# RAGAS インストール
pip install ragas
# 基本的な使用方法
from ragas import evaluate
from ragas.metrics import faithfulness, answer_relevancy
result = evaluate(
dataset=your_dataset,
metrics=[faithfulness, answer_relevancy],
)
📈 ベンチマーク結果(Microsoft Research公式)
Microsoft Researchが公開している公式ベンチマーク結果を紹介します。
DRIFT Search vs Local Search
データセット: AP News 5,000+記事
質問数: 50 local questions
| 指標 | DRIFT勝率 |
|---|---|
| Comprehensiveness | 78% |
| Diversity | 81% |
💡 DRIFT Searchは、Local Searchに対して網羅性で78%、多様性で81%の勝率を達成しました。
LazyGraphRAG vs 他手法
データセット: AP News 5,590記事
質問数: 100 (50 local + 50 global)
🚀 LazyGraphRAG の圧倒的なコスト効率
- インデックスコスト: GraphRAG Full の 0.1%
- クエリコスト同等で: 全競合手法に勝利(local queries)
- Global Searchと同等品質で: 700倍低コスト
- 4%のコストで: 全手法に有意に勝利(local + global)
| 条件 | LazyGraphRAG勝率 | 相対コスト |
|---|---|---|
| Z100_Lite vs SS_8K | 全指標で有意に優位 | 同等 |
| Z500 vs C2 | 全指標で有意に優位 | 4% |
| Z100 vs C2 Global | 同等品質 | 0.14% (700倍安) |
Dynamic Global Search vs Static Global Search
| Dynamic Search Level | 網羅性勝率 | 多様性勝率 | エンパワーメント勝率 | コスト削減 |
|---|---|---|---|---|
| Level 1 | 49.5% | 46.0% | 48.0% | -77% |
| Level 3 | 58.8% ✓ | 48.0% | 60.0% ✓ | +34% |
✓ = 統計的に有意
🧪 LLM-as-Judge実装
Microsoft方式のLLM-as-Judge評価を実装します。
評価プロンプト
EVALUATION_PROMPT = """あなたは RAG システムの回答品質を評価する専門家です。
以下の回答を評価してください。
【質問】
{question}
【回答】
{answer}
以下の観点で1-5のスコアを付けてください(5が最高):
1. **網羅性 (Comprehensiveness)**: 質問のすべての側面をカバーしているか
- 5: 完全に網羅している
- 3: 主要な点はカバーしている
- 1: 重要な側面が欠けている
2. **多様性 (Diversity)**: 異なる視点・洞察を提供しているか
- 5: 多角的な視点を提供
- 3: いくつかの視点を提供
- 1: 単一の視点のみ
3. **有用性 (Empowerment)**: 読者が判断を下せるほど理解を助けるか
- 5: 非常に有用で行動可能
- 3: ある程度有用
- 1: あまり有用でない
JSON形式で出力してください:
{{"comprehensiveness": <1-5>, "diversity": <1-5>, "empowerment": <1-5>, "reason": "..."}}
"""
ペアワイズ比較(勝率算出用)
PAIRWISE_PROMPT = """以下の2つの回答を比較し、どちらが優れているか判定してください。
【質問】
{question}
【回答A】({method_a})
{answer_a}
【回答B】({method_b})
{answer_b}
【評価観点】
{metric}
どちらの回答が優れていますか?
- "A": 回答Aが優れている
- "B": 回答Bが優れている
- "tie": 同等
出力: {{"winner": "<A|B|tie>", "reason": "<理由>"}}
"""
評価スクリプト
import asyncio
import json
from dataclasses import dataclass
@dataclass
class EvaluationResult:
"""評価結果"""
query: str
search_mode: str
comprehensiveness: float
diversity: float
empowerment: float
latency_ms: float
reason: str
class GraphRAGEvaluator:
"""GraphRAG評価エンジン"""
async def evaluate_answer(self, question: str, answer: str) -> EvaluationResult:
"""LLM-as-Judgeで回答を評価"""
prompt = EVALUATION_PROMPT.format(
question=question,
answer=answer,
)
response = await self.llm.agenerate(
messages=[{"role": "user", "content": prompt}],
max_tokens=500,
)
# JSONをパース
scores = json.loads(response)
return EvaluationResult(
query=question,
search_mode=self.current_mode,
comprehensiveness=scores["comprehensiveness"],
diversity=scores["diversity"],
empowerment=scores["empowerment"],
latency_ms=self.last_latency,
reason=scores["reason"],
)
🇯🇵 日本語評価の課題と対策
日本語でRAGを評価する際の特有の課題と対策を紹介します。
課題一覧
| 課題 | 説明 | 対策 |
|---|---|---|
| 形態素解析 | 分かち書きなしで文境界が曖昧 | GiNZA/MeCab/Sudachiを使用 |
| 敬語・文体 | 同じ意味でも異なる表現 | 正規化・パラフレーズ考慮 |
| 同義語 | 「AI」「人工知能」「エーアイ」 | 辞書ベースの正規化 |
| 評価データセット | 日本語RAGベンチマークが少ない | 自作またはJGLUE活用 |
日本語同義語正規化の例
JAPANESE_SYNONYMS = {
"AI": ["人工知能", "エーアイ", "Artificial Intelligence"],
"機械学習": ["ML", "Machine Learning", "マシンラーニング"],
"深層学習": ["ディープラーニング", "Deep Learning", "DL"],
"自然言語処理": ["NLP", "Natural Language Processing"],
}
def normalize_japanese_text(text: str) -> str:
"""日本語テキストの同義語を正規化"""
for canonical, variants in JAPANESE_SYNONYMS.items():
for variant in variants:
text = text.replace(variant, canonical)
return text
日本語評価用データセット
| データセット | 説明 | 用途 |
|---|---|---|
| JGLUE | 日本語NLU評価用 | 文理解能力評価 |
| JCommonsenseQA | 日本語常識推論 | 常識的質問への回答能力 |
| JSQuAD | 日本語読解 | 文書からの情報抽出能力 |
⚡ パフォーマンス最適化設定
コスト最適化の優先順位
📉 コスト最適化の推奨順序
- LazyGraphRAG を検討 → インデックスコスト 0.1%
- Dynamic Global Search を使用 → クエリコスト -77%
- community_level を調整 → Level 2 が多くの場合で最適
- 小規模LLMを評価用に使用 → GPT-4o-mini等
推奨設定(settings.yaml)
# GraphRAG 2.7.x 推奨設定
# インデックス設定
chunks:
size: 800 # 日本語向け(英語より小さめ)
overlap: 80
# クエリ設定
local_search:
text_unit_prop: 0.5
community_prop: 0.1
conversation_history_max_turns: 5
top_k_entities: 10
top_k_relationships: 10
max_tokens: 12000
global_search:
community_level: 2 # デフォルト推奨
max_tokens: 12000
use_dynamic_community_selection: true # コスト77%削減
drift_search:
primer_top_k: 10
follow_up_iterations: 2
community_level: 2
質問タイプ別の最適モード選択
def select_optimal_search_mode(question: str) -> str:
"""質問タイプに基づいて最適な検索モードを選択"""
# グローバル質問のキーワード
global_keywords = ["主要", "全体", "テーマ", "傾向", "動向", "要約", "概要"]
# ローカル質問のキーワード
local_keywords = ["とは", "説明", "定義", "特徴", "方法", "手順"]
# 複合質問のキーワード
hybrid_keywords = ["比較", "違い", "関係", "影響", "分析"]
if any(kw in question for kw in global_keywords):
return "global" # または "lazygraphrag" でコスト削減
elif any(kw in question for kw in hybrid_keywords):
return "drift"
else:
return "local"
📊 実験結果の可視化
評価結果をMarkdownテーブルとMermaidグラフで可視化する方法を紹介します。
結果分析スクリプト
import pandas as pd
def generate_evaluation_report(df: pd.DataFrame) -> str:
"""評価結果からMarkdownレポートを生成"""
# 検索モード別平均スコア
mode_summary = df.groupby("search_mode").agg({
"comprehensiveness": "mean",
"diversity": "mean",
"empowerment": "mean",
"latency_ms": "mean",
}).round(2)
report = "## 検索モード別平均スコア\n\n"
report += "| 検索モード | 網羅性 | 多様性 | 有用性 | レイテンシ(ms) |\n"
report += "|-----------|--------|--------|--------|---------------|\n"
for mode, row in mode_summary.iterrows():
report += f"| {mode} | {row['comprehensiveness']} | "
report += f"{row['diversity']} | {row['empowerment']} | "
report += f"{row['latency_ms']:.0f} |\n"
return report
勝率チャート(Mermaid)
📝 まとめ
検索モード選択ガイド
| ユースケース | 推奨モード | 理由 |
|---|---|---|
| 特定の概念を調べたい | Local Search | 低コスト、高速 |
| 論文集全体の傾向を知りたい | LazyGraphRAG Z500 | コスト効率最高 |
| 複数トピックを横断分析 | DRIFT Search | 網羅性・多様性が高い |
| コスト制約が厳しい | LazyGraphRAG Z100 | 品質維持でコスト最小 |
日本語研究論文向けの推奨設定
# 日本語研究論文向け推奨設定
chunks:
size: 800
overlap: 80
encoding_model: "cl100k_base"
# Ollamaローカル環境の場合
llm:
model: "qwen2.5:7b"
api_base: "http://localhost:11434/v1"
# エンベディング
embeddings:
model: "bge-m3" # 100言語対応、日本語に強い
📚 参考文献
- GraphRAG Query Engine Overview - Microsoft, 2025
- LazyGraphRAG: Setting a new standard for quality and cost - Microsoft Research, 2024-11-25
- Introducing DRIFT Search - Microsoft Research, 2024-10-31
- GraphRAG: Improving global search via dynamic community selection - Microsoft Research, 2024-11-15
- RAGAS - Evaluation framework for RAG - VibrantLabs, v0.4.3
- Evaluation of RAG performance basics - Microsoft Fabric
📖 シリーズ記事
- #1:GraphRAGで日本語論文を扱う(導入編)
- #2:GraphRAGで日本語論文を扱う(Ollama設定編)
- #3:GraphRAGで日本語論文を扱う(PDFからMarkdownへの変換編)
- #4:GraphRAGで日本語論文を扱う(インデックス作成編)
- #5:GraphRAGで日本語論文を扱う(検索編)
- #6:GraphRAGで日本語論文を扱う(LazyGraphRAG実装編)
- #7:GraphRAGで日本語論文を扱う(検索精度評価とパフォーマンス最適化編)(本記事)