最近因为相关项目需要考虑中文文本检错,然后就发现了爱奇艺发布的号称SOTA的FASPell已经开源代码,所以开始着手实现。

检错思想两步:一,掩码语言模型(MLM)产生候选字符;二,CSD过滤候选字符。

资源与数据文件

  开源代码中不包含任何处理好的数据,全部需要自己处理。训练和测试使用的SIGHAN数据没有问题。但是所需的char_meta.txt文件构建较为困难,其由字音和字形两部分特征构成。字音在unihan database可以检索到,但字形特征依照论文阐述是使用汉字的完整带结构笔画级分解,但其提供的kanji database中的结构信息有限,对于简单结构的汉字未做分解,也没有结构信息。虽然github中作者回应可以分解汉字为文件中出现过的字,递归直到无法分解,然后使用cjklib库对递归无法分解的汉字获取其笔画顺序。但这样虽然可以拆分笔画,但是缺少了笔画间的结构。我按照该方法制作了一个带部分结构的笔画级分解文件。

U+4EAC 京 jing1;ging1;KYENG;KYOU,KEI,KIN;kinh ⿳⿱㇔㇐㇑㇕㇐㇚㇒㇔
U+4EAD 亭 ting2;ting4;CENG;TEI,CHOU,CHIN;đình ⿱⿳⿱㇔㇐㇑㇕㇐㇔㇖⿱㇐㇚
U+4EAE 亮 liang4,liang2;loeng6;LYANG;RYOU;null ⿱⿳⿱㇔㇐㇑㇕㇐㇔㇖㇓㇈

模型训练

  模型训练步骤有三个:预训练掩码语言模型,微调训练掩码语言模型和训练CSD过滤器。在原作者github中讲述较为清楚,因此只简单叙述一下,不再复述细节。

  预训练掩码语言模型选择直接使用预训练好的中文BERT模型。然而,预训练模型进行随机mask的位置和实际的拼写错误位置有较大差异,因此需要使用拼写检错的训练集进行微调。微调完成之后的掩码语言模型就可以针对输入句子的每个位置计算出其置信度较高的topn候选集合判断是否存在拼写错误,再将这些候选送到CSD过滤器中过滤并确定修改的候选字。而对于候选集合的过滤方法,则是将其按照字音相似和字形相似分别评估相似度,将置信度和相似度结合进行过滤,因此,训练CSD过滤器的过程较为繁琐,耗时较长,且需要手动确定过滤线(对结果影响较大)。

  以上三个训练步骤完成之后,CSD过滤器训练会产生置信度-相似度散点图,根据散点图的分布来确定过滤曲线,然后使用一些切线来近似曲线。论文中阐述检测正确且纠正正确的样本通常分布在散点图的右上方,因此可以使用曲线对其进行过滤。训练CSD时我使用了大量的SIGHAN数据,产生的散点图并不如论文中那么完美,为了保证低误判,我仅仅考虑了检测和纠正都正确的case来划分过滤曲线。

实践的一些问题

  除了之前的char_meta.txt的问题之外,测试时还发现了对齐错误问题。

  经过排检,发现对齐问题的原因来自于句子中的数字。分词后,有些数字会被打包在一起作为一个token送到BERT中,因此产生了对齐偏差。虽然代码中考虑到了该问题,但仅仅针对两位数字的情况进行了处理,一旦3个以上数字被分为了一个token,句子必定出现对齐错误问题。因此extension()方法需要修改。

  此外,由于训练数据都是繁体字,进行微调之后模型对繁体字的偏好程度增加,这样训练出来的模型在测试时会出现把某个字更改为其繁体字形式的错误。之后我首先用zhconv将训练数据转为简体字,再进行训练测试结果没问题。但由于有些特殊的字的用法原因,如“着”和“著”,使得句子“...看着...”被改为了“...看著...”。对于这些特例,可以使用特殊过滤器进行过滤。

  我认为FASPell主要面向的还是字形相似(OCR)的错误,也的确优先检测这类错误。如果检测对象错误分布偏向于字音(语音识别、拼音输入)的话,可以仅仅开启字音相似检测,或者调整代码中的字音字形检测顺序和修改字音过滤线进行灵活适应。

相关链接

该项目的论文及github如下。

论文:https://www.aclweb.org/anthology/D19-5522.pdf

github:https://github.com/iqiyi/FASPell

文本检错——中文拼写检查工具FASPell的更多相关文章

  1. 如何写一个拼写检查器-by Peter Norvig

    本文原著:Peter Norvig  中文翻译:徐宥 上个星期, 我的两个朋友 Dean 和 Bill 分别告诉我说他们对 Google 的快速高质量的拼写检查工具感到惊奇. 比如说在搜索的时候键入 ...

  2. python 拼写检查代码(怎样写一个拼写检查器)

    原文:http://norvig.com/spell-correct.html 翻译:http://blog.youxu.info/spell-correct.html 怎样写一个拼写检查器 Pete ...

  3. Emacs中的拼写检查

    无论是在Emacs中写英文日记(diary).Org mode笔记,还是撰写程序的注释和文档,拼写检查都是一项提高工作效率.保证成果品质的必不可缺的工具.拼写检查对于常见的文字处理软件(如Word.L ...

  4. C#静态代码检查工具StyleCode

    C#静态代码检查工具StyleCode -- 初探 最近我们Advent Data Service (ADS) 在项目上需要按照代码规范进行代码的编写工作,以方便将来代码的阅读与维护. 但是人工检查起 ...

  5. 提高VS2010运行速度的技巧+关闭拼写检查

    任务管理器,CPU和内存都不高,为何?原因就是VS2010不停地读硬盘导致的; 写代码2/3的时间都耗在卡上了,太难受了; 研究发现,VS2010如果你装了VC等语言,那么它就会自动装SQL Serv ...

  6. 关闭英文拼写检查,关闭xml验证

    http://blog.sina.com.cn/s/blog_70b623e4010173ce.html eclipse里面的许多设置对于国内开发者日常使用不太适用,反而会成为干扰.既然是完全可配置的 ...

  7. Android 代码检查工具SonarQube

    http://blog.csdn.net/rain_butterfly/article/details/42170601 代码检查工具能帮我们检查一些隐藏的bug,代码检查工具中sonar是比较好的一 ...

  8. 【FLYabroad 】微软内部代码检查工具 (Microsoft Source Analysis for C#)[转]

    SourceAnalysis (StyleCop)的终极目标是让所有人都能写出优雅和一致的代码,因此这些代码具有很高的可读性. 早就听说了微软内部的静态代码检查和代码强制格式美化工具 StyleCop ...

  9. C/C++代码静态检查工具Cppcheck在VS2008开发环境中的安装配置和使用

    Cppcheck is an analysis tool for C/C++code. Unlike C/C++ compilers and many other analysis tools, it ...

随机推荐

  1. 使用Callable或DeferredResult实现springmvc的异步请求

    使用Callable实现springmvc的异步请求 如果一个请求中的某些操作耗时很长,会一直占用线程.这样的请求多了,可能造成线程池被占满,新请求无法执行的情况.这时,可以考虑使用异步请求,即主线程 ...

  2. Python Module_oslo.vmware_连接 vCenter

    目录 目录 前言 Install oslsvmware How to use the vSphere Web Service SDK 前言 oslo.vmware 是一个由 Python 实现的 vC ...

  3. 阶段3 1.Mybatis_06.使用Mybatis完成DAO层的开发_4 Mybatis中使用Dao实现类的执行过程分析-查询方法

    delete方法没有并SqlSession的delete方法,而是调用的Upadte方法. 在测试类这里加断点. 实际的方法体内也加断点 运行测试方法,选择debug的方式 走到断点这里.会看到fac ...

  4. django的url的name参数的意义及view中reverse

    Templates的链接地址都是根据urlpatterns定义的地址,拼凑成地址字符串,很难看,而且Templates里拼凑成的地址,随着页面的增加而不断增加,一旦在urlpatterns里的某个地址 ...

  5. Debian系统中当安装deb软件时出现:deb cdrom:[Debian GNU/Linux 9.3.0 _Stretch_ - Official amd64 DVD Binary-1 20171209-12:11]/ stretch contrib main

    vi /etc/apt/sources.list // 注释掉下面这句话# deb cdrom:[Debian GNU/Linux 9.3.0 _Stretch_ - Official amd64 D ...

  6. wpf 非窗体类中 异步调用窗体与控件

    App.Current.Dispatcher.Invoke((Action)(() => { MessageBoxWindow mwb = ); mwb.ShowDialog(); return ...

  7. Java程序员面试题集(151-180)

    Java面试题集(151-180) 摘要:这部分包含了Spring.Spring MVC以及Spring和其他框架整合以及测试相关的内容,除此之外还包含了大型网站技术架构相关面试内容. 151. Sp ...

  8. 【Fiddler】开启手机的http或https抓包

    fiddler安装 下载fiddler最新版: 默认安装: 打开fiddler工具,默认界面: 选择上方,Tools-→options General界面 HTTPS界面 CONNECTIONS,po ...

  9. Java第四周总结+实验报告

    实验二 Java简单类与对象 实验目的 掌握类的定义,熟悉属性.构造函数.方法的作用,掌握用类作为类型声明变量和方法返回值: 理解类和对象的区别,掌握构造函数的使用,熟悉通过对象名引用实例的方法和属性 ...

  10. SQL如何通过当前日期获取上周一日期【转】

    --当前时间 select getdate() --当前时间周的起始日期(以周一为例) ,) --上周起始: ,,)) --上上周起始: ,,)) --上上上周起始:s elect ,,))