如何评测问答系统给出的一个答案的好坏 ?
常用的有 ROUGE-L(Recall-Oriented Understudy for Gisting Evaluation)和 BLEU-4(Bilingual Evaluation Understudy)两个指标,这两个指标的人类最高分都在58分左右。
ROUGE-L 的 L 是指LCS(longest common subsequence,最长公共子序列)的首字母。
BLEU-4 的 -4 是指4元精确率的BLEU值,也就是从1-gram计算到4-gram,当我们计算2-gram以上时,更多时候结果反映的是生成文本的流畅度,值越高文章的可读性就越好。
BLEU
BLEU值的计算公式如下:
B L E U = B P × e x p ( ∑ n = 1 N W n l o g P n ) BLEU = BP \times exp(\sum_{n=1}^{N}W_{n}logP_{n}) BLEU=BP×exp(n=1∑NWnlogPn)
其中 Pn 表示匹配度,Wn 是每个n-gram的权重,默认权重相同,BP是一个惩罚因子,BP的计算方法如下:
B
P
=
{
1
i
f
l
c
>
l
s
e
1
−
l
s
l
c
i
f
l
c
<
=
l
s
BP = \left\{\begin{matrix} 1 & if & l_{c} > l_{s} \\ e^{1-\frac{ l_{s} }{l_{c}}} & if & l_{c} <= l_{s} \end{matrix}\right.
BP={1e1−lclsififlc>lslc<=ls
其中lc表示模型结果的长度,ls表示标准答案的长度。
举个例子:
标准答案:Going to play basketball in this afternoon ?
模型结果:Going to play basketball the afternoon ?
按照空格切分后,模型结果的1-gram长度:7 标准答案的1-gram长度:8
所以 1-gram 中,在模型的结果,除了“计”和“电”这两个字没有对应,其余都对应上了,因此:
P1 = 6/7
其他gram同理:
P2 = 4/6
P3 = 2/5
P4 = 1/4
于是 BP = e^(1-8/7)
则可以开始计算 BLEU 了
import math
Wn = 0.25
BP = math.exp(1-8/7)
BLEU = BP * math.exp((math.log(6/7)+math.log(4/6)+math.log(2/5)+math.log(1/4)) * Wn)
print('BLUE-4 为:',BLEU)
BLUE-4 为: 0.42383656282787796
用 NLTK 自带计算函数计算BLUE值对比一下。
import nltk
BLEU = nltk.translate.bleu_score.sentence_bleu(['Going to play basketball in this afternoon ?'.split()],
'Going to play basketball the afternoon ?'.split(),weights=(0.25, 0.25, 0.25, 0.25))
print('BLUE-4 为:',BLEU)
BLUE-4 为: 0.42383656282787796
计算结果相同,可以看出,我们这样计算BLUE值的思路是对的。
ROUGE-L:
(看看它是不是和你的老情人 recall、 precision、 f_bata 很像)
R l c s = L C S ( X , Y ) l e n ( Y ) R_{lcs} = \frac{LCS(X,Y)}{len(Y)} Rlcs=len(Y)LCS(X,Y)
P l c s = L C S ( X , Y ) l e n ( X ) P_{lcs} = \frac{LCS(X,Y)}{len(X)} Plcs=len(X)LCS(X,Y)
F l c s = ( β 2 + 1 ) R l c s P l c s R l c s + β 2 P l c s F_{lcs} = \frac{(\beta ^{2} + 1)R_{lcs}P_{lcs}}{R_{lcs}+\beta ^{2}P_{lcs}} Flcs=Rlcs+β2Plcs(β2+1)RlcsPlcs
其中 X 为模型生成的答案,Y为参考答案。LCS(X,Y)就是获取最长公共子序列的长度
。beta是一个人工设定的值,在 Baidu_EvaluationScript 评测代码 中,beta的值是1.2。
举个例子
In [1]: from rouge_metric.rouge import Rouge
In [2]: myRouge = Rouge()
In [3]: print(myRouge.calc_score(['A B C D E F G'],['A B C D E F G']))
...: print(myRouge.calc_score(['A B C D H I J'],['A B C D E F G']))
...: print(myRouge.calc_score(['A H B K C I D'],['A B C D E F G']))
1.0
0.5714285714285714
0.5714285714285714
TODO
结合各大对话系统框架评测数据进一步展开
局限性,横向对比
参考
http://www.aclweb.org/anthology/W/W04/W04-1013.pdf
http://aclweb.org/anthology/P/P02/P02-1040.pdf