自定义文本检索评测数据集#
概述#
当你需要在特定领域(如法律、医疗、金融)或私有数据上评估 Embedding 模型的检索能力时,可以构建自定义数据集进行评测。EvalScope 基于 MTEB 框架,支持通过简单的 JSONL 文件定义语料库、查询和相关性标注,快速完成端到端的检索评测。
第一步:准备数据#
目录结构#
创建一个目录,包含以下三个 JSONL 文件:
my_retrieval_data/
├── corpus.jsonl
├── queries.jsonl
└── qrels.jsonl
corpus.jsonl#
语料库文件,每行一个 JSON 对象,表示一篇待检索文档。
字段 |
类型 |
必填 |
说明 |
|---|---|---|---|
|
str |
是 |
文档唯一标识 |
|
str |
是 |
文档正文内容 |
|
str |
否 |
文档标题,用于辅助检索 |
{"_id": "doc1", "text": "气候变化正在导致更极端的天气模式。", "title": "气候变化"}
{"_id": "doc2", "text": "今天股市大幅上涨,科技股领涨。"}
{"_id": "doc3", "text": "人工智能正在通过自动化任务和提供见解来改变各种行业。"}
queries.jsonl#
查询文件,每行一个 JSON 对象,表示一条检索查询。
字段 |
类型 |
必填 |
说明 |
|---|---|---|---|
|
str |
是 |
查询唯一标识 |
|
str |
是 |
查询文本 |
{"_id": "query1", "text": "气候变化的影响是什么?"}
{"_id": "query2", "text": "今天股市上涨的原因是什么?"}
{"_id": "query3", "text": "人工智能如何改变行业?"}
qrels.jsonl#
相关性标注文件,每行一个 JSON 对象,定义查询与文档之间的相关性。
字段 |
类型 |
必填 |
说明 |
|---|---|---|---|
|
str |
是 |
对应 queries.jsonl 中的 |
|
str |
是 |
对应 corpus.jsonl 中的 |
|
int/float |
是 |
相关性分数 |
{"query-id": "query1", "corpus-id": "doc1", "score": 1}
{"query-id": "query2", "corpus-id": "doc2", "score": 1}
{"query-id": "query3", "corpus-id": "doc3", "score": 1}
score 含义说明:
二值标注(0/1):
1表示相关,0表示不相关。适用于大多数检索场景。连续分数:使用多级相关性(如 0、1、2、3),数值越大表示越相关。适用于需要区分"部分相关"和"高度相关"的精细评测。
数据质量建议#
小技巧
推荐语料库至少包含 100 篇文档,查询至少 50 条,以获得统计上有意义的评测结果。
确保每个查询至少有 1 个相关文档标注。
如果使用二值标注,建议同时标注负样本(score=0),以更准确地评估模型区分能力。
语料库中应包含足够多与查询无关的"干扰"文档,模拟真实检索场景。
第二步:配置并运行评测#
完整配置示例#
from evalscope.run import run_task
task_cfg = {
"work_dir": "outputs",
"eval_backend": "RAGEval",
"eval_config": {
"tool": "MTEB",
"models": [
{
"model_name_or_path": "AI-ModelScope/m3e-base",
"pooling_mode": None,
"max_seq_length": 512,
"prompt": "",
"model_kwargs": {"torch_dtype": "auto"},
"encode_kwargs": {
"batch_size": 128,
},
}
],
"eval": {
"custom_tasks": [
{
"name": "CustomRetrieval",
"data_path": "my_retrieval_data",
}
],
"overwrite_results": True,
"limits": 500,
},
},
}
run_task(task_cfg=task_cfg)
运行命令#
将上述代码保存为 run_eval.py,然后执行:
python run_eval.py
结果解读#
评测完成后,结果保存在 outputs/ 目录下,主要指标包括:
NDCG@k:归一化折损累计增益,衡量排序质量(k=1,3,5,10)
MAP@k:平均精度均值
Recall@k:召回率
Precision@k:精确率
分数范围为 0~1,越高表示检索效果越好。
参数参考#
custom_tasks 列表中每个任务对应一个 CustomTaskConfig,可配置字段如下:
参数 |
类型 |
默认值 |
说明 |
|---|---|---|---|
|
str |
|
任务名称,用于标识评测结果 |
|
str |
(必填) |
数据集目录路径,需包含 |
|
List[str] |
|
评测分割列表 |
备注
其他评测参数(如 models、limits、overwrite_results 等)与默认配置一致,详见 MTEB 评测参数说明。
常见问题#
字段格式错误#
数据文件必须是 JSONL 格式(每行一个独立的 JSON 对象),不是标准 JSON 数组格式。
_id字段值必须是字符串类型,即使是数字 ID 也应写为"123"而非123。qrels.jsonl中的字段名带连字符:query-id和corpus-id,不是下划线。
数据量太少的影响#
语料库文档过少(如少于 10 篇)时,Recall@10 等指标可能始终为 1.0,无法有效区分模型好坏。
查询过少会导致评测结果方差较大,不具备统计显著性。
建议根据实际业务场景,准备至少百条量级的数据。
从其他格式转换#
如果已有 TSV 或 CSV 格式的数据,可以使用以下方式转换为 JSONL:
import csv
import json
# TSV/CSV 转 corpus.jsonl 示例
with open("corpus.tsv", "r") as fin, open("corpus.jsonl", "w") as fout:
reader = csv.DictReader(fin, delimiter="\t") # CSV 使用 delimiter=","
for row in reader:
obj = {"_id": row["id"], "text": row["text"]}
fout.write(json.dumps(obj, ensure_ascii=False) + "\n")