欢迎关注「NLP 论文领读」专栏!快乐研究,当然从研读 paper 开始。关注公众号「澜舟科技」了解更多!
本期分享者:甘子发
澜舟科技算法实习生 ,郑州大学自然语言处理实验室(ZZUNLP)二年级硕士生。目前正在进行文本纠错方向的研究 E-mail: zfganlp@foxmail.com
写在前面
自然语言文本中经常会出现一些拼写错误(typo),在中文文本里即所谓的错别字,中文拼写纠错(Chinese Spelling Correction,CSC) 可以对中文文本中的 typo 进行检测和纠正。拼写纠错在诸多 NLP 任务和应用中都有重要作用,如 OCR、语音识别和搜索引擎等。在 NLP 任务和日常工作生活场景中,中文文本中的 typo 主要是拼音和字形相似导致的,示例如表 1 所示。
表 1
一般 CSC 系统的输入和输出序列长度相同,所以现在 CSC 系统主要采用基于 BERT 的非自回归生成模型,这些模型依据输入序列中的所有字符来平行生成每个位置的字符,而随着 BERT 等预训练模型的成功,CSC 模型的性能也有了极大的提升。
虽然 BERT 模型很强大,但其在解决 CSC 任务时也会遇到一些问题。
首先,基于 BERT 的 CSC 模型根据 typo 本身及其上下文对该处 typo 进行检测和纠正,但当一个句子中有多处拼写错误(multi-typo)时,则句子中每个字符的上下文都至少包含一处 typo,这导致其信息中含有噪声,从而影响模型的效果。论文统计了中文拼写纠错任务 SIGHAN13、14、15 的测试集中的 multi-typo 数据,如表 2 所示,并且把这些数据抽出做成测试集,测试模型对 multi-typo 文本的纠错能力,结果如表 3 所示(character-level),结果证实了上述结论。
其次,BERT 是掩码语言模型,其从大规模语料中学习怎样根据上下文恢复被遮掩的 token,但对于一个被遮掩的位置可能有多个有效的字符,这时候 BERT 模型则会倾向于恢复成最常见的那一个,而在 CSC 任务中,则表现为模型可能会把一个有效的表述改成另外一种更常见的表述,比如将“这并非是说……”改成“这并不是说……”。
表 2
表 3
针对上述的两个问题,来自腾讯 AI 平台部门和北京大学的研究人员提出了一种名为 CRASpell 的解决方法,让我们一起来看看吧。
论文标题
CRASpell: A Contextual Typo Robust Approach to Improve Chinese Spelling Correction
论文作者
Shulin Liu, Shengkang Song, Tianchi Yue, Tao Yang, Huihui Cai, Tinghao Yu, Shengli Sun
作者单位
Tencent AI Platform Department, China
Peking University, China
论文链接
https://aclanthology.org/2022.findings-acl.237/
项目代码
https://github.com/liushulinle/CRASpell
CRASpell 介绍
该论文将 multi-typo 降低模型性能的问题称作 Contextual Typo Disturbance,将模型对文本不必要的纠正称为 Overcorrection,并针对这两个问题提出了 CRASpell 模型,其结构如图 1 所示:
图 1
由图 1 我们可以看到,CRASpell 主要分为两部分,左边为 Correction Module,右边为 Noise Modeling Module。
1. Correction Module
Correction Module 中,Transformer Encoder 加 Generative Block 就是一个基本的 CSC 模型,Generative Block 计算并输出一个 generative distribution,其过程可以描述为:
P g = softmax ( W g h i + b g ) \mathbf{P}_{\mathrm{g}}=\operatorname{softmax}\left(\mathbf{W}_{\mathbf{g}} \mathbf{h}_{\mathrm{i}}+\mathbf{b}_{\mathrm{g}}\right) Pg=softmax(Wghi+bg) (1)
论文中使用 copy mechanism [1-2] 来解决 Overcorrection 的问题,其对于输入序列中的每一个 token,都有一个 one-shot 向量的 copy distribution,其形式可以描述为:
p c [ k ] = { 0 k ≠ i d x ( x i ) 1 k = i d x ( x i ) \mathbf{p}_{\mathbf{c}}[k]=\left\{\begin{array}{ll} 0 & k \neq i d x\left(x_{i}\right) \\ 1 & k=i d x\left(x_{i}\right) \end{array}\right. pc[k]={ 01k=idx(xi)k=i</