评估

CrossEncoder 在 sentence_transformers.cross_encoder.evaluation 中有自己的评估类。

CrossEncoderRerankingEvaluator

class sentence_transformers.cross_encoder.evaluation.CrossEncoderRerankingEvaluator(samples: list[dict[str, str | list[str]]], at_k: int = 10, always_rerank_positives: bool = True, name: str = '', batch_size: int = 64, show_progress_bar: bool = False, write_csv: bool = True, mrr_at_k: int | None = None)[source]

此类别用于评估 CrossEncoder 模型在重新排名任务中的表现。

给定一个查询和文档列表,它会计算所有可能的文档的评分 [query, doc_i] 并按降序排列。然后,计算 MRR@10NDCG@10MAP 以衡量排名质量。

评估器需要一个样本列表。每个样本都是一个字典,包含强制性的“query”和“positive”键,以及一个“negative”或“documents”键。“query”是搜索查询,“positive”是相关文档列表,“negative”是不相关文档列表。或者,可以使用“documents”键来提供所有文档的列表,包括正面文档。在这种情况下,评估器会假定列表已按相似度排名,最相似的文档在前,并将报告重新排名性能以及重新排名之前的性能。这对于衡量在第一阶段检索(例如 SentenceTransformer 模型)之上重新排名的改进非常有用。

请注意,默认情况下最大评分为 1.0,因为所有正面文档都包含在排名中。这可以通过使用带有 documents 而不是 negative 的样本来关闭,即包含所有文档(包括正面文档)的排名列表,同时设置 always_rerank_positives=Falsealways_rerank_positives=False 仅在使用 documents 而不是 negative 时有效。

参数:
  • samples (list) –

    一个字典列表,其中每个字典表示一个样本并包含以下键:- 'query'(必填):搜索查询。- 'positive'(必填):正面(相关)文档列表。- 'negative'(可选):负面(不相关)文档列表。与 'documents' 互斥。- 'documents'(可选):所有文档的列表,包括正面文档。此列表假定为

    按相似度排名,最相似的文档在前。与 'negative' 互斥。

  • at_k (int, 可选) – 对于每个查询,仅考虑前 k 个最相似的文档进行评估。默认为 10。

  • always_rerank_positives (bool) – 如果为 True,则始终包含所有正面文档进行评估。如果为 False,则仅包含已在文档列表中的正面文档。如果您的 samples 包含 negative 而不是 documents,则始终设置为 True。使用 documents 时,将其设置为 True 将产生更有用的评估信号,但将其设置为 False 将产生更真实的评估。默认为 True。

  • name (str, optional) – 评估器的名称,用于日志记录、保存到 CSV 和模型卡。默认为 ""。

  • batch_size (int) – 计算句子嵌入的批次大小。默认为 64。

  • show_progress_bar (bool) – 计算嵌入时显示进度条。默认为 False。

  • write_csv (bool) – 将结果写入 CSV 文件。默认为 True。

  • mrr_at_k (Optional[int], 可选) – 已弃用的参数。请改用 at_k。默认为 None。

示例

from sentence_transformers import CrossEncoder
from sentence_transformers.cross_encoder.evaluation import CrossEncoderRerankingEvaluator
from datasets import load_dataset

# Load a model
model = CrossEncoder("cross-encoder/ms-marco-MiniLM-L6-v2")

# Load a dataset with queries, positives, and negatives
eval_dataset = load_dataset("microsoft/ms_marco", "v1.1", split="validation")

samples = [
    {
        "query": sample["query"],
        "positive": [text for is_selected, text in zip(sample["passages"]["is_selected"], sample["passages"]["passage_text"]) if is_selected],
        "documents": sample["passages"]["passage_text"],
        # or
        # "negative": [text for is_selected, text in zip(sample["passages"]["is_selected"], sample["passages"]["passage_text"]) if not is_selected],
    }
    for sample in eval_dataset
]

# Initialize the evaluator
reranking_evaluator = CrossEncoderRerankingEvaluator(
    samples=samples,
    name="ms-marco-dev",
    show_progress_bar=True,
)
results = reranking_evaluator(model)
'''
CrossEncoderRerankingEvaluator: Evaluating the model on the ms-marco-dev dataset:
Queries: 10047    Positives: Min 0.0, Mean 1.1, Max 5.0   Negatives: Min 1.0, Mean 7.1, Max 10.0
         Base  -> Reranked
MAP:     34.03 -> 62.36
MRR@10:  34.67 -> 62.96
NDCG@10: 49.05 -> 71.05
'''
print(reranking_evaluator.primary_metric)
# => ms-marco-dev_ndcg@10
print(results[reranking_evaluator.primary_metric])
# => 0.7104656857184184

CrossEncoderNanoBEIREvaluator

class sentence_transformers.cross_encoder.evaluation.CrossEncoderNanoBEIREvaluator(dataset_names: list[~typing.Literal['climatefever', 'dbpedia', 'fever', 'fiqa2018', 'hotpotqa', 'msmarco', 'nfcorpus', 'nq', 'quoraretrieval', 'scidocs', 'arguana', 'scifact', 'touche2020'] | str] | None = None, dataset_id: str = 'sentence-transformers/NanoBEIR-en', rerank_k: int = 100, at_k: int = 10, always_rerank_positives: bool = True, batch_size: int = 32, show_progress_bar: bool = False, write_csv: bool = True, aggregate_fn: ~collections.abc.Callable[[list[float]], float] = <function mean>, aggregate_key: str = 'mean')[source]

此类别用于评估 CrossEncoder 模型在 NanoBEIR 信息检索数据集集合上的表现。

该集合是一组基于 BEIR 集合的数据集,但尺寸显着减小,因此可以在全面评估之前快速评估模型的检索性能。这些数据集可在 Hugging Face 的 NanoBEIR 集合中获取。此评估器将返回与 CrossEncoderRerankingEvaluator 相同的指标(即 MRR@k、nDCG@k、MAP),适用于每个数据集以及平均值。

评估器不会对每个查询的所有文档进行重新排名,而只会对来自 BM25 排名的 rerank_k 个文档进行重新排名。当您的日志设置为 INFO 时,评估器将打印每个数据集的 MAP、MRR@k 和 nDCG@k,以及所有数据集的平均值。

请注意,默认情况下最大评分为 1.0,因为所有正面文档都包含在排名中。这可以通过设置 always_rerank_positives=False 来关闭,此时最大评分将受到 BM25 在前 rerank_k 个文档中排名的正面文档数量的限制。

注意

此评估器使用 NanoBEIR_R{rerank_k}_{aggregate_key}_{metric} 格式的键输出结果,其中 metricmapmrr@{at_k}ndcg@{at_k} 之一,而 rerank_kaggregate_keyat_k 是评估器的参数。主要指标是 ndcg@{at_k}。默认情况下,主要指标的名称是 NanoBEIR_R100_mean_ndcg@10

对于每个数据集的结果,键的格式为 Nano{dataset_name}_R{rerank_k}_{metric},例如 NanoMSMARCO_R100_mrr@10

这些可以与 CrossEncoderTrainingArguments 中的 load_best_model_at_end=True 一起用作 metric_for_best_model,以根据特定的感兴趣指标自动加载最佳模型。

警告

当不手动指定 dataset_names 时,评估器将排除 arguanatouche2020 数据集,因为它们的论证检索任务与其他数据集有显著差异。这与 NanoBEIREvaluatorSparseNanoBEIREvaluator 不同,后者默认包含所有数据集。

参数:
  • dataset_names (List[str]) – 要评估的数据集的简称(例如,“climatefever”,“msmarco”)。如果未指定,则使用除 arguana 和 touche2020 之外的所有预定义 NanoBEIR 数据集。可用数据集的完整列表为:“climatefever”、“dbpedia”、“fever”、“fiqa2018”、“hotpotqa”、“msmarco”、“nfcorpus”、“nq”、“quoraretrieval”、“scidocs”、“arguana”、“scifact”和“touche2020”。

  • dataset_id (str) – 从中加载数据集的 HuggingFace 数据集 ID。默认为 “sentence-transformers/NanoBEIR-en”。该数据集必须包含每个 NanoBEIR 数据集的 “corpus”、“queries”、“qrels” 和 “bm25” 子集,存储在名为 Nano{DatasetName} 的分割下(例如,NanoMSMARCONanoNFCorpus)。

  • rerank_k (int) – 从 BM25 排名中重新排名的文档数量。默认为 100。

  • at_k (int, 可选) – 对于每个查询,仅考虑前 k 个最相似的文档进行评估。默认为 10。

  • always_rerank_positives (bool) – 如果为 True,则始终包含所有正面文档进行评估。如果为 False,则仅包含已在文档列表中的正面文档。如果您的 samples 包含 negative 而不是 documents,则始终设置为 True。使用 documents 时,将其设置为 True 将产生更有用的评估信号,但将其设置为 False 将产生更真实的评估。默认为 True。

  • batch_size (int) – 计算句子嵌入的批次大小。默认为 64。

  • show_progress_bar (bool) – 计算嵌入时显示进度条。默认为 False。

  • write_csv (bool) – 将结果写入 CSV 文件。默认为 True。

  • aggregate_fn (Callable[[list[float]], float]) – 用于聚合分数的函数。默认为 np.mean。

  • aggregate_key (str) – 用于聚合分数的键。默认为 "mean"。

提示

请参阅 Hugging Face 上的此 NanoBEIR 数据集集合,其中包含适用于不同语言的有效 NanoBEIR dataset_id 选项。数据集必须包含带有 BM25 排名信息的“bm25”子集,才能进行重新排名评估。

示例

from sentence_transformers.cross_encoder import CrossEncoder
from sentence_transformers.cross_encoder.evaluation import CrossEncoderNanoBEIREvaluator
import logging

logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(message)s")

# Load a model
model = CrossEncoder("cross-encoder/ms-marco-MiniLM-L6-v2")

# Load & run the evaluator
dataset_names = ["msmarco", "nfcorpus", "nq"]
evaluator = CrossEncoderNanoBEIREvaluator(dataset_names)
results = evaluator(model)
'''
NanoBEIR Evaluation of the model on ['msmarco', 'nfcorpus', 'nq'] dataset:
Evaluating NanoMSMARCO
CrossEncoderRerankingEvaluator: Evaluating the model on the NanoMSMARCO dataset:
         Base  -> Reranked
MAP:     48.96 -> 60.35
MRR@10:  47.75 -> 59.63
NDCG@10: 54.04 -> 66.86

Evaluating NanoNFCorpus
CrossEncoderRerankingEvaluator: Evaluating the model on the NanoNFCorpus dataset:
Queries: 50   Positives: Min 1.0, Mean 50.4, Max 463.0        Negatives: Min 54.0, Mean 92.8, Max 100.0
         Base  -> Reranked
MAP:     26.10 -> 34.61
MRR@10:  49.98 -> 58.85
NDCG@10: 32.50 -> 39.30

Evaluating NanoNQ
CrossEncoderRerankingEvaluator: Evaluating the model on the NanoNQ dataset:
Queries: 50   Positives: Min 1.0, Mean 1.1, Max 2.0   Negatives: Min 98.0, Mean 99.0, Max 100.0
         Base  -> Reranked
MAP:     41.96 -> 70.98
MRR@10:  42.67 -> 73.55
NDCG@10: 50.06 -> 75.99

CrossEncoderNanoBEIREvaluator: Aggregated Results:
         Base  -> Reranked
MAP:     39.01 -> 55.31
MRR@10:  46.80 -> 64.01
NDCG@10: 45.54 -> 60.72
'''
print(evaluator.primary_metric)
# NanoBEIR_R100_mean_ndcg@10
print(results[evaluator.primary_metric])
# 0.60716840988382

评估自定义/翻译数据集

import logging
from pprint import pprint

from sentence_transformers.cross_encoder import CrossEncoder
from sentence_transformers.cross_encoder.evaluation import CrossEncoderNanoBEIREvaluator

logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(message)s")

# Load a model
model = CrossEncoder("cross-encoder/mmarco-mMiniLMv2-L12-H384-v1")

# Load & run the evaluator
evaluator = CrossEncoderNanoBEIREvaluator(
    ["msmarco", "nq"],
    dataset_id="Serbian-AI-Society/NanoBEIR-sr",
    batch_size=16,
)
results = evaluator(model)
print(results[evaluator.primary_metric])
pprint({key: value for key, value in results.items() if "ndcg@10" in key})

CrossEncoderClassificationEvaluator

class sentence_transformers.cross_encoder.evaluation.CrossEncoderClassificationEvaluator(sentence_pairs: list[list[str]], labels: list[int], *, name: str = '', batch_size: int = 32, show_progress_bar: bool | None = None, write_csv: bool = True, **kwargs)[source]

根据预测类与金标签的准确性评估 CrossEncoder 模型。评估器需要一个句子对列表和一个金标签列表。如果模型只有一个输出,则假定为二元分类模型,评估器将计算准确率、F1、精确率、召回率和平均精确率。如果模型有多个输出,评估器将计算宏 F1、微 F1 和加权 F1。

参数:
  • sentence_pairs (List[List[str]]) – 句子对列表,每个元素都是一个包含两个字符串的列表。

  • labels (List[int]) – 一个整数列表,包含每个句子对的金标签。

  • name (str) – 评估器的名称,用于生成的模型卡。

  • batch_size (int) – 用于评估的批处理大小。默认为 32。

  • show_progress_bar (bool) – 输出进度条。默认为 None,在日志级别为 INFO 或 DEBUG 时显示进度条。

  • write_csv (bool) – 将结果写入 CSV 文件。如果 CSV 文件已存在,则追加值。默认为 True。

示例

from sentence_transformers import CrossEncoder
from sentence_transformers.cross_encoder.evaluation import CrossEncoderClassificationEvaluator
from datasets import load_dataset

# Load a model
model = CrossEncoder("cross-encoder/nli-deberta-v3-base")

# Load a dataset with two text columns and a class label column (https://hugging-face.cn/datasets/sentence-transformers/all-nli)
eval_dataset = load_dataset("sentence-transformers/all-nli", "pair-class", split="dev[-1000:]")

# Create a list of pairs, and map the labels to the labels that the model knows
pairs = list(zip(eval_dataset["premise"], eval_dataset["hypothesis"]))
label_mapping = {0: 1, 1: 2, 2: 0}
labels = [label_mapping[label] for label in eval_dataset["label"]]

# Initialize the evaluator
cls_evaluator = CrossEncoderClassificationEvaluator(
    sentence_pairs=pairs,
    labels=labels,
    name="all-nli-dev",
)
results = cls_evaluator(model)
'''
CrossEncoderClassificationEvaluator: Evaluating the model on all-nli-dev dataset:
Macro F1:           89.43
Micro F1:           89.30
Weighted F1:        89.33
'''
print(cls_evaluator.primary_metric)
# => all-nli-dev_f1_macro
print(results[cls_evaluator.primary_metric])
# => 0.8942858180262628

CrossEncoderCorrelationEvaluator

class sentence_transformers.cross_encoder.evaluation.CrossEncoderCorrelationEvaluator(sentence_pairs: list[list[str]], scores: list[float], name: str = '', batch_size: int = 32, show_progress_bar: bool | None = None, write_csv: bool = True)[source]

此评估器可与 CrossEncoder 类一起使用。给定句子对和连续评分,它计算句子对的预测评分与金评分之间的 Pearson 和 Spearman 相关性。

参数:
  • sentence_pairs (List[List[str]]) – 句子对列表,每个元素都是一个包含两个字符串的列表。

  • labels (List[int]) – 一个整数列表,包含每个句子对的金标签。

  • name (str) – 评估器的名称,用于生成的模型卡。

  • batch_size (int) – 用于评估的批处理大小。默认为 32。

  • show_progress_bar (bool) – 输出进度条。默认为 None,在日志级别为 INFO 或 DEBUG 时显示进度条。

  • write_csv (bool) – 将结果写入 CSV 文件。如果 CSV 文件已存在,则追加值。默认为 True。

示例

from datasets import load_dataset
from sentence_transformers import CrossEncoder
from sentence_transformers.cross_encoder.evaluation import CrossEncoderCorrelationEvaluator

# Load a model
model = CrossEncoder("cross-encoder/ms-marco-MiniLM-L6-v2")

# Load the STSB dataset (https://hugging-face.cn/datasets/sentence-transformers/stsb)
eval_dataset = load_dataset("sentence-transformers/stsb", split="validation")
pairs = list(zip(eval_dataset["sentence1"], eval_dataset["sentence2"]))

# Initialize the evaluator
dev_evaluator = CrossEncoderCorrelationEvaluator(
    sentence_pairs=pairs,
    scores=eval_dataset["score"],
    name="sts_dev",
)
results = dev_evaluator(model)
'''
CrossEncoderCorrelationEvaluator: Evaluating the model on sts_dev dataset:
Correlation: Pearson: 0.8503 Spearman: 0.8486
'''
print(dev_evaluator.primary_metric)
# => sts_dev_spearman
print(results[dev_evaluator.primary_metric])
# => 0.8486467897872038