文本纠错–CRASpell模型

CRASpell: A Contextual Typo Robust Approach to Improve Chinese Spelling Correction 这篇论文是发表于22年ACL,在Chinese spelling correction (CSC)任务上是SOTA。基于bert预训练模型的CSC的模型有两个极限: (1) 在多错误文本上模型效果不好,通常在拼写错误的文本,拼写错误字符至少出现1次,这会带来噪声,这种噪声文本导致多错字文本的性能下降。 (2) 由于bert掩码任务,这些模型过度校正偏向于高频词的有用表达词。 CRASpell模型每一个训练样本构建一个有噪声的样本,correct 模型基于原始训练数据和噪声样本输出更相似的输出,为了解决过度校正问题,结合了复制机制来使得我们的模型在错误校正和输入字符根据给定上下文都有效时选择输入字符。 文章地址为:文章 代码地址为:code

模型

任务描述

中文拼写纠错的目的是检测和纠正文本中的拼写错误。通常表述为 文本纠错EMNLP 文本纠错 bert_特征向量是长度为文本纠错EMNLP 文本纠错 bert_文本纠错EMNLP_02的包含拼写错误的文本,文本纠错EMNLP 文本纠错 bert_文本纠错EMNLP_03是长度为文本纠错EMNLP 文本纠错 bert_文本纠错EMNLP_02的正确文本,模型输入文本纠错EMNLP 文本纠错 bert_文本纠错EMNLP_05生成正确的文本文本纠错EMNLP 文本纠错 bert_transformer_06.

CRASpell 模型

文本纠错EMNLP 文本纠错 bert_深度学习_07

左边是Correction模型,右边是Noise模型,下面详细介绍模型。

(1) Correction Module

给定输入文本文本纠错EMNLP 文本纠错 bert_特征向量得到embedding 向量文本纠错EMNLP 文本纠错 bert_transformer_09,其中每一个字符文本纠错EMNLP 文本纠错 bert_自然语言处理_10对应的embedding向量记为文本纠错EMNLP 文本纠错 bert_文本纠错EMNLP_11,将文本纠错EMNLP 文本纠错 bert_自然语言处理_12输入到Transformer Encoder中得到hidden state matrix 文本纠错EMNLP 文本纠错 bert_特征向量_13,其中文本纠错EMNLP 文本纠错 bert_特征向量_14是字符文本纠错EMNLP 文本纠错 bert_自然语言处理_10经过Transformer Encoder得到特征。

(2) Generative Distribution

文本纠错EMNLP 文本纠错 bert_特征向量经过Transformer Encoder得到特征向量文本纠错EMNLP 文本纠错 bert_特征向量_13,经过一个前向线性层和一个softmax层得到每个一字符token的生成概率,公式如下:

文本纠错EMNLP 文本纠错 bert_文本纠错EMNLP_18 其中文本纠错EMNLP 文本纠错 bert_文本纠错EMNLP_19文本纠错EMNLP 文本纠错 bert_transformer_20文本纠错EMNLP 文本纠错 bert_文本纠错EMNLP_21是预训练模型词表的大小。

(3) Copy Distribution

文本纠错EMNLP 文本纠错 bert_自然语言处理_10的copy distribution 文本纠错EMNLP 文本纠错 bert_文本纠错EMNLP_23文本纠错EMNLP 文本纠错 bert_自然语言处理_10在字典中的文本纠错EMNLP 文本纠错 bert_特征向量_25的one-hot 表示,具体表示如下:

文本纠错EMNLP 文本纠错 bert_深度学习_26

(4) Copy Probability

Copy Probability是模型图中的Copy Block中的输出$\omega \in\Large\boldsymbol{R}$,即transformers encoder 得到的隐藏层特征向量$h_{i}$经过两个前向线性层和一个layer normalization得到$\omega$,具体公式如下:

文本纠错EMNLP 文本纠错 bert_transformer_27 其中文本纠错EMNLP 文本纠错 bert_自然语言处理_28文本纠错EMNLP 文本纠错 bert_transformer_29文本纠错EMNLP 文本纠错 bert_transformer_30文本纠错EMNLP 文本纠错 bert_transformer_31是layer normalization,文本纠错EMNLP 文本纠错 bert_特征向量_32是激活函数,在代码使用的激活函数为glue.详细见代码

Copy Block输出概率文本纠错EMNLP 文本纠错 bert_文本纠错EMNLP_33结合了生成Generative Distribution 文本纠错EMNLP 文本纠错 bert_transformer_34和Copy Distribution 文本纠错EMNLP 文本纠错 bert_自然语言处理_35

文本纠错EMNLP 文本纠错 bert_深度学习_36

与之前CSC模型的不同之处在于,CRASpell模型在模型最终生成输出考虑了Copy Probability 文本纠错EMNLP 文本纠错 bert_自然语言处理_35,使得模型在输入字符有效但不是最适合 BERT 时有更多机会选择输入字符,避免过度矫正。

(5) Noise Modeling Module

Noise Modeling Module通过校正模型为原始上下文和噪声上下文产生相似的分布来解决上下文错字干扰问题。 如上面模型图的右侧,Noise Modeling Module 大致分为下面几个过程:

a. 根据输入样本文本纠错EMNLP 文本纠错 bert_文本纠错EMNLP_05生成噪声上下文文本纠错EMNLP 文本纠错 bert_深度学习_39

b. 将噪声上下文文本纠错EMNLP 文本纠错 bert_深度学习_39作为输入得到Transformer Encoder得到隐藏特征向量文本纠错EMNLP 文本纠错 bert_文本纠错EMNLP_41

c. 根据隐藏特征向量文本纠错EMNLP 文本纠错 bert_文本纠错EMNLP_41生成生成分布文本纠错EMNLP 文本纠错 bert_transformer_43

d. 生成分布与校正模型生成的分布相似。生成分布与校正模型生成的分布相似这个是通过minimizing the bidirectional Kullback-

Leibler divergence体现,具体公式如下:

文本纠错EMNLP 文本纠错 bert_深度学习_44

备注:Noise Modeling Module仅在训练过程中出现,模型推理只使用校正网络

Noisy Block

下面介绍数据添加噪声数据。通过替换原始训练样本的字符来生成噪声样本。在替换字符的过程中只替换拼写错误字符上下文附近文本纠错EMNLP 文本纠错 bert_文本纠错EMNLP_45个词,如果训练样本没有拼写错误,该样本不进行替换生成噪声样本。如下图所示:

文本纠错EMNLP 文本纠错 bert_特征向量_46

文本纠错EMNLP 文本纠错 bert_文本纠错EMNLP_45选择实验结果

文本纠错EMNLP 文本纠错 bert_自然语言处理_48

我们根据公开可用的混淆集将每个选择的位置替换为相似的字符。 具体来说,我们选取位置处的词进行替换

(i) 70% 的替换随机选择语音相似字符

(ii) 15% 的替换随机选择字形相似字符

(iii) 15% 的替换从词汇表中的随机选择。

作者提供了相同拼音汉字,字形相似以及拼音相近字这三个文件,按照上述方式从这三个文件中数据进行替换。代码如下:

def do_mask(self, input_sample, target_indice):
        masked_sample = input_sample
        method = self.get_mask_method()
        for pos in target_indice:
            if method == 'pinyin':
                new_c = self.same_py_confusion.get_confusion_item_by_ids(input_sample[pos])
                if new_c is not None:
                    masked_sample[pos] = new_c
            elif method == 'jinyin':
                new_c = self.simi_py_confusion.get_confusion_item_by_ids(input_sample[pos])
                if new_c is not None:
                    masked_sample[pos] = new_c
            elif method == 'stroke':
                new_c = self.sk_confusion.get_confusion_item_by_ids(input_sample[pos]) 
                if new_c is not None:
                    masked_sample[pos] = new_c
            elif method == 'random':
                new_c = self.all_token_ids[random.randint(0, self.n_all_token_ids)]
                if new_c is not None:
                    masked_sample[pos] = new_c
        return masked_sample

这里替换后是得到的tokenizer后的结果,并不是得到一个汉字字符。

Loss

给定训练样本文本纠错EMNLP 文本纠错 bert_transformer_49文本纠错EMNLP 文本纠错 bert_文本纠错EMNLP_05是输入错误样本,文本纠错EMNLP 文本纠错 bert_transformer_06是校正正确样本,每一个校正正确样本文本纠错EMNLP 文本纠错 bert_自然语言处理_52的loss为

文本纠错EMNLP 文本纠错 bert_深度学习_53

其中文本纠错EMNLP 文本纠错 bert_文本纠错EMNLP_33

文本纠错EMNLP 文本纠错 bert_深度学习_36

详细见上面介绍。

模型loss为文本纠错EMNLP 文本纠错 bert_特征向量_56

文本纠错EMNLP 文本纠错 bert_自然语言处理_57

其中文本纠错EMNLP 文本纠错 bert_transformer_58

文本纠错EMNLP 文本纠错 bert_transformer_59

其中文本纠错EMNLP 文本纠错 bert_transformer_60文本纠错EMNLP 文本纠错 bert_文本纠错EMNLP_61文本纠错EMNLP 文本纠错 bert_深度学习_62的权衡因子。构建的噪声样本本身不会参与训练过程,而只会作为上下文参与。这个策略旨在确保构造的噪声数据不会改变训练语料中正负样本的比例。

实验结果

CRASpell模型实验结果

论文中使用的是拼写错误预训练模型得到的实验结果

文本纠错EMNLP 文本纠错 bert_自然语言处理_63

笔者最近加载torch版的chinese-roberta-wwm-ext模型得到的结果如下:

sighan15 test data result
 token num: gold_n:694, pred_n:783, right_n:586
 token check: p=0.748, r=0.844, f=0.793
 token correction-1: p=0.954, r=0.805, f=0.873
 token correction-2: p=0.714, r=0.805, f=0.757
 precision:0.7484026201754532, recall:0.8443791867735061, f1_score:0.7934992640496943

绝对准确率为0.7372。