本次BLEU算法的学习参考了东北大学出版的《机器翻译-统计建模与深度学习方法》,代码的学习参考了这篇博客: BLEU算法详解.
目录
BLEU算法介绍
目前使用最广泛的自动评价指标是BLEU。BLEU 是Bilingual Evaluation Understudy的缩写,最早由IBM 在2002 年提出。通过采用n-gram匹配的方式评定机器翻译结果和参考译文之间的相似度,即机器翻译的结果越接近人工参考译文就认定它的质量越高。
N-gram 准确率(N-gram Precision)
n-gram是指n 个连续单词组成的单元,称为n 元语法单元。n 越大表示评价时考虑的匹配片段越大BLEU的计算首先考虑待评价译文中n-gram在参考答案中的匹配率,称为n-gram 准确率(n-gram Precision)。其计算方法如下:
例如:
原文:今天天气不错
机器译文:It is a nice day today
人工译文:Today is a nice day
如果用1-gram匹配的话:
可以看到机器译文一共6个词,有5个词语都命中的了参考译文,那么它1-gram的匹配度为 5/6
我们再以3-gram举例:
可以看到机器译文一共可以分为四个3-gram的词组,其中有两个可以命中参考译文,那么它3-gram的匹配度为 2/4
依次类推,我们可以很容易实现一个程序来遍历计算N-gram的一个匹配度。一般来说1-gram的结果代表了文中有多少个词被单独翻译出来了,因此它反映的是这篇译文的忠实度;而当我们计算2-gram以上时,更多时候结果反映的是译文的流畅度,值越高文章的可读性就越好
召回率
上面所说的方法比较好理解,也比较好实现,但是没有考虑到召回率,举一个非常简单的例子说明:
原文:猫站在地上
机器译文:the the the the
人工译文:The cat is standing on the ground
在计算1-gram的时候,the 都出现在译文中,因此匹配度为4/4 ,但是很明显 the 在人工译文中最多出现的次数只有2次,因此BLEU算法修正了这个值的算法,首先会计算该n-gram在译文中可能出现的最大次数:
Count是N-gram在机器翻译译文中的出现次数,Max_Ref_Count是该N-gram在一个参考译文中最大的出现次数,最终统计结果取两者中的较小值。然后在把这个匹配结果除以机器翻译译文的N-gram个数。因此对于上面的例子来说,修正后的1-gram的统计结果就是2/4。
译文整体的准确率等于各n-gram 的加权平均:
这里解释一下这个公式,N代表的总共的单词元组,例如,n=1时就是1-gram,一元组。wn是指当前单词元组下所占有的权重比,所有的权重比相加应当为1。从公式可以看出BLEU的取值范围是(0,1],0最差,1最好。这里值得注意的是,当所有的权重值是均分的时候,这里所有元组的平均值就是算术平均值。
短句惩罚因子(Brevity Penalty, BP)
上面的算法已经足够可以有效的翻译评估了,然而N-gram的匹配度可能会随着句子长度的变短而变好,因此会存在这样一个问题:一个翻译引擎只翻译出了句子中部分句子且翻译的比较准确,那么它的匹配度依然会很高。为了避免这种评分的偏向性,BLEU在最后的评分结果中引入了长度惩罚因子(Brevity Penalty)
c: 表示译文的句子长度,
r :表示参考译文的句子长度
这个公式表示当译文小于参考译文(也就是翻译的句子过短是短句的时候)会得到一个BP值,并且最后的结果会乘上这个BP值来惩罚我们的短句翻译。这里放在指数上是为了扩大这种”惩罚“。
最终BLEU 的计算公式为:
总结一下:BLEU值其实也就是“改进版的n-gram”加上“过短惩罚因子”。
BLEU算法代码实现
通过上面BLEU算法理论的学习,我们知道BLEU算法的原理。
接着要运用到一个nltk工具包里面定义好的BLEU算法。
参考了这个博客链接: nltk.
sentence_bleu语句级的bleu值
from nltk.translate.bleu_score import sentence_bleu
reference = ['this', 'is', 'a', 'test']
candidate = ['this', 'is', 'a', 'test']
score = sentence_bleu(reference, candidate)
print(score)
corpus_bleu语句级的bleu值
from nltk.translate.bleu_score import corpus_bleu
references = [['this', 'is', 'a', 'test']]
candidates = [['this', 'is', 'a', 'test']]
score = corpus_bleu(references, candidates)
print(score)
score = corpus_bleu(references, candidates,weights,SmoothingFunction)
这里说明一下两个方法的一些参数介绍:
属性名 | 说明 |
---|---|
references | 参考语句也就是人工翻译的目标语句 |
candidates | 候选语句也就是机器翻译得到的语句 |
weights | 分配每个元组的权重值 |
SmoothingFunction | SmoothingFunction是用来平滑log函数的结果的,防止fn=0(也就是某个元组匹配数为0)时,取对数为负无穷。 |