中文站

知物由学 | “找茬”不如交给AI算法,细说文本纠错的多种实现途径

顾名思义,文本纠错就是将文本中有错误的地方进行纠正,错误类型包含错别字、缺失字、冗余字、词语搭配错误和语法错误等。目前也有一些开源的文本纠错工具,比如pycorrector等,虽然这些工具可以满足一部分场景中的文本纠错需求,但其效果距离真正应用还有较大的差距,所以十分有必要自行上手构建一个文本纠错系统。

近年来,错别字连篇的法律文件、写错国家机构的新闻报道、国名有误的发布会现场,无不成为网友热议的对象。为何低级错误无人发现?为何专业人士竟在文字上遭遇“滑铁卢”?一连串的质疑也说明,文本纠错是内容安全的首当其冲的一面。

在避免文本错误上,人工智能或许比人类更具优势,它能够记住大量的数据,且不会被糟心事影响情绪,不仅能基于客观现实执行任务,还能够比人类更好地评估和权衡相关因素,比人类更快、更准确地识别。


一套优质的“文本纠错”系统,自动对输入文本进行纠错提示,并给予修改建议,让政府机构工作人员、媒体人、文字撰稿人、编辑、律师等职业从繁杂的文字“找茬”任务中脱离出来,快速找到一时疏忽与认知错位导致的字词错误,有效降低内容风险。本文将介绍文本纠错的相关知识,提供文本纠错的几种技术落地方式。

一、用词库对文本进行纠错

文本纠错系统通过一个内置词库对文本进行纠错,这是最简单粗暴的方式。词库在文本纠错中可以处理一些常见词语的错误,如一些常见的人名、地名或者常用词。比如“秦时皇”可以被纠正为“秦始皇”;“鼓浪与”可以被纠正为“鼓浪屿”;“洛因缤纷”可以被纠正为“落英缤纷”。

同时,词库可以对业务方反馈的badcase进行快速的修正,这在算法侧是不太现实的。填平一个badcase的坑,达到后续自动发现纠正的效果,算法侧往往需要重新花1~2周去重新训练一个模型。词库虽然行动快速,但是也难免过于“横冲直撞”。词库纠错缺乏了上下文信息的利用,其所能达到的效果是远远不够的,所以词库纠错是文本纠错中必要但不充分的一个环节。

二、BERT模式的文本纠错

自从BERT在2018年出现后,NLP领域的各大榜单基本上都被BERT模型和它的各种变种模型(RoBERTa、ERNIE、NEZHA、XLNet、BART)所占据。即使是到现在,NLP领域的各项工作都被BERT模型这种大规模数据无监督预训练+小规模数据有监督微调这种模式所影响。那么文本纠错是否可以用BERT模型来做呢?先来看一下原始的BERT模型任务。

这里由于在实际使用中我们去掉了NSP任务,所以在输入端没有加上Segment Embedding。


于是,我们可以很方便的将原始BERT模型的MLM任务改进为纠错任务。在训练/微调阶段,我们可以将15%的token随机替换成错误的字,然后让模型将正确的字还原出来,这和BERT模型的训练任务是一致的。当然这里我们也可以引入wwm、ERNIE或者spanBERT里的词边界信息来提升模型的效果,这里不再展开。)


在测试阶段,直接把原文输入给模型,让模型预测每个位置的正确token,看预测token跟原始token是否一致就可以知道每个位置的token是否有错,以及正确的token是什么。

但是,可以看到,上面我们只处理了错字这种输入和输出等长的情况,在文本纠错中还存在少字、多字等输入和输出长度不相等的情况(如“哈滨是黑龙江的省会”需要被更改为“哈尔滨是黑龙江的省会”),而原始的BERT模型对于这种情况是无法处理的。

针对上述的情况,可以有如下两种解决方案。这里我们只讨论少字的情况,因为多字情况其实仍然可以视为一个错字替换的问题(将原始token替换为空)。

方案一:预测缺失字数

在将文本输入到BERT模型之前,我们可以先用一个前置模型去预测缺失字的个数,将缺失的地方用特殊字符[MASK]进行填充,然后再使用BERT语言模型生成修正候选结果,最后通过比较多个候选修正句子的困惑度来确定缺失修正结果。如下图所示:


方案二:通过序列标注来进行文本的纠错

我们可以将文本纠错问题转化为标签序列标注问题(具体可以查看Google在2019年开源的LASERTAGGER模型),然后再根据标签所对应的编辑操作,将输入文本修改后得到正确的输出文本。具体地,在文本纠错任务中我们可以设计4类标签,分别为KEEP、DELETE、DELETE|x、KEEP|x,其中KEEP表示当前文本无需修改,DELETE表示当前文本需要删除、DELETE|x表示当前文本需要被替换为token x、KEEP|x表示需要在当前文本前插入token x。借助于这种方式,我们就可以自然地对各种不同类型的错误进行修正。


三、基于生成的文本纠错

尽管用BERT模型进行文本纠错已经可以取得不错的效果,但是仅通过BERT模型来进行文本纠错仍存在一些缺陷。在BERT模型中,每个输出的token之间是相互独立的,也就是说上一个step中输出的错误纠正并不会影响到当前step的错误纠正,那么就会导致如下图的问题:


在句子“冰是液体”中,尽管位置θ的token“冰”已经被纠正为“水”,但是该纠正信息并没有传递到位置2的token中,所以模型在预测2位置的输出时仍然会将“液”纠正为“固”,这就导致了错误。

为解决上诉问题,可以引入生成模型来进行文本纠错。在生成模型中,输出是从左向右逐个生成的,左边的输出信息可以传递到右边的输出中,因此可以解决上述的缺陷。采用生成模型进行文本纠错也有两种方案:

方案一:GPT式的生成

这种方式的实现过程也比较简单,只需要在原有的BERT模型后面在嵌入一层或多层Transformer Decoder就可以了。等价于NMT任务,需要将有错的文本翻译为没有错的文本。

方案二:UniLM式的生成

这种生成方式使用的仍然是BERT模型的架构,不需要对模型进行改变。但在预训练阶段需要通过控制AttentionMask来让模型学习如何进行生成。如下图:


UniLM文本校对过程如下图:


四、模型结果的修正

接下来,我们需要修正模型建议的结果,因为我们不能保证文本纠错模型的输出都是正确的,当模型出现误判的时候,我们需要放弃对应修改,这对提升纠错模型的准确率很有帮助。

字音、字形相似度的限制

考虑到中文的输入基本上都是拼音或者五笔,因此错误内容在字音或者字形上基本上都是相似的。基于此,我们可以通过字音、字形对修改结果进行限制。

方法一:将字音、字形作为特征输入到模型中。阿里在ACL2020提出了SPELLGCN,通过图神经网络,将字音、字形特征引入模型,其主要作用就是限制每个字的输出空间,错误字的纠正结果更应该被预测为其音近字或者形近字。

方法二:在模型外对输出结果进行字音字形的限制。该方法具体可参考FASPELL,该方法结合模型输出结果,再综合考虑字音、字形相似度来选出最终的修正结果。


句子困惑度的限制

通常,我们可以困惑度来评价一个语言模型的好坏,比如一个句子困惑度的计算可以表示为:


在这里,我们还可以训练一个模型来对修正的句子计算困惑度,当发现修改之后句子的分数反而降低了,我们就可以放弃本次修改。

文本纠错的展望

文本纠错是目前MLP领域难度较高的的一项工作,如何覆盖各种不同的错误类型,如何应对不同场景下的文本差异,是一项很有挑战性的工作。同时,文本纠错技术有着广泛的应用场景,值得我们长期投入时间和精力进行研究与打磨。