BLEU/ROUGE/METEOR/CIDEr/BERTScore 的计算与缺陷?
- —用 sacrebleu 计算 BLEU,手写 ROUGE-L 的 LCS
核心概念
这些指标是用于评估自然语言生成(NLG)任务(如机器翻译、文本摘要、图像描述)质量的自动化度量标准。它们通过将模型生成的文本(候选句)与一个或多个高质量的人工参考文本(参考句)进行比较来计算得分。
- BLEU (Bilingual Evaluation Understudy): 主要衡量候选句中 n-gram(连续的 n 个词)在参考句中出现的精确率,并引入简短惩罚项,常用于机器翻译。
- ROUGE (Recall-Oriented Understudy for Gisting Evaluation): 主要衡量参考句中的 n-gram 在候选句中出现的召回率,因此更适合评估摘要任务,因为它关心摘要是否覆盖了原文的关键信息。
- METEOR (Metric for Evaluation of Translation with Explicit ORdering): 基于 unigram(单个词)的精确率和召回率的 F-score,但加入了同义词、词干匹配和语序惩罚,试图更全面地衡量语义相似性。
- CIDEr (Consensus-based Image Description Evaluation): 专为图像描述设计,通过计算候选句和所有参考句之间 n-gram 的 TF-IDF 加权余弦相似度,强调那些在参考句集中达成共识且信息量丰富的词语。
- BERTScore: 利用预训练语言模型(如
BERT)的上下文词向量,计算候选句和参考句中每个词之间的余弦相似度,从而在语义层面进行评估,而非词汇表面的重叠。
原理与推导
BLEU (Bilingual Evaluation Understudy)
BLEU 的核心思想是“一个好的机器翻译是与专业人工翻译相近的翻译”。它衡量的是“精确率”——生成的词有多少是正确的。
1. 修正的 n-gram 精确率 () 传统的精确率会错误地奖励重复输出正确词语的句子。例如:
- 候选句 (c): "the the the the the the the"
- 参考句 (r): "the cat is on the mat" 对于 unigram "the",传统精确率是 7/7 = 1.0,这显然不合理。BLEU 引入了“截断计数”(Clipped Count)。
截断计数: 一个 n-gram 在候选句中的计数,不能超过它在任何单个参考句中出现的最大次数。 在上面的例子中,"the" 在参考句中出现 2 次,所以 "the" 的截断计数为 2。
修正的精确率公式为:
其中分母是候选句中 n-gram 的总数,分子是截断后的计数总和。
2. 简短惩罚 (Brevity Penalty, BP) 只用精确率会导致模型倾向于生成非常短的句子,因为短句子更容易获得高精确率。为解决此问题,引入了简短惩罚。
- 是候选句的总长度。
- 是有效参考句长度。当有多个参考句时,选择与候选句长度最接近的那个参考句的长度。
如果候选句长度大于参考句长度 (),不惩罚 ()。如果候选句更短,则惩罚,且长度差越大,惩罚越重。
3. 最终得分 BLEU 分数是不同 n-gram 修正精确率的加权几何平均值,再乘以简短惩罚。通常使用 N=4。
- 是权重,通常取均匀权重 。
- 使用几何平均意味着只要有一个 (例如没有任何 4-gram 匹配),最终的 BLEU 分数就会是 0,这是一种严厉的惩罚。
复杂度: 计算 n-gram 计数的时间复杂度为 ,其中 是语料库的总长度。因此 BLEU 的计算非常快。
ROUGE (Recall-Oriented Understudy for Gisting Evaluation)
ROUGE 关注“召回率”——参考句中的重要信息有多少被候选句覆盖了。
1. ROUGE-N 衡量 n-gram 的召回率。
- 分子是候选句和参考句共同拥有的 n-gram 数量。
- 分母是所有参考句中 n-gram 的总数量。
2. ROUGE-L (Longest Common Subsequence) 不要求 n-gram 连续,只要求词序一致。这能更好地捕捉句子级别的结构相似性。
- 是长度为 的参考句, 是长度为 的候选句。
- 是 和 的最长公共子序列的长度。
召回率 和精确率 分别定义为:
最终的 ROUGE-L 分数是 F-score:
- 是一个常数,用于调整 P 和 R 的相对重要性。当 很大时,F-score 更偏重于召回率 ,这也是 ROUGE 的设计初衷。通常只报告 。
复杂度: ROUGE-N 复杂度与 BLEU 类似。ROUGE-L 的核心是计算 LCS,使用动态规划的复杂度为 。
METEOR
METEOR 旨在解决 BLEU 的一些缺陷,如不考虑同义词和词形变化。
- 对齐 (Alignment): 在候选句和参考句之间寻找 unigram 的最佳匹配。匹配过程分阶段进行: a. 精确匹配 (Exact match) b. 词干匹配 (Stemmed match),如 "running" 和 "run" c. 同义词匹配 (Synonym match),使用 WordNet 等词典
- 计算 Precision 和 Recall:
- 计算 F-mean: 使用加权的 F-score,更看重召回率。
- 惩罚项 (Penalty): 惩罚语序不佳的情况。如果匹配上的词在原句和译文中是连续成块的,则惩罚小。
chunks是匹配上的 unigram 形成的连续块的数量。matches是总匹配数。- 和 是超参数,默认分别为 0.5 和 3。
- 最终得分:
CIDEr
CIDEr 专为图像描述设计,核心思想是“好的描述应该与大多数人的描述相似”。
- n-gram 的 TF-IDF 权重:
- TF (Term Frequency): 计算每个 n-gram 在句子中的频率。
- IDF (Inverse Document Frequency): 衡量一个 n-gram 的信息量。CIDEr 的 IDF 计算方式很特别,它将整个数据集的所有参考句视为一个大文档集。
- 是数据集中图像的总数。 是 n-gram 在图像 的所有参考描述中出现的次数。这个 IDF 惩罚了在很多图像的描述中都频繁出现的常见 n-gram(如 "a picture of")。
- 余弦相似度:
对每个 n-gram 阶数 (n=1, 2, 3, 4),将候选句 和参考句 表示为 TF-IDF 加权的 n-gram 向量 和 。然后计算它们之间的余弦相似度。
- 是图像 的 个参考句。
- 最终得分: 对不同 n-gram 阶数的得分进行平均。
BERTScore
BERTScore 放弃了词汇匹配,转向语义匹配。
- 获取词向量: 将候选句 和参考句 输入到预训练的
BERT模型中,提取每个 token 的上下文相关词向量。 - 计算相似度矩阵: 计算候选句中每个词向量 与参考句中每个词向量 的余弦相似度,形成一个 的相似度矩阵。
- 贪心匹配:
- 召回率 (Recall): 对参考句中的每个词 ,在候选句中找到最相似的词,即 。然后对所有 的最大相似度求平均。
- 精确率 (Precision): 对候选句中的每个词 ,在参考句中找到最相似的词,即 。然后对所有 的最大相似度求平均。
- 最终得分: 计算 F1-score。
复杂度: 主要开销在于 BERT 的前向传播,对于长度为 的序列,复杂度约为 。因此,BERTScore 比基于 n-gram 的指标慢得多。
代码实现
使用 sacrebleu 计算 BLEU
sacrebleu 是一个标准化的 BLEU 实现,它能保证不同研究之间比较的公平性,因为它内置了标准的 tokenization 流程。
1import sacrebleu2import numpy as np3from collections import Counter45# --- sacrebleu 计算 BLEU ---6# 候选句7candidate = "the cat is on the mat"8# 参考句列表 (sacrebleu 要求每个候选句对应一个参考句列表)9references = ["the cat sat on the mat", "there is a cat on the mat"]1011# sacrebleu.corpus_bleu 的输入是候选句列表和参考句列表的列表12# 即使只有一个候选句,也需要包装成列表13# refs 的格式: [[ref1_for_cand1, ref2_for_cand1, ...], [ref1_for_cand2, ...], ...]14cands = [candidate]15refs = [references]1617# 计算 BLEU 分数18# verbose=True 会打印出贡献 BLEU 分数的各种统计量,如 n-gram 匹配数和句子长度19bleu = sacrebleu.corpus_bleu(cands, refs, verbose=True)20print(f"\nSacrebleu BLEU score: {bleu.score:.2f}")212223# --- 手写 ROUGE-L 的核心 LCS 算法 ---24def rouge_l_fscore(candidate: str, reference: str, beta: float = 1.2) -> dict:25 """26 计算单个候选句和参考句之间的 ROUGE-L 分数。27 核心是实现最长公共子序列 (LCS) 算法。28 """29 # 1. 分词30 cand_tokens = candidate.split()31 ref_tokens = reference.split()3233 m, n = len(cand_tokens), len(ref_tokens)3435 # 处理边界情况:如果任一句子为空,LCS 为 036 if m == 0 or n == 0:37 return {"precision": 0.0, "recall": 0.0, "f1": 0.0}3839 # 2. 动态规划计算 LCS 长度40 # dp[i][j] 表示 cand_tokens[:i] 和 ref_tokens[:j] 的 LCS 长度41 dp = np.zeros((m + 1, n + 1))4243 for i in range(1, m + 1):44 for j in range(1, n + 1):45 if cand_tokens[i - 1] == ref_tokens[j - 1]:46 # 如果当前词匹配,LCS 长度加一47 dp[i][j] = dp[i - 1][j - 1] + 148 else:49 # 如果不匹配,LCS 长度取两个子问题的最大值50 dp[i][j] = max(dp[i - 1][j], dp[i][j - 1])5152 lcs_len = dp[m][n]5354 # 3. 计算 Precision, Recall 和 F1-score55 # ROUGE-L 的召回率56 recall_lcs = lcs_len / n57 # ROUGE-L 的精确率58 precision_lcs = lcs_len / m5960 # F-score61 if recall_lcs == 0 or precision_lcs == 0:62 f1_lcs = 0.063 else:64 # beta 用于调整 P 和 R 的权重,beta > 1 表示更看重 Recall65 f1_lcs = (1 + beta**2) * precision_lcs * recall_lcs / (recall_lcs + beta**2 * precision_lcs)6667 return {68 "lcs_len": lcs_len,69 "precision": precision_lcs,70 "recall": recall_lcs,71 "f1": f1_lcs,72 }7374# 示例75candidate_lcs = "police killed the gunman"76reference_lcs = "the gunman was killed by police"7778# 虽然词序完全不同,但共享了 "the", "gunman", "killed", "police"79# LCS 应该是 "the gunman" (长度2) 或者 "police" (长度1) 等,取决于具体子序列80# 正确的 LCS 是 "the gunman"81# 让我们手动验证一下:82# cand: p k t g83# ref: t g w k b p84# LCS(cand, ref) = "k p" (killed, police) 或 "t g" (the, gunman)85# 长度都是286# 让我们用代码验证87scores = rouge_l_fscore(candidate_lcs, reference_lcs)88print(f"\n--- 手写 ROUGE-L (LCS) ---")89print(f"候选句: '{candidate_lcs}'")90print(f"参考句: '{reference_lcs}'")91print(f"LCS 长度: {scores['lcs_len']}")92print(f"ROUGE-L Precision: {scores['precision']:.4f}")93print(f"ROUGE-L Recall: {scores['recall']:.4f}")94print(f"ROUGE-L F1 (beta=1.2): {scores['f1']:.4f}")
工程实践
-
使用场景:
- BLEU: 机器翻译(MT)任务的黄金标准,也常用于代码生成、对话系统等。
- ROUGE: 文本摘要任务的首选(ROUGE-1, ROUGE-2, ROUGE-L),因为它衡量内容覆盖度。
- METEOR: 在 MT 中作为 BLEU 的补充,与人类判断的相关性通常更高,但计算较慢。
- CIDEr: 图像/视频描述生成的标准指标,因为它能有效利用多个参考句达成共识。
- BERTScore: 当语义准确性至关重要,且允许同义词、释义等灵活表达时使用。例如,释义生成、问答系统、高级对话评估。由于计算成本高,常用于最终模型评估,而非开发阶段的快速迭代。
-
超参数选择:
- BLEU/ROUGE: n-gram 的阶数 N 通常取 4。对于 BLEU,平滑方法(如
method='exp')可以处理 的情况。 - ROUGE: 摘要任务通常同时报告 ROUGE-1, ROUGE-2, ROUGE-L。
- BERTScore: 关键是选择哪个预训练模型(如
bert-base-uncased,roberta-large)和从哪一层提取向量。通常模型越大、层数越靠后,语义信息越丰富,但计算也越慢。IDF 加权通常能提升性能。
- BLEU/ROUGE: n-gram 的阶数 N 通常取 4。对于 BLEU,平滑方法(如
-
性能/显存/吞吐:
- BLEU/ROUGE 是最快的,几乎没有计算开销,适合在训练过程中频繁验证。
- METEOR 速度中等,需要加载 WordNet 等外部资源。
- BERTScore 是最慢的,需要加载数 GB 的大模型,并且需要 GPU 加速才能获得可接受的吞吐量。在评估大规模测试集时,耗时可能达到数小时。
-
调试技巧:
- 指标分数低,但人工看效果不错: 可能是因为你的模型生成了语义正确但用词不同的句子。这时 BLEU/ROUGE 会给出低分。可以尝试用 BERTScore 验证,或者增加更多样化的参考句。
- 指标分数高,但人工看效果很差: 模型可能学会了“套路”,比如通过重复高频词来刷高 ROUGE-1 分数。此时应仔细检查生成样本,并考虑使用惩罚重复的评估方法。
- 永远不要只看一个数字: 评估时,除了总分,还应该随机抽取高、中、低分的样本进行人工分析,理解模型的优点和缺点。
- 使用标准化工具: 为了公平比较,尽量使用
sacrebleu(for BLEU) 和rouge-score(for ROUGE) 等标准化库,它们处理了 tokenization、大小写等细节。
常见误区与边界情况
-
误区1: 分数可以跨任务/数据集比较
- 错误: 在新闻摘要任务上获得的 ROUGE-1=40,和在科技论文摘要任务上获得的 ROUGE-1=35,并不能直接说明前者模型更好。指标分数高度依赖于任务难度、参考句的质量和数量。
- 正确做法: 只能在相同任务、相同测试集、相同参考句、相同预处理的条件下比较模型分数。
-
误区2: BLEU 是召回率,ROUGE 是精确率
- 错误: 这是最常见的混淆。正好相反,BLEU 基于精确率(生成的词有多大比例是正确的),ROUGE 基于召回率(参考句的词有多大比例被生成了)。
-
误区3: 指标分数越高,模型就越好
- 错误: 所有自动评估指标都只是人类判断的代理(proxy)。它们无法评估事实性、逻辑性、流畅度之外的微妙之处。一个模型可能通过生成安全但无聊的通用回复来获得高分。
- 正确做法: 自动评估指标是必要的,但人工评估是最终的黄金标准。
-
边界情况与失败模式:
- 同义词/释义: BLEU 和 ROUGE 无法处理同义词。
candidate="tiny car",reference="small automobile",BLEU/ROUGE 分数会是 0。METEOR 和 BERTScore 能更好地处理这种情况。 - 语序和语法: BLEU-N (N>1) 和 ROUGE-L 在一定程度上能捕捉语序,但对长距离依赖和复杂语法结构无能为力。一个语法不通的句子也可能因为包含了正确的 n-gram 而获得不错的 BLEU 分数。
- 事实性错误:
candidate="Obama was born in Kenya",reference="Obama was born in Hawaii"。这些指标只会因为 "Kenya" 和 "Hawaii" 不匹配而轻微扣分,无法识别出严重的事实性错误。 - 重复: BLEU 的截断计数可以惩罚在单个句子内的重复。但如果模型在不同样本间生成大量重复内容,这些指标无法捕捉。
- 同义词/释义: BLEU 和 ROUGE 无法处理同义词。
-
常见面试追问:
- 问: "如果你的模型 BLEU 分数很低,但 BERTScore 很高,这意味着什么?你会相信哪个?"
- 答: 这通常意味着模型在语义上理解了任务,生成了与参考句意思相同但用词和句式不同的句子。我会更相信 BERTScore 的结果,因为它更好地捕捉了语义相似性。这也表明模型的表达能力比较丰富,没有死记硬背训练数据中的特定短语。但同时,我也会人工抽查样本,确认高 BERTScore 不是由模型缺陷(如生成通用无意义的句子)导致的。
- 问: "为什么 BLEU 使用几何平均而不是算术平均?"
- 答: 几何平均对低分(尤其是 0 分)的惩罚更重。如果一个模型生成的句子在 1-gram, 2-gram, 3-gram 上匹配都很好( 很高),但在 4-gram 上完全没有匹配(),几何平均会直接给出 0 分。这符合直觉:一个连像样的短语都生成不了的翻译不是好翻译。而算术平均则会给出一个尚可的分数,掩盖了模型在高阶流畅性上的严重缺陷。
- 问: "CIDEr 的 IDF 是如何体现“共识”的?"
- 答: CIDEr 的 IDF 是在整个数据集的所有参考句上计算的。如果一个词(如 "a" 或 "is")在几乎所有图像的描述中都出现,它的 IDF 值会非常低。相反,如果一个词(如 "frisbee")只在包含飞盘的图像描述中频繁出现,它的 IDF 值就会很高。因此,当候选句使用了这种具有高 IDF 值的、信息量丰富的词,并且这个词也出现在了当前图像的多个参考句中(即达成了“共识”),CIDEr 就会给出高分。它奖励那些既独特又有共识的描述。