BLEU源码笔记

BLEU源码笔记

本文参考代码为coco-caption

回顾

详细解释参见我的这篇博客,本文仅仅是代码解释

BLEU是2002年提出的一个机器翻译的自动度量,它从n-gram准确率的角度对比机器翻译和人工翻译的结果,计算公式为
B L E U = B P exp ⁡ ( ∑ n = 1 N w n log ⁡ p n ) BLEU = BP\exp\big(\sum_{n=1}^Nw_n\log p_n\big) BLEU=BPexp(n=1Nwnlogpn)
其中
B P = { 1 if c>r e ( 1 − r / c ) else BP= \begin{cases} 1& \text{if c>r}\\ e^{(1-r/c)}& \text{else} \end{cases} BP={1e(1r/c)if c>relse
比如当我计算下例的bleu值时

candidate = "It is a guide to action which ensures that the military always obeys the commands of the party."
reference1 = "It is a guide to action that ensures that the military will forever heed Party commands."
reference2 = "It is the guiding principle which guarantees the military forces always being under the command of the Party."
reference3 = "It is the practical guide for the army always to heed the directions of the party."

得到的结果即为(对原句进行大小写和标点的处理)

BLEU1:0.9444444444444444,
BLEU2:0.7453559924999299,
BLEU3:0.6240726989348756,
BLEU4:0.5045666840058485

需要注意的是,这里的BLEUi是上面公式中 N = i N=i N=i的结果,而非仅仅是 p i p_i pi(我一开始这么以为是因为发现BLEU1= p 1 p1 p1,但BLEU2不等于 p 2 p_2 p2,以为官方代码出错了,结果和自己写的代码怎么比都不对,后来才发现这只是N=1的特殊情况)

在coco-caption中的对应代码为

bleus = []
bleu = 1.
for k in range(n):
    bleu *= float(comps['correct'][k] + tiny) \
            / (comps['guess'][k] + small)
    bleus.append(bleu ** (1./(k+1)))
ratio = (self._testlen + tiny) / (self._reflen + small) ## N.B.: avoid zero division
if ratio < 1:
    for k in range(n):
        bleus[k] *= math.exp(1 - 1/ratio)

其中tinysmall均为防止分子分母为0而添加的微小值,comps['correct'][k]就是正确的k-gram(clip之后)数量,comps['guess'][k]就是candidate中k-gram的数量,ratio就是公式中的BP

这里实际上对计算公式做了些变形
B L E U = B P exp ⁡ ( ∑ n = 1 N w n log ⁡ p n ) = B P ∏ n = 1 N e w n log ⁡ p n = B P ∏ n = 1 N ( e log ⁡ p n ) w n = B P ( ∏ n = 1 N p n ) w n \begin{aligned} BLEU &= BP\exp\big(\sum_{n=1}^Nw_n\log p_n\big)\\ &=BP\prod_{n=1}^Ne^{w_n\log p_n}\\ &=BP\prod_{n=1}^N(e^{\log p_n})^{w_n}\\ &=BP(\prod_{n=1}^Np_n)^{w_n}\\ \end{aligned} BLEU=BPexp(n=1Nwnlogpn)=BPn=1Newnlogpn=BPn=1N(elogpn)wn=BP(n=1Npn)wn
此时与代码中变量bleu的连乘和加入到列表bleus中使用的指数就相互对应了

这是计算一句candidate和多句references的方法,如果对于整个candidate和references的集合计算整体的bleu,其计算方法就是将每一对的comps中对应的元素加起来,如前文所说,comps包括comps['correct'][k]就是正确的k-gram(clip之后)数量,comps['guess'][k]就是candidate中k-gram的数量,comps['reflen']就是BP计算公式中的rcomps['testlen']就是BP计算公式中的’c’,将它们逐个加起来,然后整体返回到上面的代码中计算即可

你可能感兴趣的:(BLEU源码笔记)