1、背景
在机器翻译中,经常使用 mosesdecoder 中的 mosesdecoder/scripts/generic/multi-bleu.perl 来评测模型的 bleu,只关注最后的bleu得分,而忽略计算过程。
2、计算过程
multi-bleu.perl 计算过程大概分为三步:
2.1、计算n-gram(1 - 4) bleu
bleu[n] = n-gram 匹配数 / n-gram 总数 , 其中 n 为1,2,3,4;
代码如下:
for(my $n=1;$n<=4;$n++) {
if (defined ($TOTAL[$n])){
$bleu[$n]=($TOTAL[$n])?$CORRECT[$n]/$TOTAL[$n]:0;
# print STDERR "CORRECT[$n]:$CORRECT[$n] TOTAL[$n]:$TOTAL[$n]\n";
}else{
$bleu[$n]=0;
}
}
2.2、惩罚系数
if 译文长度 < 参考长度:
惩罚系数 = math.exp(1-参考长度/译文长度)
esle:
惩罚系数 = 1
代码如下:
if ($length_translation<$length_reference) {
$brevity_penalty = exp(1-$length_reference/$length_translation);
}
2.3、最终 bleu
bleu = 惩罚系数 * exp(log(bleu[1])+ … +log(bleu[4]) )
代码如下:
$bleu = $brevity_penalty * exp((my_log( $bleu[1] ) +
my_log( $bleu[2] ) +
my_log( $bleu[3] ) +
my_log( $bleu[4] ) ) / 4) ;
3、运行
运行 perl multi-bleu.perl -lc 参考文件 < 译文文件 ,可得下图:
注意:下面的 bleu 是乘以 100 后的数值,并且保留1-2位小数
66.1/41.0/27.7/18.6 分别表示:1-4 gram 的 bleu*100;
BP 为惩罚系数;
ratio 为 译文长度 与 参考长度 的比值;
hyp_len 为译文长度;
ref_len 为参考长度
根据 2.3 中计算公式:
import math
BP = 1
bleu_1 = 66.1/100
bleu_2 = 41.0/100
bleu_3 = 27.7/100
bleu_4 = 18.6/100
bleu = BP*math.exp((math.log(bleu_1)+math.log(bleu_2)+math.log(bleu_3)+math.log(bleu_4))/4)
print(bleu*100)
# 34.37514251498449 因为保留1-2位小数,所以与截图 34.39 有误差