ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

qgeval评测工具:统一BLEU、METEOR、ROUGE的文本生成指标实践

qgeval评测工具:统一BLEU、METEOR、ROUGE的文本生成指标实践 简介qgeval是一款基于Python的文本生成质量评估工具面向NLP研究人员与开发者用于快速计算Bleu、METEOR和ROUGE分数适用于机器翻译、文本摘要等任务的模型性能评测其实现遵循标准评估协议提供可复现的分数输出。压缩包共26个文件以Python源码13个py及编译后的pyc模块为主包含bleu、meteor、rouge、cider等指标实现另有README、LICENSE、依赖jar包及数据文件整体约64.99MB目录结构按指标模块划分便于定位与二次开发。目前已有1494人学习下载。源码中提供了各指标的评分脚本、格式处理工具和示例数据如meteor的Java评分器可帮助理解n-gram匹配、同义词对齐与召回率计算等核心思想直接接入Python工作流即可完成多维度评估适合需要客观量化生成质量的算法工程师及学术研究者。 最近在做文本生成模型的横向对比机器翻译、摘要、对话这几个场景跑完一轮手里攒了一批候选结果。要在实验报告里交代清楚这批结果怎么样绕不开三个名字Bleu、METEOR、ROUGE。这三个指标几乎是自然语言生成任务里的默认配置但真正要在一个项目里把它们都用起来你会发现每个指标踩的坑还不一样。qgeval就是我在这个阶段找到的一个顺手的工具它把这三种分数统一封装成一套API输入候选句和参考句直接出分数不用再自己拿nltk拼装、不用为参数版本头疼。如果你也正在做NLG相关的实验或者论文里需要补一组自动指标分数这篇文章就是给你写的。我会把三个指标的原理、qgeval的安装调用、完整评测脚本、以及我实际跑实验时踩过的坑都捋一遍。1. 为什么搞文本生成的人需要一套统一评测工具做文本生成实验的人应该都有过这种体验模型跑完生成了几百条结果下一步必须算分。机器翻译要看Bleu摘要要看ROUGE对话和图像描述又经常用METEOR。如果每个指标都自己写脚本或者从不同的项目里东拼西凑很容易遇到几个问题。第一个问题是实现成本。Bleu看起来简单但精确匹配、n-gram、短句惩罚这些细节处理不好分数就会和论文对不上。ROUGE在nltk里并没有直接实现通常需要额外引入rouge_score这类库。METEOR的完整实现更麻烦它涉及词形还原、同义词匹配nltk老版本里虽然有但后期版本一度移除很多人卡在环境依赖上。第二个问题是参数不统一。Bleu要用哪种平滑策略ROUGE算的是ROUGE-1还是ROUGE-LMETEOR用哪个语言模型做词形还原这些参数直接影响最终数字。同一个模型换个脚本重新算一遍分数可能差出好几个点。论文里写“Bleu 28.4”别人复现时算出来是27.1这个锅往往不是模型的问题是评测脚本的问题。qgeval这套工具的价值就在于把这三个指标的口径统一了。它对上层暴露的是一套简短的API内部实现细节默认到一套合理的配置上。我在几个项目里用下来最舒服的一点就是不用再为一个指标配一个环境命令统一、输出结构统一实验记录和复现都变得清爽很多。适合用这套工具的人我总结下来有三类做课程设计或毕业论文的本科生需要快速给模型打分做研究的硕博生和算法工程师需要稳定可复现的评测口径以及任何不想在评测环节浪费时间的NLG从业者。2. 先把三个指标的原理搞清楚用工具之前先搞清楚工具在算什么。这三个指标听起来名字差不多但设计思路完全不同。如果你只知道调用API而不知道指标背后的偏向很容易被分数误导。2.1 Bleu基于n-gram精确匹配的机器翻译老牌指标Bleu最早是IBM在2002年提出的机器翻译评测指标核心思想很朴素候选译文和参考译文在n-gram层面重合得越多分数越高。它计算的是modified precision也就是在候选句子中统计n-gram出现次数并在匹配时参考句子中限制每个n-gram的最大计数防止重复词刷分。Bleu还有一个关键设计叫做brevity penalty短句惩罚。如果一个候选翻译比参考译文短哪怕每个词都匹配上了分数也会被压缩。原因是机器翻译系统倾向于输出“安全”的短句漏译的部分无法通过precision体现出来短句惩罚就是为了抑制这种情况。实际使用中Bleu通常计算的是1-gram到4-gram的加权几何平均所以它既看词汇选择的准确性也看语序和句法结构的吻合度。但Bleu有个近些年被反复讨论的缺点它只做精确匹配同义词、词形变换都算作不匹配。中文里“美丽”和“漂亮”英文里“run”和“ran”在Bleu眼里完全是两回事。这也是为什么后来有了METEOR。2.2 METEOR比Bleu更“懂”同义词和词形变化METEOR是卡内基梅隆大学在2005年前后提出的指标名字来源于Metric for Evaluation of Translation with Explicit ORdering。它的设计动机就是弥补Bleu对同义词和词形变化不敏感的缺陷。METEOR在匹配阶段有几个层次精确匹配之外会做词形还原让“runs”“running”“ran”都能对齐到同一个词根还会使用WordNet的同义词集让“car”和“automobile”互相匹配。这一点非常实用因为优秀的译文本来就不需要和参考译文逐字一致METEOR的分数更能反映出“意思到位了”。在匹配对齐完成之后METEOR会把匹配结果组织成尽量少的连续块块数量越少说明语序越接近参考。同时它使用调和平均来综合precision和recall并且recall的权重更高一些。在机器翻译中METEOR和人工评价的相关性通常比Bleu高代价是计算更慢、依赖外部词形资源。需要注意METEOR对语言比较挑英文效果好对中文和一些资源匮乏语言的表现不稳定。2.3 ROUGE和Bleu互补的召回率导向指标ROUGE是文本摘要领域使用最广的指标全称就是Recall-Oriented Understudy for Gisting Evaluation。和Bleu侧重精确率不同ROUGE的核心是召回率参考摘要里出现的词或短语有多少在候选摘要中出现了。ROUGE家族里有几个常用变体。ROUGE-1比较参考句子和候选句子之间的unigram重合ROUGE-2比较bigram重合ROUGE-L则基于最长公共子序列计算它对语序有一定敏感性又不死抠连续完全匹配。由于摘要任务天然关心“参考里的关键信息是否被覆盖到”ROUGE这种以召回为主的思路更贴合任务目标。好用的评测习惯是把ROUGE和Bleu搭配起来看一个看生成内容是否过度保守一个看是否覆盖了必要信息。两者互补比单看某一个指标要可靠得多。3. qgeval的安装与核心API5分钟跑通第一个例子原理说清楚了下面直接上手。qgeval的安装很常规核心API也不难我建议你在一个新环境里操作避免和已有依赖打架。3.1 环境准备与安装我用的环境是Python 3.9其他3.8以上的版本应该也没问题。安装qgeval只需要一条命令pip install qgeval安装过程中会自动带上依赖主要会用到的底层库是nltk。如果你系统里之前装过老版本nltk建议顺手升一下pip install -U nltkMETEOR和ROUGE计算都需要一些语言资源。我第一次跑METEOR时直接报错提示缺少wordnet后来总结出一句话装完qgeval之后先把nltk常用的几个资源包手动下好免得运行时才到处查。import nltk nltk.download(wordnet) nltk.download(omw-1.4) nltk.download(punkt)3.2 核心调用方式Bleuqgeval的调用方式非常统一。计算Bleu的代码示例如下import qgeval cands [ the cat is on the mat, a fast brown fox jumps over the lazy dog ] refs [ [a cat is sitting on the mat], [the quick brown fox jumps over the lazy dog] ] result qgeval.eval.bleu(cands, refs, smoothTrue) print(result)输出是一个列表每项对应一条候选句子的分数最后还会附加一个平均值。smooth参数对应的是Bleu的平滑策略建议保持默认的True。现在大多数实验都默认使用平滑版本因为不做平滑的话短文本或n-gram匹配为0时会得到不合理的低分。3.3 METEOR与ROUGE调用METEOR的调用方式几乎一样meteor_scores qgeval.eval.meteor(cands, refs) print(meteor_scores)ROUGE调用时会返回多个子分数的字典rouge_scores qgeval.eval.rouge(cands, refs) # 返回格式里会包含 rouge-1、rouge-2、rouge-l 的 f-measure print(rouge_scores)我建议先跑一个只有两条数据的样例确认输出格式符合预期再上全量数据。qgeval对输入格式有要求cands是候选句子列表refs是参考句子的列表的列表也就是每条候选可以对应多条参考。如果你手头参考语料只有一条要保证refs最内层仍然是列表。4. 实操搭一个批量评测翻译结果的脚本工具跑通之后真正干活的时候需要处理批量数据。我来展示一个完整脚本它的功能是读入两个文件一个候选文件一个参考文件批量计算三个指标并把汇总结果打印出来。4.1 准备评测数据我在项目里一般用txt或jsonl存结果。txt的话一行放一条候选参考文件同样一行一条如果一条候选有多条参考可以按tab分隔写在同一行。数据格式约定如下# cands.txt the cat is on the mat a fast brown fox jumps over the lazy dog# refs.txt a cat is sitting on the mat the cat is on the mat the quick brown fox jumps over the lazy dog4.2 完整脚本与逐行解读import qgeval def read_lines(path): with open(path, r, encodingutf-8) as f: return [line.strip() for line in f if line.strip()] def read_refs(path): refs [] with open(path, r, encodingutf-8) as f: for line in f: parts line.strip().split(\t) refs.append([p for p in parts if p]) return refs cands read_lines(cands.txt) refs read_refs(refs.txt) assert len(cands) len(refs), cands和refs行数不一致 bleu_result qgeval.eval.bleu(cands, refs, smoothTrue) meteor_result qgeval.eval.meteor(cands, refs) rouge_result qgeval.eval.rouge(cands, refs) print(Bleu:, bleu_result) print(METEOR:, meteor_result) print(ROUGE:, rouge_result)这个脚本有几个点值得说。read_lines里过滤了空行避免空字符串参与计算。read_refs用split(\t)解析多参考数据这样格式比较灵活。读取数据后的assert检查是一个好习惯行数对不上时立即报错省得后面算完发现缺了一行。在真实项目里我通常会把这些分数再聚合成一个总体均值。qgeval返回的结果在列表最后已经附带平均值直接取用即可如果想自己聚合取列表前n项做均值也是一样的逻辑。4.3 解读输出怎么看这些分数跑完脚本后输出大概长这样Bleu: [0.612, 0.337, 0.4745] METEOR: [0.583, 0.426, 0.5045] ROUGE: {rouge-1: 0.726, rouge-2: 0.438, rouge-l: 0.669}看到这种数字第一反应不是“分数高就好”而是结合任务去判断。机器翻译领域Bleu超过30就已经算不错的系统但换个领域、换个语种这个基线可能完全不适用。ROUGE在摘要任务里ROUGE-1一般会比ROUGE-2高不少如果ROUGE-2异常低说明生成结果和参考在关键短语层面的重合度很低模型可能只是在关键词层面“撞车”。一个特别容易踩的坑是拿不同评测配置下的分数去对比。比如A论文用了带平滑的Bleu你的项目里为了“原汁原味”关掉了平滑最后分数差了2个点结论可能就反了。用qgeval统一配置之后至少在同一批实验内部分数是可比的。5. 常见问题与避坑指南这部分是我跑评测时真实踩过的坑整理成问题清单方便以后排查。5.1 高频报错与解决报错信息原因解决办法LookupError: resource wordnet not foundnltk词形资源缺失提前执行 nltk.download(wordnet) 和 nltk.download(omw-1.4)中文/日文句子分数极低输入未按空格分词先用分词工具处理成空格分隔的token序列METEOR运行极慢每条候选句子过长或数据量大分批计算或者确认是否真的需要METEORROUGE返回结果里缺少期望的子项版本间子指标命名不同先打印一下返回字典的keys确认子指标键名cands和refs数量对不上文件解析过滤了空行导致错位检查原文件最后一行是否有多余换行使用assert前置校验5.2 那些容易忽略的评测细节第一个要注意的是分词一致性。Bleu和ROUGE都基于空格分词英文天然合适但中文如果整句塞进去n-gram几乎对不上分数会惨不忍睹。计算前一定要用jieba或其他分词工具把中文切成空格分隔的token串。这一点对METEOR同样重要因为底层词形还原和匹配都是基于token进行的。第二个细节是多参考带来的差异。同一个候选句子匹配一条参考和多条参考分数差别很大。qgeval支持多参考如果你手里数据是多参考的一定要用全参考越多评测结果越稳定。第三个是分数可比性问题。不同论文之间对比指标分数前提是数据预处理、分词方式、平滑策略都得一致。我在实际实验里发现中文数据集上光分词方式不同BLEU就能差出3到5个百分点。所以记录实验时我会把评测脚本版本、分词方式、是否平滑一并记下来这样后续复盘才能说得清。第四个是METEOR的语言依赖。METEOR对英文支持最成熟对中文需要额外的语言资源和配置效果没那么稳。如果你做的是中文摘要实验METEOR的结果通常只作为参考不建议作为主要指标。最后一个提醒是评估数据量的影响。几十条样本算出来的分数方差很大指标给出的置信意义有限。尽量在几百条以上的样本上评测否则数字波动太大看不出模型之间的真实差异。从个人经验来说qgeval最好的使用方式是把它作为团队的统一评测工具而不是每个项目临时写脚本。一旦大家都用同一套工具、同一份配置分数就有了可比的基础省去大量“你这个数怎么跟我对不上”的沟通成本。后续我还会在更多多语言评测场景里试试它的表现METEOR之外也想看看它在其他语种上是否还能保持稳定。本文还有配套的精品资源点击获取
返回列表