浅谈用 Python 计算文本 BLEU 分数

BLEU, 全称为 Bilingual Evaluation Understudy(双语评估替换), 是一个比较候选文本翻译与其他一个或多个参考翻译的评价分数

尽管 BLEU 一开始是为翻译工作而开发, 但它也可以被用于评估文本的质量, 这种文本是为一套自然语言处理任务而生成的

通过本教程, 你将探索 BLEU 评分, 并使用 Python 中的 NLTK 库对候选文本进行评估和评分

完成本教程后, 你将收获:

BLEU 评分的简单入门介绍, 并直观地感受到到底是什么正在被计算

如何使用 Python 中的 NLTK 库来计算句子和文章的 BLEU 分数

如何用一系列的小例子来直观地感受候选文本和参考文本之间的差异是如何影响最终的 BLEU 分数

让我们开始吧

浅谈用 Python 计算文本 BLEU 分数

照片由 Bernard Spragg. NZ 提供, 保留所有权

教程概述

本教程分为 4 个部分; 他们分别是:

双语评估替换评分介绍

计算 BLEU 分数

累加和单独的 BLEU 分数

运行示例

双语评估替换评分

双语评估替换分数 (简称 BLEU) 是一种对生成语句进行评估的指标

完美匹配的得分为 1.0, 而完全不匹配则得分为 0.0

这种评分标准是为了评估自动机器翻译系统的预测结果而开发的尽管它还没做到尽善尽美, 但还是具备了 5 个引人注目的优点:

计算速度快, 计算成本低

容易理解

与具体语言无关

和人类给的评估高度相关

已被广泛采用

BLEU 评分是由 Kishore Papineni 等人在他们 2002 年的论文 BLEU: a Method for Automatic Evaluation of Machine Translation 中提出的

这种评测方法通过对候选翻译与参考文本中的相匹配的 n 元组进行计数, 其中一元组 (称为 1-gram 或 unigram) 比较的是每一个单词, 而二元组 (bigram) 比较的将是每个单词对这种比较是不管单词顺序的

BLEU 编程实现的主要任务是对候选翻译和参考翻译的 n 元组进行比较, 并计算相匹配的个数匹配个数与单词的位置无关匹配个数越多, 表明候选翻译的质量就越好

摘自论文 BLEU: a Method for Automatic Evaluation of Machine Translation,2002 年发表

n 元组匹配的计数结果会被修改, 以确保将参考文本中的单词都考虑在内, 而不会对产生大量合理词汇的候选翻译进行加分在 BLEU 论文中这被称之为修正的 n 元组精度

糟糕的是, 机器翻译系统可能会生成过多的合理单词, 从而导致翻译结果不恰当, 尽管其精度高... 从直观上这个问题是明显的: 在识别出匹配的候选单词之后, 相应的参考单词应该被视为用过了我们将这种直觉定义为修正的单元组精度

摘自论文 BLEU: a Method for Automatic Evaluation of Machine Translation,2002 年发表

BLEU 评分是用来比较语句的, 但是又提出了一个能更好地对语句块进行评分的修订版本, 这个修订版根据 n 元组出现的次数来使 n 元组评分正常化

我们首先逐句计算 n 元组匹配数目接下来, 我们为所有候选句子加上修剪过的 n 元组计数, 并除以测试语料库中的候选 n 元组个数, 以计算整个测试语料库修正后的精度分数 pn

摘自论文 BLEU: a Method for Automatic Evaluation of Machine Translation,2002 年发表

实际上, 一个完美的分数是不可能存在的, 因为这意味着翻译必须完全符合参考甚至连人类翻译家都不能做到这点对计算 BLEU 分数的参考文本的数量和质量的水平要求意味着在不同数据集之间的比较 BLEU 分数可能会很麻烦

BLEU 评分的范围是从 0 到 1 很少有翻译得分为 1, 除非它们与参考翻译完全相同因此, 即使是一个人类翻译, 也不一定会在一个大约 500 个句子 (也就是 40 个普通新闻报道的长度) 的测试语料上得 1 分, 一个人类翻译在四个参考翻译下的得分为 0.3468, 在两个参考翻译下的得分为 0.2571

摘自论文 BLEU: a Method for Automatic Evaluation of Machine Translation,2002 年发表

除了翻译之外, 我们还可以将 BLEU 评分用于其他的语言生成问题, 通过使用深度学习方法, 例如:

语言生成

图片标题生成

文本摘要

语音识别

以及更多

计算 BLEU 分数

Python 自然语言工具包库 (NLTK) 提供了 BLEU 评分的实现, 你可以使用它来评估生成的文本, 通过与参考文本对比

语句 BLEU 分数

NLTK 提供了 sentence_bleu()函数, 用于根据一个或多个参考语句来评估候选语句

参考语句必须作为语句列表来提供, 其中每个语句是一个记号列表候选语句作为一个记号列表被提供例如:fromnltk.translate.bleu_scoreimportsentence_bleu

reference=[['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()的函数来计算多个句子 (如段落或文档) 的 BLEU 分数

参考文本必须被指定为文档列表, 其中每个文档是一个参考语句列表, 并且每个可替换的参考语句也是记号列表, 也就是说文档列表是记号列表的列表的列表候选文档必须被指定为列表, 其中每个文件是一个记号列表, 也就是说候选文档是记号列表的列表

这听起来有点令人困惑; 以下是一个文档的两个参考文档的例子# two references for one document

fromnltk.translate.bleu_scoreimportcorpus_bleu

references=[[['this','is','a','test'],['this','is''test']]]

candidates=[['this','is','a','test']]

score=corpus_bleu(references,candidates)

print(score)

运行这个例子就像之前一样输出满分

1.0

累加和单独的 BLEU 分数

NLTK 中提供的 BLEU 评分方法允许你在计算 BLEU 分数时为不同的 n 元组指定权重

这使你可以灵活地计算不同类型的 BLEU 分数, 如单独和累加的 n-gram 分数

让我们来看一下

单独的 N-Gram 分数

单独的 N-gram 分数是对特定顺序的匹配 n 元组的评分, 例如单个单词 (称为 1-gram) 或单词对(称为 2-gram 或 bigram)

权重被指定为一个数组, 其中每个索引对应相应次序的 n 元组仅要计算 1-gram 匹配的 BLEU 分数, 你可以指定 1-gram 权重为 1, 对于 2 元, 3 元和 4 元指定权重为 0, 也就是权重为 (1,0,0,0) 例如:# 1-gram individual BLEU

fromnltk.translate.bleu_scoreimportsentence_bleu

reference=[['this','is','small','test']]

candidate=['this','is','a','test']

score=sentence_bleu(reference,candidate,weights=(1,0,0,0))

print(score)

运行此例将输出得分为 0.5

0.75

我们可以重复这个例子, 对于从 1 元到 4 元的各个 n-gram 运行语句如下所示:# n-gram individual BLEU

fromnltk.translate.bleu_scoreimportsentence_bleu

reference=[['this','is','a','test']]

candidate=['this','is','a','test']

print('Individual 1-gram: %f'%sentence_bleu(reference,candidate,weights=(1,0,0,0)))

print('Individual 2-gram: %f'%sentence_bleu(reference,candidate,weights=(0,1,0,0)))

print('Individual 3-gram: %f'%sentence_bleu(reference,candidate,weights=(0,0,1,0)))

print('Individual 4-gram: %f'%sentence_bleu(reference,candidate,weights=(0,0,0,1))

运行该示例, 结果如下所示:Individual1-gram:1.000000

Individual2-gram:1.000000

Individual3-gram:1.000000

Individual4-gram:1.000000

虽然我们可以计算出单独的 BLEU 分数, 但这并不是使用这个方法的初衷, 而且得出的分数也没有过多的含义, 或者看起来具有说明性

累加的 N-Gram 分数

累加分数是指对从 1 到 n 的所有单独 n-gram 分数的计算, 通过计算加权几何平均值来对它们进行加权计算

默认情况下, sentence_bleu()和 corpus_bleu()分数计算累加的 4 元组 BLEU 分数, 也称为 BLEU-4 分数

BLEU-4 对 1 元组, 2 元组, 3 元组和 4 元组分数的权重为 1/4(25%)或 0.25 例如:# 4-gram cumulative BLEU

fromnltk.translate.bleu_scoreimportsentence_bleu

reference=[['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 元组 BLEU 使用相同的权重, 也就是 (1,0,0,0) 计算累加的 2 元组 BLEU 分数为 1 元组和 2 元组分别赋 50%的权重, 计算累加的 3 元组 BLEU 为 1 元组, 2 元组和 3 元组分别为赋 33%的权重

让我们通过计算 BLEU-1,BLEU-2,BLEU-3 和 BLEU-4 的累加得分来具体说明:# cumulative BLEU scores

fromnltk.translate.bleu_scoreimportsentence_bleu

reference=[['this','is','small','test']]

candidate=['this','is','a','test']

print('Cumulative 1-gram: %f'%sentence_bleu(reference,candidate,weights=(1,0,0,0)))

print('Cumulative 2-gram: %f'%sentence_bleu(reference,candidate,weights=(0.5,0.5,0,0)))

print('Cumulative 3-gram: %f'%sentence_bleu(reference,candidate,weights=(0.33,0.33,0.33,0)))

print('Cumulative 4-gram: %f'%sentence_bleu(reference,candidate,weights=(0.25,0.25,0.25,0.25)))

运行该示例输出下面的分数结果的差别很大, 比单独的 n-gram 分数更具有表达性Cumulative1-gram:0.750000

Cumulative2-gram:0.500000

Cumulative3-gram:0.632878

Cumulative4-gram:0.707107

在描述文本生成系统的性能时, 通常会报告从 BLEU-1 到 BLEU-4 的累加分数

运行示例

在这一节中, 我们试图通过一些例子来进一步获取对 BLEU 评分的直觉

我们在语句层次上通过用下面的一条参考句子来说明:

the quick brown fox jumped over the lazy dog

首先, 我们来看一个完美的分数# prefect match

fromnltk.translate.bleu_scoreimportsentence_bleu

reference=[['the','quick','brown','fox','jumped','over','the','lazy','dog']]

candidate=['the','quick','brown','fox','jumped','over','the','lazy','dog']

score=sentence_bleu(reference,candidate)

print(score)

运行例子输出一个完美匹配的分数

1.0

接下来, 让我们改变一个词, 把 quick 改成 fast# one word different

fromnltk.translate.bleu_scoreimportsentence_bleu

reference=[['the','quick','brown','fox','jumped','over','the','lazy','dog']]

candidate=['the','fast','brown','fox','jumped','over','the','lazy','dog']

score=sentence_bleu(reference,candidate)

print(score)

结果是分数略有下降

0.7506238537503395

尝试改变两个词, 把 quick 改成 fast , 把 lazy 改成 sleepy# two words different

fromnltk.translate.bleu_scoreimportsentence_bleu

reference=[['the','quick','brown','fox','jumped','over','the','lazy','dog']]

candidate=['the','fast','brown','fox','jumped','over','the','sleepy','dog']

score=sentence_bleu(reference,candidate)

print(score)

运行这个例子, 我们可以看到得分线性下降

0.4854917717073234

如果候选语句的所有单词与参考语句的都不一样呢?# all words different

fromnltk.translate.bleu_scoreimportsentence_bleu

reference=[['the','quick','brown','fox','jumped','over','the','lazy','dog']]

candidate=['a','b','c','d','e','f','g','h','i']

score=sentence_bleu(reference,candidate)

print(score)

我们得到了一个更糟糕的分数

0.0

现在, 让我们尝试一个比参考语句的词汇更少 (例如, 放弃最后两个词) 的候选语句, 但这些单词都是正确的# shorter candidate

fromnltk.translate.bleu_scoreimportsentence_bleu

reference=[['the','quick','brown','fox','jumped','over','the','lazy','dog']]

candidate=['the','quick','brown','fox','jumped','over','the']

score=sentence_bleu(reference,candidate)

print(score)

结果和之前的有两个单词错误的情况很相似

0.7514772930752859

如果我们把候选语句调整为比参考语句多两个单词, 那又会怎么样?# longer candidate

fromnltk.translate.bleu_scoreimportsentence_bleu

reference=[['the','quick','brown','fox','jumped','over','the','lazy','dog']]

candidate=['the','quick','brown','fox','jumped','over','the','lazy','dog','from','space']

score=sentence_bleu(reference,candidate)

print(score)

再一次, 我们可以看到, 我们的直觉是成立的, 得分还是有点像 有两个错字 的情况

0.7860753021519787

最后, 我们来比较一个很短的候选语句: 只有两个单词的长度# very short

fromnltk.translate.bleu_scoreimportsentence_bleu

reference=[['the','quick','brown','fox','jumped','over','the','lazy','dog']]

candidate=['the','quick']

score=sentence_bleu(reference,candidate)

print(score)

运行此示例首先会打印一条警告消息, 指出不能执行评估 3 元组及以上部分 (直到 4 元组) 这是合乎情理的, 因为在候选语句中我们最多只能用 2 元组来运行UserWarning:

Corpus/Sentencecontains0counts of3-gram overlaps.

BLEU scores might be undesirable;useSmoothingFunction().

warnings.warn(_msg)

接下来, 我们会得到一个非常低的分数

0.0301973834223185

你可以继续用这些例子来进行其他试验

BLEU 包含的数学知识非常简单, 我也鼓励你阅读这篇论文, 并在自己电子表格程序中探索计算语句评估分数的方法

进一步阅读

如果你要深入研究, 本节将提供更多有关该主题的资源

BLEU 在维基百科的主页

BLEU: a Method for Automatic Evaluation of Machine Translation,2002 年发表

nltk.translate.bleu_score 的源码

nltk.translate 包的 API 文档

总结

在本教程中, 你探索了 BLEU 评分, 根据在机器翻译和其他语言生成任务中的参考文本对候选文本进行评估和评分

具体来说, 你学到了:

BLEU 评分的简单入门介绍, 并直观地感受到到底是什么正在被计算

如何使用 Python 中的 NLTK 库来计算语句和文章的 BLEU 分数

如何使用一系列的小例子来直观地感受候选文本和参考文本的差异是如何影响最终的 BLEU 分数

来源: https://cloud.tencent.com/developer/article/1042161

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/394482.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/394482.shtml
英文地址,请注明出处:http://en.pswp.cn/news/394482.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Unity的几个特殊文件夹

1.以.开头的文件夹会被unity忽略,资源不会被导入,脚本不会编译。 2.Standard Assets和Pro Standard Assets:在这个文件夹中的脚本最先被编译。 3.Editor:以Editor命名的文件夹允许其中的脚本访问Unity Editor的API。如果脚本中使用…

怎么上传文件到kk服务器,VS Code 关于SFTP上传文件到多服务器的配置

工欲善其事,必先利其器!刚学前端的时候一直用的DW来编写代码,其功能非常强大,但在Linux下不能用,所以就转VS Code了。但是刚开始使用VS Code的时候,很多DW上的功能需要自己安装扩展,并配置才可以…

CentOS7 Firewall NAT 及端口映射

本节介绍用CentOS7的Firewalll来做NAT以及端口映射实验拓扑:因为我的环境里CentOS7上有KVM虚拟机需要共享网卡上网,所以我把网卡都添加到了桥里面,当然这里也可以不用桥,直接用物理网口;用nmcli创建桥,并添加网口到桥&…

JVM源码---教你傻瓜式编译openjdk7(JAVA虚拟机爱好者必看)

LZ经过一个星期断断续续的研究,终于成功的搞定了JDK的成功编译与调试。尽管网络上的教程也有不少,包括源码中也有自带的编译步骤说明,但真正自己动手的话,还是会遇到不少意料之外的错误。 为了方便各位猿友编译,LZ临时…

leetcode1105. 填充书架(动态规划)

附近的家居城促销,你买回了一直心仪的可调节书架,打算把自己的书都整理到新的书架上。 你把要摆放的书 books 都整理好,叠成一摞:从上往下,第 i 本书的厚度为 books[i][0],高度为 books[i][1]。 按顺序 将…

python 微信bot_使用Tweepy在Python中创建Twitter Bot

python 微信botby Lucas Kohorst卢卡斯科斯特(Lucas Kohorst) 使用Tweepy在Python中创建Twitter Bot (Create a Twitter Bot in Python Using Tweepy) With about 15% of Twitter being composed of bots, I wanted to try my hand at it. I googled how to create a Twitter …

第五周学习进度

1.学习所花时间:单纯Java是12个小时左右; 2.代码量:大约300行; 3.博客量:1篇。 4.了解到的知识点:数据库语言的增删改查 5.下周计划除了掌握课上知识外,还要再复习之前的关于Java的相关知识点。…

另一个域的cookie_一定要知道的第一方Cookie和第三方Cookie

Cookie 是您访问过的网站创建的文件,用于存储浏览信息,例如您的网站偏好设置或个人资料信息。共有两种类型的 Cookie:第一方 Cookie 是由地址栏中列出的网站域设置的 Cookie,而第三方 Cookie 来自在网页上嵌入广告或图片等项的其他…

苹果手机怎么连接不了无线网络连接服务器,苹果手机连接wifi显示无互联网连接怎么办?...

在开始对网络操作以后,也可尝试着把 iPhone 重新启动一下,按下 iPhone 电源键不放,直到出现关机选项并滑动关机,最后再开机。在 iPhone 的无线局域网列表中,当前连接的这个无线网络显示“无互联网连接”。此时可以通过…

中小企业大数据应用之道:思维在于借力

要想大数据落地,特别是中小企业,首先得有大数据思维,否则大数据的案例不能直接借鉴,自己摸索又怕不专业、坑太多。 何谓大数据思维,个人认为不是什么决策都参考数据,也不是什么问题都要足够精准&#xff0c…

git学习心得之从远程仓库克隆

现在,远程库已经准备好了,下一步是用命令git clone克隆一个本地库: $ git clone gitgithub.com:michaelliao/gitskills.git Cloning into gitskills... remote: Counting objects: 3, done. remote: Total 3 (delta 0), reused 0 (delta 0) R…

leetcode350. 两个数组的交集 II(hashmap)

给定两个数组&#xff0c;编写一个函数来计算它们的交集。 将长度小的数组放入hashmap&#xff0c;记录出现的次数&#xff0c;遍历另一个数组&#xff0c;找出交集 class Solution {public int[] intersect(int[] nums1, int[] nums2) {ArrayList<Integer> resnew Arra…

如何使用Swift Playgrounds制作东西

by Harshita Arora通过Harshita Arora 如何使用Swift Playgrounds制作东西 (How to make something with Swift Playgrounds) Just a few days ago, I finished my WWDC 2018 scholarship submission. It was so much fun creating Alice in codeLand. This was my first year…

2018-2019 20165208 网络对抗 Exp3 免杀原理与实践

目录 2018-2019 20165208 网络对抗 Exp3 免杀原理与实践实验内容基础问题回答实践过程记录任务一&#xff1a;正确使用免杀工具或技巧任务二&#xff1a;通过组合应用各种技术实现恶意代码免杀任务三&#xff1a;用另一电脑实测&#xff0c;在杀软开启的情况下&#xff0c;可运…

k均值例子 数据挖掘_人工智能、数据挖掘、机器学习和深度学习的关系

一、人工智能人工智能是计算机科学的一个分支&#xff0c;它企图了解智能的实质&#xff0c;并生产出一种新的能以人类智能相似的方式做出反应的智能机器。实际应用比如&#xff1a;机器视觉&#xff0c;指纹识别&#xff0c;人脸识别&#xff0c;视网膜识别&#xff0c;虹膜识…

hive中sql使用英文分号

hql只要遇见分号则认识是语句的EOF&#xff0c;所以对于分号&#xff0c;需要用“\“转义。 例如&#xff1a; insert overwrite table test_json_map select {"accountid":"1_:\;11"}, t.map_col from t where dt 2017-08-08 limit 1; 或者用”\073&qu…

软件系统换服务器地址,天正软件客户端修改服务器地址

天正软件客户端修改服务器地址 内容精选换一换如果IP经过NAT/WAF&#xff0c;则只能获取到NAT/WAF转化后的IP地址&#xff0c;无法获取到NAT/WAF前的IP地址。如果客户端为容器&#xff0c;只能获取到容器所在主机的IP地址&#xff0c;无法获取容器的IP。四层监听器(TCP/UDP)开启…

orcale可视化建立用户_建立动态可视化的新方法

orcale可视化建立用户by Sushrut Shivaswamy通过Sushrut Shivaswamy 建立动态可视化的新方法 (A new way of building dynamic visualisations) The Flux architecture gained popularity after Facebook adopted it. It’s a way of managing the state of React components …

leetcode剑指 Offer 47. 礼物的最大价值(动态规划)

在一个 m*n 的棋盘的每一格都放有一个礼物&#xff0c;每个礼物都有一定的价值&#xff08;价值大于 0&#xff09;。你可以从棋盘的左上角开始拿格子里的礼物&#xff0c;并每次向右或者向下移动一格、直到到达棋盘的右下角。给定一个棋盘及其上面的礼物的价值&#xff0c;请计…

atoi()函数

原型&#xff1a;int atoi &#xff08;const char *nptr&#xff09; 用法&#xff1a;#include <stdlib.h> 功能&#xff1a;将字符串转换成整型数&#xff1b;atoi()会扫描参数nptr字符串&#xff0c;跳过前面的空格字符&#xff0c;直到遇上数字或正负号才开始做…