©作者 | 岳天驰
单位 | 腾讯
研究方向 | 自然语言处理
背景
由于用户在文本输入法,语音输入法使用上的随意性,后续又缺少审核,极易产生语法错误内容。近年来随着自媒体的热潮,人人都是信息的生产者,互联网上语法错误的内容暴增,有分析表明中文网络新闻标题和正文的语法错误率超过 1%,这些语法不通顺的文本极大影响了用户体验。以输入“语法纠错方法调研”为例,可能产生的错误如下所示:
▲ 图1 错误类型
目前许多文本内容相关的产品都内嵌了语法纠错服务,优秀的语法纠错系统进而帮助提升用户体验。例如在搜索场景中,搜索引擎会对用户输入的 query 纠错后再精准返回搜索结果,在语音交互场景中,语音系统会将用户的语音转换成正确的文本后再进行后续的意图识别与交互。
因此文本语法纠错(Grammatical Error Correction)的研究应运而生,它是指自动检测出句子语法不通顺的错误,然后将检测出的错误进行纠正,进而减少人工校验成本。其在搜索 query,OCR,ASR,写作辅助与文章审核等场景中有着广泛的应用。本人最近对于学术界和工业界的语法纠错相关研究进展进行了调研和总结,下面将进行详细介绍。
本文的组织如下:
背景
语法纠错
中文错别字检测
工业界方法
评测方法
总结
参考论文
语法纠错
2.1 综述
虽然语法纠错(Grammatical Error Correction)在很多实际场景有着重要的应用,但是这个任务在学术界一直是不温不火的状态,近年研究成果较机器翻译、信息抽取等少很多。纠错任务的传统方案一般是 pipeline 方法:错误检测,候选召回,候选排序三步走,随着近年来 seq2seq 等 NMT 方法在文本生成上的突出效果,学术界更多的方案采用端到端的生成正确句子的方法。根据调研发现目前学术界的研究方向主要分为以下三个部分:
训练数据自动构造方法:深度学习模型的训练尤其是 seq2seq 通常需要大规模的训练数据,然而错误与正确文本的训练数据 pair 是非常少的,因此很多方法都研究构建伪数据来增强训练数据,尽可能使伪造数据近似于现实情况。
基于序列标注的纠错方法:基于 Token 级进行修改(增删改)。
基于文本生成的纠错方法:利用生成模型直接使用错误文本生成正确文本。
由于 GEC 的学术研究很少基于中文数据,本章的调研将对这三个部分在英文的研究进行介绍。内容简要总结如下:
2.2 学术界相关工作
2.2.1 构建数据方法
语法纠错的数据主要是以句子对的方式表现,包括错误句子和改正句子。然而由于纠错需要较多的语言知识和背景,标注成本很高,很难获得大规模的训练数据。尤其要是采用 seq2seq 模型对数据的需求会更大,因此大部分的语法纠错研究关注在如何模拟真实的场景自动构建大规模的训练数据。很多研究证明,借助于自动构建的数据对语法纠错模型有显著作用。
文章 [6] 详细分析了构造数据对语法纠错的重要性以及不同构造方法的优劣,对于引入构造数据,有几个关键因素:1)构造数据的方法;2)构造数据的种子语料;3)训练策略。作者基于 Transformer 的 Encoder-Decoder 结构实验发现,直接进行加噪声相比于几种翻译方法效果较好,种子数据的领域影响不大,预训练-微调的策略相比联合训练要好,同时数据量级越大效果越好。
下面具体介绍几大类数据构建的方法:
1. 基于规则的方法
对于这个任务,很容易想到可以根据图 1 的几种错误类别制定策略构建数据,包括随机删词,随机加词,随机替换词,随机乱序等。文章 [1] 借鉴去噪自编码的方法,对文本进行随机处理加噪声,然后使用 seq2seq 对其复原,将训练好的 seq2seq 迁移到真实数据上进行微调,模型 loss 采用 MaskedLoss, 也就是只计算加噪声部分的 loss,其余部分只计算 3% 的位置。可以强迫模型学习有意义的表示,而不是直接复制原文。
2. 基于文本生成的方法
既然目标是用错误文本生成正确文本,那么自然而然也会想到用正确文本生成错误文本。很多研究利用 seq2seq 模型自动生成纠错 pair。文章 [3] 构建了一个分类器和 encoder-decoder 自编码器,首先将错误句子编码得到隐向量,模型有两个目标,一是进行错误类别分类,另一个是利用隐向量进行 decoder 自编码。巧妙的是它如何生成特定类型的数据,对于刚才训练好的模型,输入正确句子和指定错误类别 z,首先对隐向量 h 加上随机扰动 r,基于扰动向量预测错误类别 z',最小化分类 loss,然后就可以更新这个扰动 r,再基于更新后的表示进行解码,就可以生成指定类型的错误了 ,具体如下图所示。
文章 [4] 提出了一种 fluency boost sentence pairs 的训练数据补充方法。出发点是基于错误句子-正确句 pair 训练的 seq2seq 模型会生成 n-best 个句子。那么这些句子中 ppl 低于正确的句子就还可以和正确句子组合成一个 pair,这样子补充的数据就又可以在训练中利用。
3. 借助翻译的方法
构建数据主要是想构建语法错误或逻辑上的错误,而现在的机器翻译模型的效果也很易产生错误,因此可以利用某个中间语言作为桥梁构建错误样本,就是先将句子翻译成英文,再翻译回来,构建成 pair [2]。文章 [5] 借助于 NMT 翻译模型显著好于 SMT 翻译模型的特点,利用 NMT 生成 Good 句子,利用 SMT 生成 poor 句子,构建 Poor-Good pair,利用这个 pair 构建训练数据 。但是翻译方法会存在一个问题是,语法错误会比较固定。
4. 借助外部数据
Google 借助于维基百科最后的句子可能是语法错误较少的句子,根据编辑历史构造 pair [2]。这种方法依然会存在问题,包括 pair 的大幅变化,未全部改正,百科的 spam 等等。
5. 选择替换位置
从经验来看,人不一定是在所有的地方都容易写错,那么实际数据的错误位置分布也应该是不均衡的。文章 [7] 首先识别大概率容易错的地方。在这里有个巧妙的地方就是,他根据 seq2seq 解码的时候每个步骤的预测概率来判断当前词是不是可能有问题,然后根据 attention 对齐去找到原文本对应的位置。找到位置后再进行替换,生成错误句子。
如上所述的自动构建数据方法还是存在一些问题:
预定义的加噪声规则或者(错误-正确对)替换方法会让模型去学习到这些策略。而这些策略与真实的场景还是有点差异或覆盖不全,进而限制模型的泛化性能
一些基于生成或翻译的方法,无法定位错误片段,其可能表达的意思与输入有很大不同了。
构建的样本可能带入噪声,伪正例对模型训练会造成困扰。
2.2.2 序列标注模型
目前纠错模型的研究方向主要是两种,一是基于序列标注的纠正,出发点在于 seq2seq 生成文本的可控性较差,decode 的推理速度也比较慢。在语法纠错的场景中,错误文本和正确文本的交集特别大,因此可以联系到字符串编辑距离的方式,如何通过较少的 token 编辑操作将错误文本改造成正确文本。
文章 [9] 是比较早用 tag 方式做纠错的,他首先定义了 copy, appends, deletes, replacements, ,case-changes 这些编辑操作,比如下图的错误句子 X 和正确句子 y,可以得出编辑方法 e,然后对每个 token 打上标记。再使用迭代序列标注方法预测 token- 级别的编辑操作。
文章 [8] 设置了两种标签 keep 和 delete,然后在 keep 和 delete 的基础上添加额外标签 P(表示在当前位置需要在前面加入短语 P,P 是空或单词或短语),如下图所示 。实验设置的词表 V 大小只有500(覆盖 85% 的训练数据),在实际应用场景可能会很大,所以整个预测空间是 2V(V 代表词表大小,2 是 keep 或 delete)。模型上在 BERT 的输出后添加 MLP 或 transformer decoder 进行序列标注。
文章 [10] 详细定义了多种语法操作的 tag。tag 空间达到了 5000 个,包括 KEEP,DELETE,1167 个依赖于 token 的 append,3802 个 replace,和 29 个独立于 token 的语法变化(包括 CASE:大小写,MERGE:将当前 TOKEN 和后面 TOKEN 合并成一个,SPLIT:将当前 TOKEN 拆成两个,单复数转换,时态转换等等)。
因为语法纠错的数据都是 wrong-correct pair,所以首先需要做的是预处理,对错误句子的每个 token 打上前面定义的 tag,这部分需要较为复杂的处理,具体实现可以去论文里参考代码。序列标注的数据生成好了,那么后面就很简单了,模型上就是基于 bert 的 tagging 模型,采用迭代序列标注的方法多轮 tagging。这个方法是 grammaly 在 conll 数据上的 sota,应该是和工业应用场景比较接近,基于 tag 方法的纠错就是需要这种细致的数据处理和 tag 定义。
这几种基于编辑的方法上准确率会很高,可控性和解释性很强。但是需要对数据的细致分析和处理,tag 的定义取舍要求较高。由于一般不会把 tag 的集合设置过大,在封闭集上效果会较好,但开放集上的复杂情况和长尾问题很难处理。目前还没发现这种方法在中文上的应用。
2.2.3 生成模型
语法纠错的目的是利用原句得到正确的句子,与机器翻译的任务很相似,所以将机器翻译的生成模型引入到语法纠错中取得了很好的效果。与机器翻译的区别是,target 和 source 是同一种语言,且有很大的交集,也比较容易想到可以借鉴文本摘要中的 Copy 机制 。那么主要的研究方向包括,数据使用及训练策略,如何解决 target 和 source 交集过多的问题,解码策略。
数据使用及训练策略:
文章 [11] 首先基于去噪自编码方法在大规模数据上预训练,同时引入 token 级序列标注(判断这个 token 是否错误)和句子级别 copy(判断改句子是否正确,正确就是应该全 copy)做多任务提升 copy 机制在正确句子上的效果。
文章 [16] 不同于在预处理阶段静态扩增数据