基于Transformer网络的中文单字词检错方法研究
2021-03-18曹存根
曹 阳,曹存根,王 石
(1. 中国科学院 计算技术研究所 智能信息处理重点实验室,北京100190;2. 中国科学院大学,北京 10049)
0 引言
在日常使用计算机或手机等终端设备输入汉字时,人们在输入时的心理状态、输入习惯、误触按键或者文化水平等因素时常会造成文本中出现错别字。例如,在语句“黄金首饰带久了会发白”以及语句“我再这里等你好长时间了”中,“带”和“再”都是比较容易用错的单字词(称为中文单字词错误)。在此背景下,研究文本错误自动识别对于规范中文汉字的使用和提升用户感知体验具有重要意义。
针对多字词错别字情形,张仰森等[1]将多字词错别字分类为“非多字词错误”和“真多字词错误”。前者“非多字词错误”指由两个或两个以上的汉字构成的词中至少出现一个别字替换错误、缺字错误或者多字错误;该词也不是词典中的词。例如,“端庄”错写成“端壮”,而“端壮”在词典中无法找到。“真多字词错误”指一个多字词错成词典中的另一个多字词。根据错别字产生的替换、缺字以及多字这三种原因,刘亮亮等[2]将非多字词错误分类为“别字型非多字词错误”“缺字型非多字词错误”以及“多字型非多字词错误”。
虽然学术界对多字词检错方法研究较多,但据我们所知,对单字词检错方法的研究较少,本文重点研究中文单字词检错方法。
相比于中文多字词错误自动识别,中文单字词错误识别尤为困难,其原因主要体现在以下几个方面:
(1)单字词往往是多义词这些多义的单字词可以和不同的词组合,无疑增加了单字词错误识别难度。
(2)单字词使用频率高单字词大都是一些常用高频词,例如,“的”“在”“这”等,它们的频繁使用也给单字词错误识别带来困难。
(3)上下文语境复杂单字词的多义性和高频性使得它在句中的位置具有随机性,出现的上下文语境十分复杂,这又增加了单字词错误的识别难度。
(4)单字词错误训练样本收集困难通过对训练语料进行抽样统计,我们发现,单字词错误在抽样语料中普遍存在,但因为没有明显的文本特征和上下文特征,所以很难自动搜集。本文所使用的方法需要大量单字词错误训练样本作为训练集,由于人工收集耗时耗力,因此需要一种能够自动产生单字词错误训练样本的方法。
针对上述问题,本文提出了一种利用汉字混淆集构造单字词错误训练语料、基于Transformer网络的中文单字词错误识别方法。Transformer网络方法解决上述四个问题具有以下优势:
(1) Transformer网络在对字(或词)进行编码的过程中能够考虑字(或词)的位置信息。
(2) Transformer网络避免了循环神经网络(RNN)中存在的长期依赖的问题。
(3) Transformer网络可以通过Self-attention捕获到句子中的每个字(或词)与句子上下文内部之间的关系。
(4) Transformer网络可以并行计算,提高训练速度[3]。
1 相关研究
国外对文本自动校对研究可以追溯到20世纪60年代,当时研究文本自动校对的动机是为了解决数据录入过程中出现的数据名称拼写错误[4]。斯坦福大学的Ralph Gorin[4]开发出第一款英语拼写检查程序SPELL。Damerau等[5]发现句子中的英文拼写错误出现的原因主要是由于 “真词”中的字母被替换、缺失、增加或对换所造成的。关于英文拼写错误识别方法主要分成以下两类: n-gram分析方法[6],这类方法是统计连续n个元素在语料中出现频率来识别拼写错误;字典查询方法[6],这类方法假设字典中所包含的词都是正确的,通过判断当前词是否在字典中来识别英文拼写错误。
国内对中文错别字校对方法的研究可以分成以下四类: ①基于规则的方法。易蓉湘等[7]通过对文本中大量错误现象的观察总结出规则进行文本错误校对。②基于统计的方法。 Chang[8]提出根据汉字中的形似、音似、意似以及按键编码相似来构造混淆集,然后使用混淆集对句子中的字做相应替换操作,并利用语言模型对替换前后句子打分来实现中文自动校对。Xie等[9]采用二元文法和三元文法相结合进行文本错别字识别,并且利用平滑技术来解决数据稀疏的问题。Han等[10]利用最大熵方法进行错别字的识别。③基于上下文局部语言特征方法。Zhang等[11]提出基于语言特征并利用Window方法进行特征学习以实现文本的自动校对。④混合方法。于勐等[12]以模式匹配的方法和三元文法分析的方法为基础,结合语法属性标注和分析进行中文校对。Ren等[13]提出基于统计和规则相结合的方法进行错别字校对。Liu等[14]提出利用统计机器翻译和语言模型相结合的框架来产生错别字更正的候选项集合,同时利用支持向量机对产生的错别字更正候选项进行排序来实现中文的自动校对。刘亮亮等[2]针对传统“非多字词错误”自动校对方法的不足,提出利用模糊分词的“非多字词错误”自动查错和自动校对方法。
2 本文的模型和方法
2.1 基于汉字混淆集的训练语料生成方法
本文利用施恒利等[15]和Liu等[16]研制的汉字混淆集来构造Transformer网络的训练语料。开始时,汉字混淆集是根据汉字之间的音似和形似等特点以手动方式构建,随后Liu等[16]使用大量语料进行了自动扩展。
为了描述单字词错误训练语料的生成算法,下面先引入两个定义。
定义1(汉字混淆集)汉字混淆集记为集合Cset={cs1,cs2,…,csi,…,csm},其中混淆集中csi={cpairi1,cpairi2,…,cpairij,…,cpairik}。csi中元素cpairij=(errChari,corrCharij),cpairij中第一个元素errChari称为疑似错别字,第二个元素corrCharij为errChari对应的可能正确字。
例如,csi={(带,戴),(带,代),(带,待),…}就是“带”的混淆集。它的含义是: 当“带”出现在语句S中,并且有证据怀疑“带”是错别字时,“带”对应的正确字可能是“戴”“代”“待”等。因此,当计算机发现“黄金首饰带久了会发白”中的“带”可能是错别字时,它会尝试对“带”在混淆集中对应的可能正确字进行必要的验证。这不仅提高了错别字识别精度,而且还提高了计算的效率。
定义2(单字词错误)S是由n个单字词和多字词组成的句子,假设句子S中没有错别字,记为S=c1…ci…cn,其中,n称为S的长度,记为|S|,S中第i项ci的长度记为|ci|。如果|ci|=1,并且ci在汉字混淆集Cset中的疑似错别字记为集合Error={errChar1,…,errCharj,…,errChark},其中,将errCharj替换句子S中的ci形成新的句子S′,记为S′=c1…errCharj…cn。 那么称errCharj是S′中的单字词错误。
例如,S=“黄金 首饰戴久了 为什么 会 发白”,单字词“戴”在汉字混淆集Cset中疑似错别字集合为Error={带,黛},将“带”替换S中的“戴”形成新的句子S′=“黄金 首饰带久了 为什么 会 发白”,其中,称“带”为句子S′的单字词错误。
下文我们将在汉字混淆集的基础上构建Transformer网络的单字词错误训练语料。
Transformer网络的训练需要大量的含有单字词错误的数据。在日常生活中,相对于网络上出现的海量数据,单字词错误出现的数量有限,不足以达到网络训练的目的。如果以人工方式标记单字词错误将十分耗时耗力,并且训练语料中单字词错误分布是否合理将直接影响到单字词错误识别效果。针对这个问题,本文设计出一种利用原始语料和汉字混淆集来自动构建单字词错误训练语料的方法。
在生成单字词错误训练语料前,我们从表1中的网址下载了大量的网页。每个网页去除标签形成纯文本。采用ICTCLAS分词器(1)http://ictclas.nlpir.org/对文本进行分词。为了便于后续处理,将分词后的文本按照句号、分号、逗号、感叹号以及问号分割成一个一个的句子。最后形成语料库,记为segCorpus={doc1,…,doci,…,docn}。
算法1给出了单字词错误训练语料生成过程。在第8行,定义了一个标签数组Tag,并且初始化为“C”,表示S′中的每个字都是正确的。在第12行中,当确定segj为单字词,且CSet存在segj对应的混淆字errChari,那么在第14行用errChari替换S′中的segIndex位置的字,并且在第17行用“E”标记出在S′中segIndex位置上的errChari是单字词错误。
算法1 单字词错误训练语料生成算法输入: (1) 分词后文本语料库: segCorpus={doc1,…,doci,…,docn}(2) 中文汉字混淆集:Cset={cs1,…,csk,…,csm}输出: (1)单字词错误训练语料Corpus1. Corpus={}2. 对segCorpus中的每篇doci:3. {4. 对doci中每句S'=seg1…segj…segh:5. {6. segLen=seg1+…segj…+segh;7. segIndex=0;8. 定义长度为senLen的标签数组Tag[0… senLen],初始化数组中每个值为“C”;9. 对S'中每项segj: 10. {11. segIndex=segIndex+|segj|;12. 如果segj=1,且Cset中存在混淆对 (errChari,segj),则:13. {14. S'segIndex =errChari;15. typoSent=S';16. Sent=convertToChar(typoSent);17. Tag[segIndex]=“E”;18. Corpus=Corpus∪Sent,Tag ;19. S'segIndex =segj;20. Tag[segIndex]=“C”;21. }22. }23. }24. }25. Return Corpus;
以S′=“黄金/首饰/戴/久/了/会/发白”为例,S对应标签数组初始化为Tag[0]=“C”,…,Tag[9]=“C”。由于(带,戴)是Cset的一个汉字混淆对,因此,第15行产生了一个含错别字的句子typoSent=“黄金/首饰/带/久/了/会/发白”。此时,第16行产生单字词错误的训练语句Sent=“黄 金 首 饰带久 了 会 发 白”。对应的标签数组修改为Tag[0]=“C” ,…,Tag[4]=“E” ,…,Tag[9]=“C”,其中,Tag[4]=“E”表示Sent中的“带”是单字词错误。
需要注意的是,Corpus中的每条语句仅含一个单字词错误。
2.2 基于Transformer的单字词检错模型
近几年来,具有注意力机制的神经网络在自然语言应用领域取得了突破性进展[17]。本质原因是注意力机制对自然语言文本中的重要信息赋予更高的权重,因此具有注意力机制的神经网络更能学习到文本的重要信息。
与主流的端到端神经网络架构中利用RNN作为自然语言文本的编码器和解码器不同,Vaswani等[3]利用Transformer网络解决RNN处理数据不具备并行运行的缺陷。其中,编码器和解码器分别由多个块(block)串联组成,编码器中的每个block由多头注意力机制层(multi-head attention)和前向反馈神经网络层两部分组成,这两部分都使用了残差连接和归一化(normalization)操作。解码器比编码器多了编码—解码注意机制(encoder-decoder attention),其中多头注意力机制是通过多个自注意力机制(self-attention)堆叠而成。
为了得到句子中的每个字和句子中所有字之间的语义关系,Transformer网络使用了自注意力机制来描述(图1)。通过自注意力机制可以训练出句子中每个字与句子中所有字上下文之间的关系。自注意力机制主要原理如下: 假设自注意力机制中输入单字词错误例句S的字嵌入矩阵为S=[c1,c2,…,ci,…cn],(S∈n×dim,n表示句子S中所含有字的个数,dim表示字向量ci的维度),通过对字嵌入矩阵S与权重矩阵WQ,WK,WV(WQ∈dim×dQ,WK∈dim×dQ,WV∈dim×dV)相乘得到对应Q(Query),K(Key),V(Value)(Q∈n×dQ,K∈n×dQ,V∈n×dV)。接着Transformer采用注意力机制中常用的缩放点积(scaled dot-product)函数,首先对Q和KT内积得到相应的注意力权重矩阵,该矩阵中的值表示句子中字与字之间的相关性,再除以等于K的维度),然后对得到的结果进行mask和SoftMax操作,最后通过和V加权求和得到自注意力特征编码如式(1)所示。
图1 Scaled Dot-Product Attention机制[3]
如图2所示,多头注意力机制能够在不同的表示子空间中获取信息,对Q(query),K(key),V(value)分别做线性变换后再进行scaled dot-product attention操作,接着对上述操作重复做h次后,再将scaled dot-product attention的结果进行拼接和线性变换,最终得到多头注意力机制的输出,多头注意力机制如式(2)、式(3)所示。
图2 Multi-Head Attention机制[3]
(2)
MH(Q,K,V)=Concat(head1,…,headh)Wo
(3)
为了便于描述单字词错误检错网络训练过程,我们假设单字词错误训练网络的批大小(batch size)为b,编码器和解码器的层数为1。整个单字词错误检错网络的训练流程如下:
第一步首先,将b条单字词错误句子对应的索引编码I通过字向量嵌入层得到字嵌入张量S。 其次,通过位置编码层得到位置编码张量P,将位置编码张量P和字嵌入张量S相加,得到字嵌入张量S′;
第二步将字嵌入张量S′输入到编码器部分的multi-head attention层后使用Add&Norm操作。其中,Add操作是将字嵌入张量S′和multi-head attention层输出张量相加,Norm操作是对Add的结果进行归一化(layer normalization),归一化操作有助于模型训练稳定,最后输出结果为M;
第三步将M通过前向反馈神经网络后使用Add&Norm操作,最后得到编码器的编码结果;
第四步将单字词错误标签索引序列通过字嵌入层和位置编码层得到字嵌入张量T′;
第五步将T′输入到masked multi-head attention 层后使用Add&Norm操作,最后输出结果为Query;
第六步将解码器中的Query与Encoder编码结果的Key和Value作为 multi-head attention层的输入后使用 Add&Norm操作,最后输出结果为O;
第七步将O输入到解码器中的前向反馈神经网络后使用Add&Norm操作,对解码器的输出结果使用Linear和Softmax操作得到句子中单字词是否是错别字的概率分布,计算损失函数并利用反向传播更新网络中的参数。
2.3 基于滑动窗口的单字词错误测试方法
本文实验的目的是为了识别出文本中的单字词错误。一方面,Transformer网络在做单字词错误测试中泛化能力较弱,测试结果往往误纠率较高。另一方面,Transformer网络模型中的参数较多,神经网络测试时的结果往往具有不可解释性。我们只能依赖个人经验对网络参数进行调参,但是如果只是不断调节网络参数来适应测试句子中的单字词错误的结果,又会极大地浪费时间。例如,在原始的句子中“加字”或“减字”都会影响单字词错误的识别。因此,本文提出采用多窗口的方法进行测试,即输入时对待测语句加入固定大小的移动窗口,通过对待测语句移动窗口生成多条测试语句进行测试,最后综合考虑得到单字词错误识别的预测结果。算法2给出了具体的单字词错误测试算法。
算法2: 单字词错误测试算法输入: (1) 待测句子sent(2) 移动窗口大小为winsize(3) 每次移动步长为stride输出: (1)识别出的单字词错误Error1. testSet={};//testSet为sent的测试集合2. predArr=[];//predArr为sent中所有可能的单字词错误;3. len=sent.length;//计算待测句子的长度4. 如果len小于或等于winsize,则将sent加入到测试集合testSet中;5. 如果len大于winsize,则使用winsize大小的窗口对sent自左往右以步长大小为stride进行移动,并将每次窗口移动中的字符串加入到testSet中;6. For testi in testSet do:7. Errori=predict(testi)//利用训练出的单字词检错网络模型预测testi中单字词错误Errori;8. predArr=predArr.add(Errori)//将单字词错误Errori加入到predArr;9. Error=majority(predArr) //将predArr中出现次数最多的单字词作为sent中的单字词错误;10. Return Error;
例如,待测句子S=“由于印度越南等过限制大米出口”,移动窗口winsize=10。在第5行,由移动窗口在S中移动生成testSet,testSet={“由于印度越南等过限制”,“于印度越南等过限制大”,“印度越南等过限制大米”, “度越南等过限制大米出”,“越南等过限制大米出口”}。在第8行,sent中所有可能的单字词错误predArr=[“过”,“过”,“过”,“出”,“过”]。在第9行,将predArr中出现次数最多单字词“过”作为sent中的单字词错误。
3 实验与分析
3.1 训练数据与测试指标
在训练语料生成中,本文还考虑了以下两个方面。
(1)汉字混淆集的出现率汉字混淆集中的汉字errChari尽可能多地出现在训练语料中,并且分词后以单字词的形式出现在训练语料中。
(2)领域丰富性、题材多样性单字词错误训练语料来自多个不同的领域,使得训练出来的Transformer网络模型能适用较多领域。
为此,本文选择了“新闻类”“科技类”“财经类”“娱乐类”网站的网页作为训练语料来源,如表1 所示。
我们从表1的网址上爬取了大量的语料,经过去除HTML标签、分句和分词等预处理后,产生语料库segCorpus,大约有405MB,如表2所示。
表1 训练语料类别与来源
表2 segCorpus含有的语料类别和大小
通过算法1自动生成单字词错误语料,我们获得了单字词错误语料库,大小为7.8GB。
对Corpus随机抽取出7.2MB作为测试集,剩余语料作为训练集。我们课题组在真实语料中收集了单字词错误例句共有220条,也作为本实验的测试语料。如表3所示,需要注意的是,这两个测试集中,每条语句仅含一个单字词错误。
表3 单字词错误测试集
本文采用召回率、精确率以及F1评价Transformer网络的识别单字词错误性能,如式(4)~式(6)所示。
3.2 实验过程与结果分析
为了验证第2节所述的单字词错误识别方法的可行性,我们进行了实验。实验过程中所使用服务器的型号为Dell PowerEdge R730,操作系统为Ubuntu, RAM的内存大小为64GB,显卡类型为NVIDIA GTX1080ti,运行代码主要基于Tensorflow软件,分词器采用ICTCLAS。
本文训练神经网络隐藏单元设置成320,dropout设置成0.05,学习率设置成0.001,优化算法使用Adam,字向量的维度设置成320。分别对自动生成的测试集句和220条人工收集的真实例句进行测试,不同窗口的实验结果见表4~表6。
表4 自动生成的测试集的效果
表5 人工收集的测试集的效果
通过对表4和表5实验结果分析发现,并不是移动窗口越大,单字词检错效果越好,当窗口数是15时,在两个测试集上识别精确率、召回率以及F1都分别达到最优。
表6显示,基于Transformer网络的单字词错误识别方法在准确率和召回率上要比传统的BiLSTM和3-GRAM的单字词检错方法高。Transformer带窗口测试相比不带窗口测试准确率和召回率都有增加,说明窗口测试对提高单字词错误识别的准确率起到了一定作用。
表6 不同模型和窗口测试结果
表7和表8分别是测出错别字和未测出错别字的部分案例。对人工收集的测试集中未测出单字词错误的语句进行分析,发现有以下特点:
(1) 句中含有字数较多的人名、地名、日期。 这类约占35%;
(2) 单字词错误位于测试句的句首或者句尾。这类约占30%;
(3) 测试句子中包含阿拉伯数字、字母、特殊符号。这类约占22%;
(4) 分词结果不正确导致单字词错误无法判断。例如,有时分词工具会把多字词切碎,这样会给我们构造的单字词错误训练语料造成干扰。这类约占7%;
(5) 待测句子过长,识别往往出错。这类约占6%。
表7 测出错别字部分案例
表8 未测出错别字部分案例
4 总结
针对单字词检错困难的问题,本文基于Transformer网络,提出一种利用原始语料和汉字混淆集[15-16]来自动构建单字词检错训练语料,并使用移动窗口以提高单字词检错准确性的方法。从实验效果来看,基于Transformer网络方法的F1值要比传统的3-GRAM和BiLSTM方法高出12至16个百分点。在同样的Transformer网络模型测试时,加窗口又比不加窗口的方法在精确率和召回率方面都得到较大提升。通过对实验结果中的错误分析,发现在待测句中单字词错误能否被正确识别与很多因素有关。例如,待测句中含有字数较多的人名、地名、日期,单字词错误在句中的位置,标点符号、句子长短、分词是否准确等。这反映出Transformer 网络进行单字词检错还有一定的局限性。对一些句首或句尾的错别字,应用移动窗口的方法测试,测试准确性较差,主要原因是一方面位于首尾的单字词错误在语句中缺少上下文语境,另一方面是移动窗口产生位于句首或句尾单字词错误的测试语句较少。下一步工作,我们将探索提高位于句首或者句尾的单字词错误识别准确性的方法。