NLP 中文拼写检测开源-01-基于贝叶斯公式的拼写检查器 CSC

拼写纠正系列

NLP 中文拼写检测实现思路

NLP 中文拼写检测纠正算法整理

NLP 英文拼写算法,如果提升 100W 倍的性能?

NLP 中文拼写检测纠正 Paper

java 实现中英文拼写检查和错误纠正?可我只会写 CRUD 啊!

一个提升英文单词拼写检测性能 1000 倍的算法?

单词拼写纠正-03-leetcode edit-distance 72.力扣编辑距离

NLP 开源项目

nlp-hanzi-similar 汉字相似度

word-checker 中英文拼写检测

pinyin 汉字转拼音

opencc4j 繁简体转换

sensitive-word 敏感词

前言

大家好,我是老马。

下面的内容是一些其他小伙伴开源的比较优秀的实现和文章解释。

个人感受

这里的贝叶斯感觉实际实现起来特别简单,就是找到对应拼写错误的单词。

然后计算对应的 2 以内的编辑距离的单词,计算出现的概率,进行排序返回即可。

和我的实现逻辑是一样的,不同的是我已经提前处理好了词典的频率。

不过感觉还是有 n-gram 的优化,可以更加准确。

比如前面输入一个单词,后面存在错误的,那么前面的一个应该是已经存在的概率,然后推导后面的,用 2-gram 之类的方式。

贝叶斯公式

什么是贝叶斯公式?

来看来自维基百科的定义:

贝叶斯定理

贝叶斯定理由英国数学家贝叶斯 ( Thomas Bayes 1702-1761 ) 发展,用来描述两个条件概率之间的关系,比如 P(A|B)P(B|A)

按照定理 6 的乘法法则,P(A∩B)=P(A)·P(B|A)=P(B)·P(A|B),可以立刻导出贝叶斯定理:

P(A|B) = P(A)·P(B|A) / P(B)

如上公式也可变形为

P(B|A) = P(A)·P(A|) / P(A)

拼写错误的定义

拼写纠错(Spelling Correction),又称拼写检查(Spelling Checker),往往被用于字处理软件、输入法和搜索引擎中。

拼写纠错一般可以拆分成两个子任务:

拼写错误检测Spelling Error Detection:按照错误类型不同,分为Non-word Errors和Real-word

Errors。前者指那些拼写错误后的词本身就不合法,如错误的将"giraffe”写成"graffe”;后者指那些拼写错误后的词仍然是合法的情况,如将"there”错误拼写为"three”(形近),将"peace”错误拼写为"piece”(同音),将"two”错误拼写为"too”(同音)。

拼写纠错Spelling Error Correction:自动纠错,如把"hte”自动校正为"the”,或者给出一个最可能的拼写建议,甚至一个拼写建议列表。

二、Non-word拼写错误

拼写错误检测Spelling error detection:任何不被词典所包含的word均被当作拼写错误(spelling error),识别准确率依赖词典的规模和质量。

拼写纠错Spelling error correction:查找词典中与error最近似的word,常见的方法有:

最短加权编辑距离(Shortest weighted edit distance)和最高噪音通道概率(Highest noisy channel probability)。

三、Real-word拼写错误

拼写错误检测Spelling error detection:每个word都作为拼写成员(spelling error candidate)。

拼写纠错Spelling error correction:从发音和拼写等角度,查找与word最近似的words集合作为拼写建议,常见的方法有最高噪音通道概率(Highest noisy channel probability)和分类(Classifier)。

四、基于噪声信道模型(Noisy Channel Model)的拼写纠错

Noisy Channel Model 即噪声信道模型,或称信源信道模型,这是一个普适性的模型,被用于语音识别、拼写纠错、机器翻译、中文分词、词性标注、音字转换等众多应用领域。

其形式很简单,如下图所示:

模型

噪声信道试图通过带噪声的输出信号恢复输入信号,形式化定义为:

恢复输入信号

应用于拼写纠错任务的流程如下:

拼写纠错任务

noisy word(即splling error)被看作original word通过noisy channel转换得到,现在已知noisy word(用x表示)如何求得最大可能的original word(用w表示),公式如下:

result

P(w)为先验概率,P(x|w)为转移概率,二者可以基于训练语料库建立语言模型和转移矩阵(又称error model,channel model)得到。

五、拼写检查器

第一步,以一个比较大的文本文件big.txt作为样本,分析每个单词出现的概率作为语言模型(Language Model)和词典。

big.txt的地址是:http://norvig.com/big.txt

第二步,如果用户输入的单词不在词典中,则产生编辑距离(Edit Distance)为2的所有可能单词。

所谓编辑距离为1就是对用户输入的单词进行删除1个字符、添加1个字符、交换相邻字符、替换1个字符产生的所有单词。

而编辑距离为2就是对这些单词再进行一次上述所有变换,因此最后产生的单词集会很大。

可以与词典作差集,只保留词典中存在的单词。

1)插入一个字符(Insertion) 2)删除一个字符(Deletion) 3)替代一个字符(Substitution) 4)转义一个字符(Transposition)

第三步,假设事件c是我们猜测用户可能想要输入的单词,而事件w是用户实际输入的错误单词,根据贝叶斯公式可知:

P(c|w) = P(w|c) * P(c)/ P(w)

这里的P(w)对于每个单词都是一样的,可以忽略。

P(w|c) 是误差模型(Error Model),是用户想要输入w却输入c的概率,这是需要大量样本数据和事实依据来得到的,为了简单起见也忽略掉。

因此,我们可以找出编辑距离为2的单词集中P(c)概率最大的几个来提示用户。

据统计,80%的拼写错误编辑距离为1,几乎所有的拼写错误编辑距离小于等于2,基于此,可以减少大量不必要的计算。

通过计算最小编辑距离获取拼写建议候选集(candidate w),此时,我们希望选择概率最大的w作为最终的拼写建议,基于噪声信道模型思想,需要进一步计算 P(w)P(x|w)

通过对语料库计数、平滑等处理可以很容易建立语言模型,即可得到P(w)。

核心实现

https://github.com/hlk-1135/Dictionary

public class SpellChecker {private static final char[] alphabets = "abcdefghijklmnopqrstuvwxyz".toCharArray();public void start() throws IOException {//1.构建语言模型String path = "E:\\big.txt";Map<String, Double> languModel = buildLanguageModel(path);Set<String> dictionary = languModel.keySet();while((input = reader.readLine()) != null) {input = input.trim().toLowerCase();if("bye".equals(input))break;if(dictionary.contains(input))continue;long startTime = System.currentTimeMillis();//3.在编辑距离内设置一个单词集,并删除字典中不存在的单词Set<String> wordsInEditDistance = buildEditDistance1Set(languModel, input);wordsInEditDistance.retainAll(dictionary);if(wordsInEditDistance.isEmpty()) {wordsInEditDistance = buildEditDistance2Set(languModel, input);wordsInEditDistance.retainAll(dictionary);if (wordsInEditDistance.isEmpty()) {System.out.println("Failed to check this word!");continue;}}// 4.计算所以可能的概率List<String> guessWords = guessRightWord(languModel, wordsInEditDistance);System.out.printf("Do you want to input %s and Cost time: %.10f second(s)\n",guessWords.toString(), (System.currentTimeMillis() - startTime) / 1000D);}}/*** 读取语料库big.txt,构建模型* @param path* @return* @throws IOException*/private Map<String, Double> buildLanguageModel(String path) throws IOException {Map<String, Double> languModel = new HashMap<String, Double>();BufferedReader reader = new BufferedReader(new FileReader(path));//去掉文档中除字母外的所有符号Pattern pattern = Pattern.compile("[a-zA-Z]+");String line;int totalCount = 0;while ((line = reader.readLine()) != null) {String[] words = line.split(" ");for(String word : words) {if(pattern.matcher(word).matches()) {word = word.toLowerCase();Double wordCount = languModel.get(word);if(wordCount == null) {languModel.put(word, 1D);} else {languModel.put(word, wordCount+1D);}totalCount++;}}}reader.close();for(Entry<String, Double> entry : languModel.entrySet())entry.setValue(entry.getValue() / totalCount);return languModel;}/*** 编辑距离为1的单词集合* @param languModel* @param input* @return*/private Set<String> buildEditDistance1Set(Map<String, Double> languModel,String input) {Set<String> wordsInEditDistance = new HashSet<String>();char[] characters = input.toCharArray();// 删除:删除一个字母的情况,delete letter[i]for(int i=0;i<input.length();i++) {wordsInEditDistance.add(input.substring(0,i) + input.substring(i+1));}// 换位: 交换letter[i] and letter[i+1]for(int i=0;i<input.length()-1;i++) {wordsInEditDistance.add(input.substring(0,i) + characters[i+1] + characters[i] + input.substring(i+2));}// 替换: 将 letter[i]替换为a-zfor(int i=0;i<input.length();i++) {for(char c : alphabets) {wordsInEditDistance.add(input.substring(0,i) + c + input.substring(i+1));}}// 插入: 插入一个新的字母 a-zfor(int i=0;i<input.length()+1;i++){for(char c : alphabets) {wordsInEditDistance.add(input.substring(0,i) + c + input.substring(i));}}return wordsInEditDistance;}/*** 编辑距离为2的集合.通过editDistance1函数得到编辑距离为1的集合,* 该集合单词再通过editDistance1函数,就可以得到编辑距离为2的集合 * @param languModel* @param input* @return*/private Set<String> buildEditDistance2Set(Map<String, Double> languModel,String input) {Set<String> wordsInEditDistance1 = buildEditDistance1Set(languModel, input);Set<String> wordsInEditDistance2 = new HashSet<String>();for(String editDistance1 : wordsInEditDistance1) {wordsInEditDistance2.addAll(buildEditDistance1Set(languModel, input));}wordsInEditDistance2.addAll(wordsInEditDistance1);return wordsInEditDistance2;}/*** 从语料库中获取正确单词* @param languModel* @param wordsInEditDistance* @return*/private List<String> guessRightWord(final Map<String, Double> languModel,Set<String> wordsInEditDistance){List<String> words = new LinkedList<String>(wordsInEditDistance);//按照单词在字库中出现的频率大小排序,频率越大出现的可能性越大  Collections.sort(words, new Comparator<String>() {@Overridepublic int compare(String word1, String word2) {return languModel.get(word2).compareTo(languModel.get(word1));}});    return words.size() > 5 ? words.subList(0, 5) : words;}
}

小结

希望本文对你有所帮助,如果喜欢,欢迎点赞收藏转发一波。

我是老马,期待与你的下次相遇。

参考资料

贝叶斯公式与拼写检查器

http://mindhacks.cn/2008/09/21/the-magical-bayesian-method/

https://blog.youxu.info/spell-correct.html

基于贝叶斯算法的拼写检查器

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/494351.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SpringBoot核心:自动配置

有使用过SSM框架的&#xff0c;还记得曾经在spring-mybatis.xml配置了多少内容吗&#xff1f;数据源、连接池、会话工厂、事务管理&#xff0c;而现在Spring Boot告诉你这些都不需要了&#xff0c;简单的几个注解统统搞定&#xff0c;是不是很方便&#xff01; 前言 SpringBoo…

重温设计模式--职责链模式

文章目录 职责链模式的详细介绍C 代码示例C示例代码2 职责链模式的详细介绍 定义与概念 职责链模式&#xff08;Chain of Responsibility Pattern&#xff09;是一种行为型设计模式&#xff0c;它旨在将请求的发送者和多个接收者解耦&#xff0c;让多个对象都有机会处理请求&a…

微信小程序UI自动化测试实践 !

微信小程序UI自动化测试实践 引言&#xff1a; 随着微信小程序的快速发展&#xff0c;越来越多的企业和开发者开始开发小程序来满足用户的需求。而在开发小程序的过程中&#xff0c;UI自动化测试是一个必不可少的环节&#xff0c;可以帮助开发者减少人工测试的工作量&#xff…

C#在自定义事件里传递数据

通过自定义事件来传值。此种方法适合于写驱动程序。进行数据采集。 对于一般的系统事件&#xff0c;是有两个参数的&#xff0c;一个是sender&#xff0c;一个是EventArgs&#xff0c;对于sender&#xff0c;个事件的触发者&#xff0c;一般指向的是一个控件&#xff0c;但是对…

MacroSan 2500_24A配置

双控制器电源同时按下,切记/切记/切记 默认信息 默认地址:192.168.0.210 输入ODSP授权后设置密码## 配置端口 物理资源–>设备–>网口–>eth-1:0:0或eth-2:0:0 创建存储池 存储资源–>存储池 介质类型:混合(支持机械及SSD)全闪(仅支持SSD) RAID类型:CRAID-P(基于磁…

法学硕士,有哪些专业可以申请呢?

同等学力申请硕士学位 &#xff08;简称“同等学力申硕”&#xff09; 是指本科毕业获得学士学位的人员&#xff0c;通过工作之余的时间参与课程的学习&#xff0c; 把专业知识水平提升至研究生毕业的同等水平&#xff0c; 在院校的专业考核和国家统考成绩通过后&#xff0c; 成…

大数据操作实验一

实验一&#xff1a;https://www.hifleet.com/wp/communities/data/hangyundashujujishukechengshiyanzhinan 1.Postgresql 1.1 数据库的对象创建 1.1.1 创建数据库(Database) 鼠标右键database进行创建 1.1.2 创建图(Schema) 鼠标右键schema&#xff0c;然后创建schema图…

Java Spring Boot 项目中嵌入前端静态资源:完整教程与实战案例

言简意赅的讲解Java Spring Boot 中嵌入前端项目的静态资源解决的痛点 之前给大家讲解了如何部署一个前端项目&#xff0c;但大家还是好奇如何部署一个前后端一体项目。将前端构建后的静态资源嵌入 Java Spring Boot 后端项目&#xff0c;是现代全栈开发中一种流行的实践方式。…

独一无二,万字详谈——Linux之文件管理

Linux文件部分的学习&#xff0c;有这一篇的博客足矣! 目录 一、文件的命名规则 1、可以使用哪些字符&#xff1f; 2、文件名的长度 3、Linux文件名的大小写 4、Linux文件扩展名 二、文件管理命令 1、目录的创建/删除 &#xff08;1&#xff09;、目录的创建 ① mkdir…

ctfshow web入门文件上传总结

1.web151 前端验证 前端验证&#xff0c;修改html代码&#xff0c;上传还有一句话木马的php文件,之后用蚁剑连接即可找到flag <?php eval($_POST[1])?>2.web152 后端验证&#xff0c;修改mime类型(content-type) burp抓包&#xff0c;修改content-type为image/png …

R9000P键盘失灵解决办法

问题描述 突然&#xff0c;就是很突然&#xff0c;我买的R9000P 2024不到三个月&#xff0c;键盘突然都不能用了&#xff0c;是所有键盘按键都无效的那种。&#xff08;可以使用外接键盘&#xff09; 解决办法 我本科室友说的好哈&#xff0c;全坏全没坏。 &#xff08;该解…

vscode添加全局宏定义

利用vscode编辑代码时&#xff0c;设置了禁用非活动区域着色后&#xff0c;在一些编译脚本中配置的宏又识别不了 遇到#ifdef包住的代码就会变暗色&#xff0c;想查看代码不是很方便。如下图&#xff1a; 一 解决&#xff1a; 在vscode中添加全局宏定义。 二 步骤&#xff1a…

KingbaseES(金仓数据库)入门学习

前言 金仓是一种多进程架构&#xff0c;每一个连接到服务器的会话&#xff0c;在服务器上面都会为该会话分配进程 图形化界面管理 新建数据库名 然后新建一个模式 再创建一个表 新建一个表&#xff0c;然后设置列名 记得要保存 查询数据 也可以新建数据表&#xff0c;用命令…

SpringCloud 入门(3)—— Nacos配置中心

上一篇&#xff1a;SpringCloud 入门&#xff08;2&#xff09;—— 跨服务调度-CSDN博客 Nacos是阿里巴巴开源的服务发现与配置管理基础设施&#xff0c;旨在帮助开发者更轻松地构建云原生应用。它提供了一组简单易用的特性集&#xff0c;支持动态服务发现、配置管理和服务管理…

中地数码亮相2024武汉市数字经济应用场景对接大会

为推动数字经济应用场景供需有效精准对接&#xff0c;加快新技术新产品在汉应用推广&#xff0c;12月16日&#xff0c;由武汉市数据局主办的2024武汉市数字经济应用场景对接暨揭榜挂帅项目发布会成功举行。作为国产GIS基础软件领军企业&#xff0c;中地数码受邀出席作数字赋能产…

《解锁 Python 数据挖掘的奥秘》

《解锁 Python 数据挖掘的奥秘》 一、Python 数据挖掘基础&#xff08;一&#xff09;Python 基础与数据挖掘环境搭建&#xff08;二&#xff09;数据挖掘基本流程概述 二、Python 数据挖掘核心技术&#xff08;一&#xff09;数据收集与预处理技术&#xff08;二&#xff09;常…

如何学习Trustzone

阅读官方文档 ARM 官方文档是学习 Trustzone 最权威的资料来源。例如&#xff0c;ARM Architecture Reference Manual 中详细介绍了 Trustzone 的架构原理、寄存器定义和操作模式等内容。这些文档虽然比较复杂&#xff0c;但能够提供最准确的技术细节&#xff0c;适合在学习过…

Gaea学习笔记总结

Gaea 是一款地形创建软件&#xff0c;它内置了丰富的地貌节点&#xff0c;能快速生成像山脉、荒原峡谷、河流、湖泊等地貌特征。 节点解释使用方法概述Primitives&#xff08;基本体&#xff09;Constant&#xff08;常数&#xff09;创建输出&#xff0c;一般用来输出Hight&am…

Pytorch | 从零构建MobileNet对CIFAR10进行分类

Pytorch | 从零构建MobileNet对CIFAR10进行分类 CIFAR10数据集MobileNet设计理念网络结构技术优势应用领域 MobileNet结构代码详解结构代码代码详解DepthwiseSeparableConv 类初始化方法前向传播 forward 方法 MobileNet 类初始化方法前向传播 forward 方法 训练过程和测试结果…

深度学习0-前置知识

一、背景 AI最大&#xff0c;它的目的是通过让机器模仿人类进而超越人类&#xff1b; ML次之&#xff0c;它是AI的一个分支&#xff0c;是让机器模仿人类的一种方法。开发人员用大量数据和算法“训练”机器&#xff0c;让机器自行学会如何执行任务&#xff0c;它的成功取决于…