|
用Python计算文本BLEU分数和ROUGE值NLP 2020年08月13日文本生成是自然语言处理(NLP)中常见的一类任务,例如机器翻译、自动摘要、图片生成等等。如何评估生成文本的质量,或者说衡量生成文本与参考文本之间的差异,是一个必须考虑的问题。目前比较常见的评估方法就是计算 BLEUBLEU 分数和 ROUGEROUGE 值。BLEUBLEUBLEU (BilingualEvaluationUnderstudy,双语评估替换)一开始是为翻译工作而开发的,是一个比较候选文本翻译与其他一个或多个参考翻译的评价分数。完美匹配的得分为 1.01.0,完全不匹配则得分为 0.00.0。尽管它还没做到尽善尽美,但它具有计算速度快、容易理解、与具体语言无关等优点。翻译系统的 BLEUBLEU 得分不可能为 1,除非它们与参考翻译完全相同。通常一个人类翻译在四个参考翻译下的得分为 0.34680.3468,在两个参考翻译下的得分为 0.25710.2571。BLEUBLEU 评分由KishorePapineni等人在2002年的论文《BLEU:aMethodforAutomaticEvaluationofMachineTranslation》中提出。这种评测方法通过对候选翻译与参考文本中的相匹配的 n𝑛 元组进行计数,其中一元组(1-gram1-gram / unigramunigram)比较的是每一个单词,而二元组(bigrambigram)比较的则是每个单词对,以此类推,并且这种比较是不管单词顺序的。匹配个数越多,表明候选翻译的质量就越好。同时为了避免机器翻译系统为了追求高精度而生成过多的“合理”单词,从而导致翻译结果不恰当。在识别出匹配的候选单词之后,相应的参考单词就被视为用过了,以确保不会对产生大量合理词汇的候选翻译进行加分。在论文中这被称之为修正的 n𝑛 元组精度。BLEU评分是用来比较语句的,但是又提出了一个能更好地对语句块进行评分的修订版本,这个修订版根据n元组出现的次数来使n元组评分正常化。首先逐句计算n元组匹配数目,然后为所有候选句子加上修剪过的n元组计数,并除以测试语料库中的候选n元组个数,以计算整个测试语料库修正后的精度分数pn。ROUGEROUGEROUGE 受到了 BLEUBLEU 的启发,不同之处在于 ROUGEROUGE 采用召回率来作为指标。基本思想是将模型生成的摘要与参考摘要的 n𝑛 元组贡献统计量作为评判依据。ROUGEROUGE 由Chin-YewLin在2004年的论文《ROUGE:APackageforAutomaticEvaluationofSummaries》中提出。与 BLEUBLEU 类似,通过统计生成的摘要与参考摘要集合之间重叠的基本单元(n𝑛 元组)的数目来评估摘要的质量,该方法已成为自动文摘系统评价的主流方法。常见的 ROUGEROUGE 评价指标有 ROUGE-NROUGE-N 和 ROUGE-LROUGE-L。其中,ROUGE-NROUGE-N 计算生成的摘要与参考摘要的 n-gramn-gram 召回率,通常用 ROUGE-1/2ROUGE-1/2 来评估,而 ROUGE-LROUGE-L 则匹配两个文本单元之间的最长公共序列(LCS,LongestCommonSubsequence)。ROUGE-NROUGE-N 的计算方法非常简单,就是计算 n𝑛 元组的召回率:ROUGE-N=∑S∈{RefSummaries}∑n-gram∈SCountmatch(n-gram)∑S∈{RefSummaries}∑n-gram∈SCount(n-gram)ROUGE-N=∑𝑆∈{RefSummaries}∑n-gram∈𝑆𝐶𝑜𝑢𝑛𝑡𝑚𝑎𝑡𝑐ℎ(n-gram)∑𝑆∈{RefSummaries}∑n-gram∈𝑆𝐶𝑜𝑢𝑛𝑡(n-gram)其中 RefSummariesRefSummaries 表示参考摘要集合,Countmatch(n-gram)𝐶𝑜𝑢𝑛𝑡𝑚𝑎𝑡𝑐ℎ(n-gram) 表示生成的摘要和参考摘要中同时出现的 n-gramn-gram 的个数,Count(n-gram)𝐶𝑜𝑢𝑛𝑡(n-gram) 则表示参考摘要中出现的 n-gramn-gram 个数。因此分子就是生成摘要与参考摘要相匹配的 n-gramn-gram 个数,分母就是参考摘要中所有的 n-gramn-gram 个数。Rouge-LRouge-L 使用了最长公共子序列,L即是LCS(longestcommonsubsequence,最长公共子序列)的首字母,其计算方式如下:Rlcs=LCS(X,Y)mPlcs=LCS(X,Y)nFlcs=(1+β2)RlcsPlcsRlcs+β2Plcs𝑅𝑙𝑐𝑠=𝐿𝐶𝑆(𝑋,𝑌)𝑚𝑃𝑙𝑐𝑠=𝐿𝐶𝑆(𝑋,𝑌)𝑛𝐹𝑙𝑐𝑠=(1+𝛽2)𝑅𝑙𝑐𝑠𝑃𝑙𝑐𝑠𝑅𝑙𝑐𝑠+𝛽2𝑃𝑙𝑐𝑠其中 LCS(X,Y)𝐿𝐶𝑆(𝑋,𝑌) 是 X𝑋 和 Y𝑌 的最长公共子序列的长度,m,n𝑚,𝑛 分别表示参考摘要和生成摘要的长度(一般就是所含词的个数),Rlcs,Plcs𝑅𝑙𝑐𝑠,𝑃𝑙𝑐𝑠 分别表示召回率和准确率。最后的 Flcs𝐹𝑙𝑐𝑠 即是我们所说的 ROUGE-LROUGE-L。通常 β𝛽 被设置为一个很大的数,所以 ROUGE-LROUGE-L 几乎只考虑了 Rlcs𝑅𝑙𝑐𝑠,也就是召回率。计算BLEU分数NLTK自然语言工具包库提供了 BLEUBLEU 评分的实现,你可以使用它来评估生成的文本。语句BLEU分数NLTK提供了 sentence_bleu() 函数,用于根据一个或多个参考语句来评估候选语句。参考语句必须为语句列表,其中每个语句是一个词语列表。候选语句则直接是一个词语列表。例如:fromnltk.translate.bleu_scoreimportsentence_bleureference=[['this','is','a','test'],['this','is''test']]candidate=['this','is','a','test']score=sentence_bleu(reference,candidate)print(score)#>1.0语料库BLEU分数NLTK还提供了一个称为 corpus_bleu() 的函数来计算多个句子的 BLEUBLEU 分数。参考文档必须为文档列表,其中每个文档是一个参考语句列表,每个参考语句是一个词语列表。候选文档必须被指定为句子列表,每个句子是一个词语列表。以下是一个候选文档、两个参考文档的例子。#tworeferencesforonedocumentfromnltk.translate.bleu_scoreimportcorpus_bleureferences=[[['this','is','a','test'],['this','is''test']]]candidates=[['this','is','a','test']]score=corpus_bleu(references,candidates)print(score)#>1.0运行这个例子就像之前一样输出满分设置N-Gram权重NLTK中提供的 BLEUBLEU 评分方法还允许你在计算 BLEUBLEU 分数时为不同的 n𝑛 元组指定不同的权重。权重被指定为一个数组,其中每个索引对应相应次序的 n𝑛 元组,然后通过计算加权几何平均值来对它们进行加权计算。默认情况下,sentence_bleu() 和 corpus_bleu() 分数计算累加的4元组 BLEUBLEU 分数,也称为 BLEU-4BLEU-4 分数。例如 BLEU-4BLEU-4 对1元组,2元组,3元组和4元组分数的权重都为 1414:#4-gramcumulativeBLEUfromnltk.translate.bleu_scoreimportsentence_bleureference=[['this','is','small','test']]candidate=['this','is','a','test']score=sentence_bleu(reference,candidate,weights=(0.25,0.25,0.25,0.25))print(score)#>0.707106781187累加的1元组和单独的1元组 BLEUBLEU 使用相同的权重,也就是 (1,0,0,0)。累加的2元组 BLEUBLEU 分数为1元组和2元组分别赋 50%50% 的权重,计算累加的3元组BLEU为1元组,2元组和3元组分别为赋 33%33% 的权重。例如计算 BLEU-1,BLEU-2,BLEU-3,BLEU-4BLEU-1,BLEU-2,BLEU-3,BLEU-4 的累加得分:#cumulativeBLEUscoresfromnltk.translate.bleu_scoreimportsentence_bleureference=[['this','is','small','test']]candidate=['this','is','a','test']print('Cumulative1-gram:%f'%sentence_bleu(reference,candidate,weights=(1,0,0,0)))print('Cumulative2-gram:%f'%sentence_bleu(reference,candidate,weights=(0.5,0.5,0,0)))print('Cumulative3-gram:%f'%sentence_bleu(reference,candidate,weights=(0.33,0.33,0.33,0)))print('Cumulative4-gram:%f'%sentence_bleu(reference,candidate,weights=(0.25,0.25,0.25,0.25)))#>Cumulative1-gram:0.750000#>Cumulative2-gram:0.500000#>Cumulative3-gram:0.632878#>Cumulative4-gram:0.707107可以看到结果的差别很大,比单独的 n-gramn-gram 分数更具有表达性。在描述文本生成系统的性能时,通常会报告从 BLEU-1BLEU-1 到 BLEU-4BLEU-4 的累加分数。计算ROUGE值考虑到实践中最经常计算的就是 ROUGE-1ROUGE-1、ROUGE-2ROUGE-2 和 ROUGE-LROUGE-L 这三个评估指标,因此简单地使用rouge库就可以了,它虽然只能计算 ROUGE1/2/LROUGE1/2/L,但是十分方便。先通过 pipinstallrouge 安装,然后就可以直接调用 Rouge.get_scores() 计算了:fromrougeimportRougecandidate=['iamastudentfromxxschool']#预测摘要,可以是列表也可以是句子reference=['iamastudentfromschoolonchina']#真实摘要rouge=Rouge()rouge_score=rouge.get_scores(hyps=candidate,refs=reference)print(rouge_score[0]["rouge-1"])print(rouge_score[0]["rouge-2"])print(rouge_score[0]["rouge-l"])#>{'f':0.7999999950222222,'p':0.8571428571428571,'r':0.75}#>{'f':0.6153846104142012,'p':0.6666666666666666,'r':0.5714285714285714}#>{'f':0.7929824561399953,'p':0.8571428571428571,'r':0.75}candidates=['iamastudentfromxxschool','happynewyear']references=['iamastudentfromschoolonchina','happybirthday']rouge_score=rouge.get_scores(hyps=candidates,refs=references,avg=True)print(rouge_score["rouge-1"])print(rouge_score["rouge-2"])print(rouge_score["rouge-l"])#>{'r':0.625,'p':0.5952380952380952,'f':0.5999999951111111}#>{'r':0.2857142857142857,'p':0.3333333333333333,'f':0.3076923052071006}#>{'r':0.625,'p':0.5952380952380952,'f':0.5999999951111111}结果会输出在参考摘要的 1-gram1-gram 和 2-gram2-gram 的准确率、召回率和F1值。ROUGE-LROUGE-L 类似,最长公共子序列在生成的摘要中所占比例是准确率,在参考摘要中所占比例是召回率,然后可以计算出F1值。注意:对于英文直接把句子输入即可,中文如果没有空格就无法识别词,所以得先分词之后再计算 ROUGEROUGE 值。如果以字为单位也得每个两个字中间加一个空格。参考[1] AGentleIntroductiontoCalculatingtheBLEUScoreforTextinPython[2] 浅谈用Python计算文本BLEU分数[3] ROUGE评价方法详解(一)[4] 自动文摘评测方法:Rouge-1、Rouge-2、Rouge-L、Rouge-S[5] pyrouge和rouge,文本摘要评测方法库
|
|