1. 背景
在很多中文NLP相关的落地场景都会涉及到文本纠错的相关技术,例如跟各种形式机器人的语音或者文字对话,或者用手机扫描相关的PDF或者图片,或者跟人聊天时用输入法打字等等,无论是通过ASR识别的语音信息,通过OCR识别得到的图片信息,还是用户真实通过输入法的文字,都有可能出现错误。这些错误会影响文本的可读性,不利于人和机器的理解,如果这些错误不加处理,会传播到后续的环节,影响后续任务的效果。常见的中文错误类型包括以下几种:
发音&音转错误
原因:音近,发音不标准,地方方言,常见语音识别,同音不同字或者相近拼音
例子:输暖管手术投保 -> 卵
拼写错误
原因:由于输入法的正确词语错误使用
例子:眼睛蛇咬了 -> 镜
OCR识别错误/字形错误
原因:ocr识别到的错误字
例子:白然语言处理 -> 自
语法错误
词缺失 每份投保能返还5%的总金额 -> 每份投保都能返还5%的总金额
词冗余 我和经理是不像别的上下级 -> 我和经理不像别的上下级
词不当 最重要的是做投资的环境 -> 最重要的是创造投资的环境
词乱序 宠物险是对宠物应该有保障的 -> 宠物险应该是对宠物有保障的
知识错误
原因:对知识的了解不足,这类往往最难识别
例子:在南山平安金融中心入职 -> 福田
在不同的场景下出现的不同的错误类型的占比也不尽相同,但是无论哪种错误,都会影响文本的质量,妨碍人或者机器的阅读理解。而NLP的大部分模型都是通过高质量的中文数据训练得到的,训练语料中没见过这些错误类型,所以如果推理时的文本输入带有这些错误,一定程度上会影响模型的理解,从而使得模型的推理效果大打折扣。
中文文本纠错任务就是检测出文本中的错误并且进行纠正,这跟小学语文老师给大家改作文的方式如出一辙,不仅要注明那个位置出错了,还要给出相应的改正措施。中文文本纠错任务包括两部分,一方面是检测任务,一方面是纠正任务,必须同时正确检测到错误的位置并且完成纠正才能算完整的纠错。任何一部分出了差错都会影响最后的效果,尤其是检测模块误判了没有出错的位置并且进行了误纠,就会将正确的内容改成不正确的,会让文本变得更加糟糕。
为了更加合理的评估不同模型的纠错效果,一般都会分别计算检测任务跟纠正任务的准确率,包括准确率,精确率和F1,进而做一个整体的评估。同时中文文本纠错任务一般都是基于字为基本单位的。如果是以词为基本单位的,一方面是分词过程有可能引入别的错误,另一方面是文字的错误也会影响分词的效果。但是对于中文,词所蕴含的语义信息往往更加丰富,所以有时候虽然纠错任务是以字为基本单位的,但是可以将词的信息作为字的额外特征加到模型中去,进一步丰富字的信息。
2. 纠错常见思路
构建一个经典的中文纠错系统主要有两种方法:
- 第一种是多模型Pipeline把纠错任务分为多个步骤多个模型,每个模型解决具体的特定问题,然后通过Pipeline的方式串联,得到最后结果;这种方式的优点在于方便分析问题,能够针对各个问题进行重点突破,但是也存在两个明显问题:一是错误会逐级传递。
- 二是每个模型单独学习,模型之间知识无法共享。 第二种系统则采用端到端的学习、联合优化,单个模型就能完成纠错任务。
2.1 多模型Pipeline方法
第一种模型主要分为三个步骤:错误检测、候选召回、候选排序。此部分参考百度解决方案,详见附录。
2.1.1 错误检测:
错误检测的目标是识别输入句子中可能存在的问题,定位到错误词的位置。
1、 基于规则
- 拼音匹配检测: 抽取ngram级别的拼音,构建实体词与拼音映射词表,将抽取的拼音映射到实体词,比较和原词是否一致。
- 拼音编辑距离检测: 同上,但是拼音映射的实体词并不一定要完全同拼音,一定编辑距离之内即可。
- 单双向2-gram检测: 统计大规模语料中2gram的频率,检测适合句子中的2-gram小于一定频次即识别为错误。
- 困惑集:在SIGHAN7 Bake-off 2013中文拼写检查任务中,组织者提供了六种混淆集:4组语音相似的字符(音近字)和2组视觉上相似的字符(形近字)
2、 语言模型
使用LM预测下一个字(或上一个字),如果真实字不在预测的topk内,即识别为错误。LM从规则到统计模型到gpt皆可。
另外一种同思想的方法是bert的遮蔽语言模型,将当前词用mask符号代替,然后做预测,若真实字不在topk内即为错。
*目前在有embedding的纠错方案中,重新进行预训练并加入拼音和字形embedding已经成为主流方案。
3、 序列标注 or PLM
在ptm流行之前,主流做法是bilstm crf或者transformer crf预测每个字是否有错,现在也可以用bert等预训练模型。
基于BERT预训练模型的错字检测模块
步骤如下:
- 提取query特征——将query中的每个字符转换为其在BERT中文模型字典里的字典序号即为句子的特征,此外还有位置特征Position Embedding,如果句子长度小于序列最大长度,则补0直到长度满足。
- 计算query中每个字符出现的概率——在BERT模型框架的基础上添加一个Softmax层。将句子特征从BERT的输入层输入到模型里,通过中间隐藏层复杂的计算后,Softmax层的输出结果即为BERT字典中每个字出现在句子每个位置的概率(矩阵维度:序列最大长度*BERT字典大小)。
- 找出疑似错字——在剔除白名单中出现的字符的概率后,对剩下的所有字符的概率计算其平均绝对离差值,并且通过变量值与其中位数的离差除以平均绝对离差计算标准得分。对于概率小于平均绝对离差并且标准得分大于阈值的字符,我们认为是疑似错字,将其加入到疑似错误集中。
2.1.2 候选召回:
候选召回指的是,识别出具体的错误点之后,需要进行错误纠正,为了达到更好的效果以及性能,需要结合历史错误行为,以及音形等特征召回纠错候选。
主要可分为两部分工作:离线的候选挖掘,在线的候选预排序。
离线候选挖掘利用大规模多来源的错误对齐语料,通过对其模型,得到不同粒度的错误混淆矩阵。在线候选预排序主要是针对当前的错误点,对离线召回的大量纠错候选,结合语言模型以及错误混淆矩阵的特征,控制进入纠错排序阶段的候选集数量与质量。
现在主流的召回纠错候选方案都是结合规则与深度学习方法,同时控制一部分词进入候选集。
离线候选挖掘
有两种混淆词挖掘方法的方法:一是从语料中挖掘词,先采用新词挖掘算法挖掘语料中的新词,从而得到正确的种子词,再通过拼音编辑距离得到语料中与种子词拼音相近的错误词,从而通过人工标注得到高质量的高频混淆词典;二是通过ICD10等标准的疾病词典与挖掘到的新词进行匹配,可以得到新词中与疾病相关的口语词,再根据疾病口语词挖掘与疾病相关的混淆词典。
在线候选预排序
1、 基于规则
近音候选词召回、字音编辑距离召回
2、 语言模型
简单地利用LM或者ptm计算错误词可能的topk正确答案。
2.1.3 候选排序
候选排序解决的是,由于纠错的正确结果具有唯一性,如何在召回的纠错候选中将正确的结果排在第一位。
粗排序
候选召回模块得到的候选词数量庞大,逐一通过复杂模型计算替换概率将引入较大的时间损耗,因此在精排序前需要进行一定粗排序,从而通过简单的算法来过滤掉部分明显错误的答案。
一般来说这一阶段都是用小模型为主,通过构造的几个特征来对候选词进行粗打分。人工抽取的特征主要包括:语料频率比值、编辑距离、拼音jaccard距离、Ngram统计语言模型分数差值等。
精排序
这里举两个实践例子:
1、平安寿险
采用Xgboost模型对候选进行打分,同时在特征工程方面也进行了更精细化地处理。候选特征主要分为局部特征、全局特征两个方面。局部特征主要包括:分词变化、频次变化、形音变化、PMI互信息变化、Ngram语言模型分数变化以及一些其他的基础特征。
2、百度api
Deep&Wide的混合模型结构,Deep部分学习当前错误点上下文表示,Wide部分基于形音、词法、语义、用户行为等特征学习原词与候选词的多维度距离表示,另外通过GBDT&LR模型学习到更好的特征组合。
3、 LM与ptm
计算困惑度,选择困惑度最低的。
2.2 端到端
构建中文纠错系统的第二种方法是构建端到端的系统。机器翻译方法是目前最为热门的方法,简单的说,它将从原始“错误句子”到修正后“正确句子”的处理过程,看作是一个机器翻译的问题,即将错误的句子翻译成正确的句子。
此方案在ptm流行之前是纠错竞赛的标配,一般会结合之前三段式的方案组合使用。
2.3.1 有道NLPCC2018
有道团队在nlpcc2018的工作是以机器翻译方法作为基础。
- 首先利用规则方法(音错,形错)移除浅层错误。
- 计算训练句困惑度,去掉高困惑度句子。
- 利用transformer在字级别模型和词级别模型上分别进行机器翻译,得到正确的句子。
- 最后用五个模型做个集成,用语言模型来选其中的最优答案。阿里团队的方案与其基本一致,不过模型改成了lstm的seq2seq结构,并且针对最后集成的模型冲突,选择了用语言模型、计算并集、计算与原始句子编辑距离相结合的策略。
2.3.2 Confusionset-guided Pointer Network
Confusionset-guided Pointer Network是一个seq2seq模型,同时学习如何从原文本复制一个正确的字或者从混淆集中生成一个候选字。整个模型分为encoder跟decoder两部分。其中encoder用的BiLSTM用于获取原文本的高层次表征,例如图中左下角部分,decoder部分用的带注意力机制的循环神经网络,在解码的每个时刻,都能生成相应的上下文表征。生成的上下文表征有两个用途,第一个是利用这部分表征作为输入,通过矩阵乘法跟softmax来计算当前位置生成全词表中各个字的概率(右边的概率图)。第二个用途是利用这部分上下文表征加上位置信息来计算当前时刻复制原文本某个位置的字的概率或者需要生成原文本中不存在的字的概率(左边的概率图,这里其实是一个分类模型,假设原文本的长度是n,那么全部分类有n 1种,其中1至n的标签的概率代表当前时刻要复制原文本第i个位置的字的概率,第n 1的类别代表当前时刻要生成原文本不存在的字的概率。如果是1至n中某个类别的概率最大,那么当前位置的解码结果就是复制对应概率最大的原文本的某个字,如果是第n 1个类别概率最大,那么就会用到前面提及的第一个用途,计算当前位置词表中各个字的概率,取其中概率最大的字作为当前时刻解码的结果)。这里要注意的是,生成新字为了保证结果更加合理,会事先构建好一个混淆集,对于每个字,都有若干个可能错别字(形近字或者同音字等),模型会对生成的候选会限制在这个字的混淆集中,也不是在全词表中选择,所以才称为confusionset-guided。训练时会联合encoder跟decoder一同训练,以预测各个类别的交叉熵损失作为模型优化目标。
Confusionset-guided Pointer Network看起来跟之前提及的CopyNet思路很接近文本生成系列之文本编辑,同时考虑到copy原文跟生成新字两种可能性,相对于之前的seq2seq模型的改进主要是引入混淆集来控制可能的候选字符。这种设置也比较合理,中文的错别字多是在形状或者发音上有一定相似之处,通过混淆集可以进一步约束纠错的结果,防止纠错的不可控。但是由于生成的结果一定来源于混淆集,所以混淆集的质量也影响了最终纠错的效果。一个合理的混淆集的构建都需要付出比较大的代价。
2.3.3 FASPell
爱奇艺发布在EMNLP2019的基于词的中文纠错的方法,FASPell有两个特别的点,一个是用BERT为基础的DAE取代了传统的混淆集,另一点是使用置信度-相似度的解码器来过滤候选集,从而提高纠错效果。
FASPell首先利用Bert来生成句子每个字符的可能候选结果,但是Bert的预训练任务MLM中选中的token有10%是被随机替代的,这跟文本纠错的场景不符,所以需要对Bert进行一定的微调。具体过程就是对MLM任务做一定调整,调整策略如下
a)如果文本没有错误,那么沿用之前Bert的策略。
b)如果文本有错误,那么随机选择的要mask的位置的字,如果处于错误的位置,那么设置对应的标签为纠错后的字,也就是相对应的正确的字。如果不是处于错误的位置,那么设置对应的标签为原来文本中的字。
在获得文本可能的候选结果后,FASPell利用置信度-相似度的解码器来过滤这些候选结果。这里为什么需要对Bert生成的候选字进行过滤呢?因为汉语中常见的错误大部分在字形或者发音有一定相似之处,但是Bert生成的候选字并没有考虑到中文纠错的背景,所以Bert提供的候选结果很多都是纠错任务不相关的。这里每个位置的候选词的置信度由Bert计算得到,相似度这里包括字形相似度跟音素相似度,其中因素相似度考虑到在多种语言中的发音。对于每个位置的候选词,只有当置信度,字形相似度跟音素相似度满足某个条件时,才会用这个候选字符替代到原文对应字符。至于这个过滤条件,一般是某种加权组合,通常需要置信度跟相似度的加权和超过一定阈值才会进行纠错,加权相关的参数可以通过训练集学习得到,在推理时就可以直接使用。
FASPell没有单独的检测模块,利用BERT来生成每个位置的候选字,避免了以往构建混淆集的工作,同时利用后续的置信度-相似度的解码器,对候选结果进行过滤,从而进一步提高纠错效果。
2.3.4 Soft-Masked BERT
Soft-masked Bert是字节发表在ACL 2020的中文纠错方法,针对目前主流的深度学习纠错方法都是利用Bert生成各个位置的可能候选,但是Bert本身缺乏判断每个位置是否需要纠错的能力,也就是缺乏检测能力。
为此,提出了一个包含检测网络跟纠正网络的中文纠错方法。整个流程是经过检测网络,然后再经过纠错网络。其中检测网络是的双向GRU 全连接层做一个二分类任务,计算原文本每个位置是否有错误的概率。每个位置有错别字的概率为p,没有错别字的概率是1-p,如图中左边部分。纠正网络采用的是预训练模型Bert,但是在嵌入层的地方有所不同,每个位置的嵌入是由原文本中对应位置的字的词嵌入跟[MASK]的词嵌入的加权和得到的,这里的[MASK]的权重等于检测网络预测的当前位置是错别字的概率。
具体如下图所示,所以如果检测网络判断当前位置是错别字的概率较高,那么在纠正网络中该位置的词嵌入中[MASK]的权重就更高,反之,如果检测网络判断当前位置是错别字的概率很低,那么在纠正网络中该位置的词嵌入中[MASK]的权重就更低。利用Bert获得每个位置的表征后,将Bert最后一层的输出加上原文本中对应位置的词嵌入作为每个时刻最终的表征,通过全连接层 Softmax去预测每个位置的字,最终选择预测概率最大的字作为当前结果的输出。
训练过程中联合训练检测网络跟纠正网络的,模型的目标包括两部分,一个是检测网络的对数似然函数,另一个是纠正网络的对数似然函数,通过加权求和联合这两部分,使得加权和的负数尽可能小,从而同时优化这两个网络的参数。
Soft-Masked BERT相比直接采用预训练模型BERT,利用检测网络从而得到更合理的soft-masked embedding,缓解了Bert缺乏充足检测能力的问题,虽然改动不大,但是效果提升明显。
2.3.5 MLM-phonetics
MLM-phonetics是在soft-masked BERT的基础上做的优化,思路也比较接近,同样是包括检测网络跟纠正网络,主要有几点不同,
a) 纠正网络的词嵌入组成不同,Soft-Masked BERT的词嵌入由原文本中各个位置本身的词嵌入和[MASK]的词嵌入组成,而MLM-phonetics则是将相应[MASK]的词嵌入替换为相应位置对应的拼音序列的嵌入。
b) 目标函数不同,MLM-phonetics在纠正网络的目标函数中加入了检测网络的预测结果作为一个权重项。
c) 检测网络不同,MLM-phonetics的检测网络采用了预训练模型Bert。
d) BERT预训练任务不同,为了更加适配中文纠错任务的场景,MLM-phonetics的Bert的MLM任务中预测的字都是根据汉字常见的错误选取的,要不在字形上有相似之处,要不在发音上有相似之处。
2.3.7 SpellGCN
https://www.jianshu.com/p/7256a37dc4a9
除此之外,关于中文纠错任务,还有一些需要注意的点。
a)由于纠错任务可以分为检测跟纠正两个过程,所以相应的错误也可以分为这两种类型。目前基于BERT的中文纠错方法的检测错误的比例要高于纠正错误的比例,这也得益于Bert训练过程的MLM任务。
b) 中文纠错方法基本都是以字为基本单位,很大程度是因为以词为单位的话会引入分词模块的错误,但是可以用分词的结构来作为字的特征增强。
c) 目前中文纠错任务有两种类型的错误还没有很好的解决。第一种是模型需要强大推理能力才能解决,例如“他主动牵了姑娘的手,心里很高心,嘴上却故作生气。”这里虽然容易检测出“高心”是错别字,但是至于要把它纠正为“寒心”还是“高兴”需要模型有强大的推理能力才可以。第二种错误是由于缺乏常识导致的(缺乏对这个世界的认识),例如“芜湖:女子落入青戈江,众人齐救援。”需要知道相关的地理知识才能把“青戈江”纠正为“青弋江”。
3. Ref
数据集
nlpcc 2018 task 2: Grammatical Error Correction
训练数据来源于一个语言学习网站,该网站提供了一个开放平台让对应语言的母语者可以自由地对平台上语言学习者写的作文进行语法修正。训练数据共有71万条记录,每一条记录包含一个可能含有语法错误的句子和零到多句对应句子修正结果。如果是零句修正结果,则可以认为这句话是不需要修正的;如果是多句修正结果,可以认为有多种修改方法。
NLPTEA2020
中文语法错误诊断(CGED)。CGED旨在诊断四种类型的语法错误,即单词缺失(M),单词冗余(R),错误单词选择(S)和单词乱序(W)。CGED包含两个部分,包括错误检测和错误纠正。
比赛
2020 CGED
冠军 - 哈工大讯飞实验室
哈工大讯飞实验室使用了两种模型来分别应对中文纠错中的S型错误(selection,删、改)和M型错误(missing,增),并且将残差resnet集成到模型中去(就是底层输入也到高层作为输出)。S型错误的工具为roberta和ngram语言模型。步骤如下:
1、 两个工具模型的领域自适应
2、 Roberta做错误检测,错误分为单字纠错与多字纠错。
3、 单字纠错的召回为roberta的top20加上3000个最常用汉字,然后用LM和roberta算句子困惑度打分。多字纠错的召回为roberta预测的top20,然后计算多个位置处所有可能字符的组合,用LM和roberta计算困惑度。 困惑度低的为最优解。
M型错误的工具为bert-base和统计模型步骤为:
1、 错误检测:用bert预测可疑缺失位置,然后再在可疑位置前插入[MASK]符号,符号的数量也由bert预测。
2、 召回由bert对于[MASK]符号的预测topk决定,统计模型对其作为补充。
3、 排序也是经典的困惑度计算。
此工作为了给每个步骤选择最佳模型,提出来一种字集组合的方法,以选到各个模型的最优组合。
Pycorrector
https://github.com/shibing624/pycorrector
Pycorrector项目由规则纠错和深度学习纠错两部分组成。
深度学习纠错项目中提到一些前沿的方法,比如机器翻译,但作者未提供直接调用接口;
下面简单介绍一下规则纠错,主要分为经典三步曲:
第一步通过常用词词典匹配结合统计语言模型的方式进行错误检测;
第二步利用近音字,近形字和混淆字进行候选召回;
最后一步利用统计语言模型进行打分排序。
基本和上面说的三个步骤一致。在经过测试之后,发现这种方案能满足基本的音、形、错字纠错,但对更复杂的错误无法识别。
文章
- https://cloud.tencent.com/developer/article/1156792
- https://mp.weixin.qq.com/s/r0kWgPHKthPgGqTbVc3lKw 百度纠错实践
- Alibaba at IJCNLP-2017 Task 1: Embedding Grammatical Features into LSTMs for Chinese Grammatical Error Diagnosis Task
- Youdao’s Winning Solution to the NLPCC-2018 Task 2 Challenge: A Neural Machine Translation Approach to Chinese Grammatical Error Correction
- FASPell: A Fast, Adaptable, Simple, Powerful Chinese Spell Checker Based On DAE-Decoder Paradigm
- https://blog.csdn.net/chenguangchun1993/article/details/104972843
- https://cloud.tencent.com/developer/article/1156792
- https://www.jianshu.com/p/7256a37dc4a9
- NLP日志 公众号文章