介绍 语言模型的 BLEU、ROUGE 和 困惑度(Perplexity) 三种常用的语言模型评估指标,帮助你快速理解它们的含义、计算方法及优缺点。
概览
这些指标都是为了解决:「我们自动生成的句子到底有多好?」这个问题:
BLEU 着重看译文和参考译文在 n-gram 级别上的重合度,用来衡量精准度;
ROUGE 则以召回率为主,考察自动摘要或翻译覆盖了参考文本多少内容;
困惑度(PPL) 直接度量语言模型对测试集的“困惑程度”,值越低表示模型预测下一个词越有把握。
BLEU
1. 什么是 BLEU
BLEU(Bilingual Evaluation Understudy)是2002年提出的机器翻译评测指标,用来自动评估译文与人工参考译文的相似度,分数范围0–1,越接近1表示译文越“精准” 。
2. 核心计算
提取 n-gram:先从译文(candidate)和参考译文(reference)中分别列出所有 n 连续词组(如1-gram、2-gram、…)。
匹配计数:统计译文中每个 n-gram 在参考译文中出现的次数(最多算参考中出现次数),并除以译文中该 n-gram 的总数,得到每个阶数的匹配度。
几何平均:将各阶匹配度按权重几何平均,再乘以“短句惩罚”(brevity penalty),综合得出最终 BLEU 值 。
3. 优缺点
优点:自动化程度高,不需人工判断;能够快速对比不同系统输出质量。
缺点:过度强调精确匹配,可能忽略同义替换和语序变化;对短句或多参考时效果不稳定 。
# 第一步安装nltk的包-->pip install nltk # BLEU算法实际上就是在判断两个句子的相似程度. BLEU 的分数取值范围是 0~1,分数越接近1,说明翻译的质量越高。 from nltk.translate.bleu_score import sentence_bleu def cumulative_bleu(reference, candidate): # 指标计算:p1^w1*p2^w2 =0.6^0.5*0.25^0.5 = 0.387 # math.exp(0.5 * math.log(0.6) + 0.5 * math.log(0.25)) = # math.exp(0.5*math.log(0.15)) = math.exp(math.log(0.15)^0.5) = 0.15^0.5 = 0.387 # # 0.3872983346207417 bleu_1_gram = sentence_bleu(reference, candidate, weights=(1, 0, 0, 0)) bleu_2_gram = sentence_bleu(reference, candidate, weights=(0.5, 0.5, 0, 0)) bleu_3_gram = sentence_bleu(reference, candidate, weights=(0.33, 0.33, 0.33, 0)) bleu_4_gram = sentence_bleu(reference, candidate, weights=(0.25, 0.25, 0.25, 0.25)) return bleu_1_gram, bleu_2_gram, bleu_3_gram, bleu_4_gram # return bleu_1_gram, bleu_2_gram # 生成文本 candidate_text = ["This", "is", "some", "generated", "text"] # 参考文本列表 reference_texts = [["This", "is", "a", "reference", "text"]] # 计算 Bleu 指标 c_bleu = cumulative_bleu(reference_texts, candidate_text) # 打印结果 print("The Bleu score is:", c_bleu) # The Bleu score is: (0.6, 0.3872983346207417, 1.594907e-102, 9.2831e-155)
ROUGE
1. 什么是 ROUGE
ROUGE(Recall-Oriented Understudy for Gisting Evaluation)是一组以召回率为核心的评测指标,主要用于自动摘要和机器翻译等生成任务,通过比较生成结果与参考文本的 n-gram 重叠来评估质量 。
2. 核心计算
ROUGE-N:统计参考文本中的所有 n-gram 总数,以及这些 n-gram 在机器生成文本中被“召回”了多少,并以召回率形式给分(召回率=召回 n-gram 数/参考文本中 n-gram 总数)。
ROUGE-L:基于“最长公共子序列”(LCS)长度来考察整体文本的连贯覆盖率。
ROUGE-W/S 等:考虑加权或跳跃 n-gram 匹配等更复杂情况。
3. 优缺点
优点:侧重覆盖信息量,尤其适合评估摘要系统是否“没漏掉”重要内容;支持多种子指标,更灵活。
缺点:纯召回视角下易忽略冗余与精确度;大篇幅文本或多人参考时计算复杂度高 。
# 第一步:安装rouge-->pip install rouge from rouge import Rouge # 生成文本 generated_text = "This is some generated text." # 参考文本列表 reference_texts = ["This is another generated reference text."] # 计算 ROUGE 指标 rouge = Rouge() scores = rouge.get_scores(generated_text, reference_texts[0]) # 打印结果 print("ROUGE-1 precision:", scores[0]["rouge-1"]["p"]) print("ROUGE-1 recall:", scores[0]["rouge-1"]["r"]) print("ROUGE-1 F1 score:", scores[0]["rouge-1"]["f"]) # ROUGE-1 precision: 0.8 # ROUGE-1 recall: 0.6666666666666666 # ROUGE-1 F1 score: 0.7272727223140496
困惑度 (Perplexity)
1. 什么是困惑度
困惑度(PPL)是衡量语言模型预测下一个词不确定性的指标,本质上是测试集上交叉熵的指数形式,值越低说明模型越不“困惑”,预测越准确 。
2. 核心计算
3. 优缺点
优点:直接反映模型在真实语言分布上的拟合好坏,可用于模型训练监控。
缺点:只关注语言本身概率分布,无法区分生成内容的可读性和实际意义;对长文本较为敏感。
import math # 定义语料库 sentences = [ ['I', 'have', 'a', 'pen'], ['He', 'has', 'a', 'book'], ['She', 'has', 'a', 'cat'] ] # 定义语言模型 unigram = {'I': 1/12, 'have': 1/12, 'a': 3/12, 'pen': 1/12, 'He': 1/12,'has': 2/12,'book': 1/12,'She': 1/12, 'cat': 1/12} perplexity = 0 for sentence in sentences: sentence_prob = 1 for word in sentence: sentence_prob *= unigram[word] temp = -math.log(sentence_prob, 2)/len(sentence) perplexity+=2**temp perplexity = perplexity/len(sentences) print('困惑度为:', perplexity) # 困惑度为: 8.15
总结:
BLEU 强调“译文有多少词精确命中参考文本”,偏向准确率;
ROUGE 强调“参考文本有多少信息被生成文本覆盖”,偏向召回率;
困惑度 则衡量语言模型对测试数据的整体“理解能力”,值越低越好。
根据具体任务(翻译、摘要、纯语言建模)选择合适的指标,能更全面地评估模型性能。