文本生成评估指标简单介绍BLEU+ROUGE+Perplexity+Meteor 代码实现

以下指标主要针对两种:机器翻译和文本生成(文章生成),这里的文本生成并非是总结摘要那类文本生成,仅仅是针对生成句子/词的评价。
首先介绍BLEU,ROUGE, 以及BLEU的改进版本METEOR;后半部分介绍PPL(简单介绍,主要是关于交叉熵的幂,至于这里的为什么要求平均,是因为我们想要计算在一个n-gram的n中,平均每个单词出现需要尝试的次数。

机器翻译(Machine Translation, MT)

BLEU:Bilingual Evaluation Understudy

形式:
目的:计算网络生成文本Candidate和参考翻译文本(Reference, 可以有多个参考)之间的文本交叉计算。

计算:针对单个Reference:
举例子:

Candidate: ha ha ha
Reference: only saying ha is not good
针对unigram计算BLUE:
BLUE-1 = Candidate在Reference出现的次数 len(Candidate) = count(ha) count(ha,ha, ha) = 1 3 \text{BLUE-1} = \frac{\text{Candidate在Reference出现的次数}}{\text{len(Candidate)}}=\frac{\text{count(ha)}}{\text{count(ha,ha, ha)}} = \frac{1}{3} BLUE-1=len(Candidate)CandidateReference出现的次数=count(ha,ha, ha)count(ha)=31

缺点(存在问题): 如果长度很短的话,分母会很小,BLEU取值会很大,为了消除长度带来的影响:
B P = { e 1 − l r e f l c d d , l c d d < l r e f 1 , l c d d ≥ l r e f BP=\left\{ \begin{aligned} e^{1 - \frac{l_{ref}}{l_{cdd}}}, &\quad l_{cdd} < l_{ref} \\ 1, &\quad l_{cdd} \ge l_{ref} \end{aligned} \right. BP= e1lcddlref,1,lcdd<lreflcddlref

这里的BP跟n-gram的n无关

则修正之后的BLUE计算方式为:
计算步骤

  1. 确定n, n是ngram的n
  2. 统计n-gram在reference,Candidate出现次数,reference出现次数作为次数统计上限
  3. 对Candidate中每个n-gram计算匹配次数:
    M = ∑ n − g r a m min ⁡ ( O n g r a m c d d , O n g r a m r e f ) M = \sum_{n-gram} \min(O_{ngram}^{cdd}, O_{ngram}^{ref}) M=ngrammin(Ongramcdd,Ongramref)
  4. 计算BLEU-N
    B L E U N = M l c d d − 1 + n BLEU_{N} = \frac{M}{l_{cdd} - 1 + n} BLEUN=lcdd1+nM
  5. 利用几何平均计算综合得分
    B L E U = B P ⋅ ( ∏ n = 1 k B L E U n ) 1 k BLEU = BP \cdot ({\prod \limits_{n = 1}^{k}}BLEU_{n})^{\frac{1}{k}} BLEU=BP(n=1kBLEUn)k1
    这里的k一般取值为4,代表的是看了1-gram, 2-gram, 3-gram, 4-gram综合判断
    参考:https://mp.weixin.qq.com/s/wdIWq6XUcB6HJchpHie–g

使用场景:短文本生成的机器翻译评估(有reference的样本)
缺点:只适用于短文本,不适合长文本生成(生成故事)

实现

from torchtext.data.metrics import bleu_score
candidate_corpus = [['My', 'full', 'pytorch', 'test'], ['Another', 'Sentence']]
references_corpus = [[['My', 'full', 'pytorch', 'test'], ['Completely', 'Different']], [['No', 'Match']]]
bleu_score(candidate_corpus, references_corpus)

ROUGE: Recall-Oriented Understuy for Gisting Evaluation

简介:主要用于评估机器翻译文本摘要(或其他自然语言处理任务)的质量,即:衡量目标文本与生成文本之间的匹配程度,此外还考虑生成文本的召回率,BLEU则相对更看重生成文本的准确率,着重于涵盖参考摘要的内容和信息的完整性。
分别有四种方法:ROUGE-N, ROUGE-L, ROUGE-W, ROUGE-S

主要有两种形式

  • ROUGE-N(N = 1, 2, 3, …)
  • ROUGE-L

ROUGE-N计算方式为:
ROUGE-N = Candidate ∩ Reference l e n ( Reference ) \text{ROUGE-N} = \frac{\text{Candidate} \cap \text{Reference}}{len(\text{Reference})} ROUGE-N=len(Reference)CandidateReference
这里的分子交集不像最长公共子串一样,这里的交集不考虑顺序。
ROUGE-L
考虑最长公共子串(是区分顺序的,参考leetcode中最长公共子串计算,不过在这里最小单元从leetcode的字符变成了单词。1143. 最长公共子序列

单句ROUGE-L
ROUGE-L = 最长公共子串 ( Candidate , Reference ) l e n ( Reference ) \text{ROUGE-L} = \frac{\text{最长公共子串}(\text{Candidate}, \text{Reference})}{len(\text{Reference})} ROUGE-L=len(Reference)最长公共子串(Candidate,Reference)

举例子
Candidate: police killed the gunman
Reference1: police kill the gunman
Reference2: the gunman kill police

对reference1而言,ROUGE-2为1/3; 对于reference2而言,ROUGE为1/3
对于reference1而言,ROUGE-L为3/4l; 对于reference2而言,ROUGE-L为1/2
还有ROUGE-W, ROUGE-S, 可以参考: 自动文摘评测方法:Rouge-1、Rouge-2、Rouge-L、Rouge-S
缺点

实现

from torchmetrics.text.rouge import ROUGEScore
preds = "My name is John"
target = "Is your name John"
rouge = ROUGEScore()
from pprint import pprint
pprint(rouge(preds, target))

在这里插入图片描述
来源:https://torchmetrics.readthedocs.io/en/stable/text/rouge_score.html
跑代码会遇到问题:https://blog.csdn.net/qq_24263553/article/details/105726751

METEOR: The Metric for Evaluation of Translation with Explicit ORdering

目的:解决BLEU的不足,与 BLEU 相比,METEOR 考虑了更多的因素,如同义词匹配、词干匹配、词序等,因此它通常被认为是一个更全面的评价指标。
实现(计算):基于unigram精度和召回率的调和平均
应用:机器翻译(Machine Translation, MT), Image Caption, Question Generation, Summarization

参考:【NLG】(三)文本生成评价指标—— METEOR原理及代码

from nltk.translate.meteor_score import meteor_score
 
reference3 = '我 说 这 是 怎 么 回 事,原 来 明 天 要 放 假 了'
reference2 = '我 说 这 是 怎 么 回 事'
hypothesis2 = '我 说 这 是 啥 呢 我 说 这 是 啥 呢'
# reference3:参考译文
# hypothesis2:生成的文本
res = round(meteor_score([reference3, reference2], hypothesis2), 4)
print(res)
 
输出:
0.4725

文本生成(Text Generation)

Perplexity 困惑度

这里作了详细的解释:求通俗解释NLP里的perplexity是什么?
计算: 2 H ( p , p ^ ) 2^{H(p, \hat{p})} 2H(p,p^)
其中 H ( p , p ^ ) H(p, \hat{p}) H(p,p^)计算为:
H ( p , p ^ ) = − 1 n ∑ x p ( x ) log ⁡ 2 p ^ ( x ) H(p, \hat{p}) = -\frac{1}{n} \sum_{x} p(x) \log_2 \hat{p}(x) H(p,p^)=n1xp(x)log2p^(x)
通俗解释:

困惑度p可以理解为,如果每个时间步都根据语言模型计算的概率分布随机挑词,那么平均情况下,挑多少个词才能挑到正确的那个

from torchmetrics.text import Perplexity
import torch
gen = torch.manual_seed(42)
preds = torch.rand(2, 8, 5, generator=gen)
target = torch.randint(5, (2, 8), generator=gen)
target[0, 6:] = -100
perp = Perplexity(ignore_index=-100)
perp(preds, target)

参考:

【NLG】(二)文本生成评价指标—— METEOR原理及代码示例
一文搞懂Language Modeling三大评估标准
Perplexity of fixed-length models

<think>嗯,用户现在问的是BLEU代码实现,之前他们问过n-gram的具体计算示例,现在可能是在自然语言处理的学习过程中,逐步深入到模型评估指标了。我需要先确认用户对BLEU的基本概念是否了解,可能他们在了解n-gram后,想进一步知道如何用这些概念来评估机器翻译的效果。 首先,BLEU的核心是基于n-gram的精确度,加上句子长度惩罚。用户可能需要一个具体的代码示例,而不仅仅是理论。他们可能希望看到如何从零开始实现BLEU,或者至少理解现有库(如nltk)的实现逻辑。 接下来,我需要考虑用户的背景。可能是学生或者刚入行的开发者,所以代码需要清晰,步骤明确。同时,要避免使用过于复杂的库,除非必要。例如,使用nltk的BLEU实现可以作为参考,但自己实现的部分需要分解步骤,比如计算n-gram匹配、 brevity penalty等。 用户可能存在的疑问点包括:如何计算修正的n-gram精确度,为什么需要brevity penalty,以及不同n-gram权重的选择。在解释代码的时候,需要逐一解决这些问题,最好通过示例说明。 另外,用户之前的问题是关于n-gram的计算,所以需要将BLEU与n-gram联系起来,说明BLEU如何利用n-gram的重合度来评估翻译质量。例如,在代码示例中,可以展示如何统计候选翻译和参考翻译中的n-gram重叠情况。 需要注意的是,用户可能希望看到两种实现方式:一种是手动实现,帮助理解原理;另一种是使用现有库,方便实际应用。因此,回答中需要包括这两个部分,并比较它们的优缺点。 最后,要提醒用户BLEU的局限性,比如不考虑语法和语义,只关注表面匹配,这样他们在实际应用中能正确使用和解释BLEU分数。可能还需要提到常见的n-gram组合权重,如BLEU-4通常使用1/4的均匀权重,但可以根据任务调整。</think>以下是通过Python代码实现BLEU算法的分步详解,包含**基础版本实现**与**标准库使用**两种方式,并配以具体示例说明: --- ### 一、BLEU核心公式 BLEU分数 = **BP × exp(∑ wn log pn)** - **BP(Brevity Penalty)**:短句惩罚因子 - **pn**:n-gram精确度(n=1~4) - **wn**:权重(通常取wn=1/4) --- ### 二、手动实现关键步骤 #### 1. 计算n-gram匹配数 ```python from collections import Counter import math def count_ngrams(sentence, n): tokens = sentence.split() return Counter([' '.join(tokens[i:i+n]) for i in range(len(tokens)-n+1)]) # 示例:计算候选句与参考句的2-gram匹配 candidate = "猫 坐在 垫子 上" # 候选翻译 reference = ["猫 躺在 垫子 上"] # 参考翻译(可多个) candidate_bigrams = count_ngrams(candidate, 2) reference_bigrams = count_ngrams(reference[0], 2) # 统计匹配数(取参考集中最大匹配值) matches = sum(min(candidate_bigrams[gram], max(r.count(gram) for r in reference_bigrams)) for gram in candidate_bigrams) print(f"2-gram匹配数:{matches}/{len(candidate.split())-1}") # 输出:3/3 ``` #### 2. 计算修正的n-gram精确度(Modified Precision) ```python def modified_precision(candidate, references, n): candidate_ngrams = count_ngrams(candidate, n) max_counts = {} for ref in references: ref_ngrams = count_ngrams(ref, n) for gram in candidate_ngrams: max_counts[gram] = max(max_counts.get(gram,0), ref_ngrams.get(gram,0)) total_matches = sum(min(candidate_ngrams[gram], max_counts[gram]) for gram in candidate_ngrams) total_candidate = max(len(candidate.split())-n+1, 1) # 防止除零 return total_matches / total_candidate ``` #### 3. 计算短句惩罚因子(BP) ```python def brevity_penalty(candidate, references): c = len(candidate.split()) r = min(len(ref.split()) for ref in references) # 取最接近的参考长度 return 1 if c > r else math.exp(1 - r/c) ``` #### 4. 完整BLEU计算 ```python def manual_bleu(candidate, references, weights=[0.25]*4): bp = brevity_penalty(candidate, references) precisions = [] for n in range(1, len(weights)+1): pn = modified_precision(candidate, references, n) precisions.append(pn) score = sum(w * math.log(p) if p >0 else 0 for w, p in zip(weights, precisions)) return bp * math.exp(score) # 测试示例 candidate = "猫 坐在 垫子 上" references = ["猫 躺在 垫子 上", "一 只 猫 在 垫子 上"] print(f"手动实现BLEU: {manual_bleu(candidate, references):.4f}") # 输出约0.5568 ``` --- ### 三、标准库实现(NLTK) ```python from nltk.translate.bleu_score import sentence_bleu, SmoothingFunction # 使用示例 references = [['猫', '躺在', '垫子', '上'], ['一', '只', '猫', '在', '垫子', '上']] candidate = ['猫', '坐在', '垫子', '上'] # 使用平滑方法处理零计数问题 smoother = SmoothingFunction().method1 score = sentence_bleu(references, candidate, weights=(0.25, 0.25, 0.25, 0.25), smoothing_function=smoother) print(f"NLTK库BLEU: {score:.4f}") # 输出约0.5568 ``` --- ### 四、关键实现细节说明 1. **n-gram截断**:当候选句长度<4时自动调整n值 2. **多重参考处理**:取所有参考译文中的最大匹配数 3. **平滑技术**:处理未出现n-gram的情况(如Add-k平滑) 4. **长度惩罚逻辑**:当候选句短于所有参考译文时启动惩罚 --- ### 五、BLEU评分典型区间 | 翻译质量 | BLEU范围 | |----------|----------| | 优秀 | 0.6~1.0 | | 可用 | 0.3~0.6 | | 较差 | 0~0.3 | --- ### 六、注意事项 1. **语言特性**:BLEU对形态丰富的语言(如俄语)评分偏低 2. **常用配置**:通常使用BLEU-4(即n=4) 3. **改进变体**:NIST、ROUGE指标的互补使用 通过代码实现可清晰理解BLEU算法中n-gram匹配、长度惩罚等核心机制,实际应用建议优先使用标准库实现以保证计算一致性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值