当前位置: 首页 > news >正文

写作纠错?用机器学习实现单词拼写修正器(附Python代码)

目录

  • 0 写在前面
  • 1 语言中的贝叶斯公式
  • 2 朴素贝叶斯建模
  • 2.1 单词异化
    • 2.2 语言模型建模
    • 2.3 误差模型建模
  • 3 单词修正测试

0 写在前面

机器学习强基计划聚焦深度和广度,加深对机器学习模型的理解与应用。“深”在详细推导算法模型背后的数学原理;“广”在分析多个机器学习模型:决策树、支持向量机、贝叶斯与马尔科夫决策、强化学习等。

🚀详情:机器学习强基计划(附几十种经典模型源码合集)


在机器学习强基计划4-3:详解朴素贝叶斯分类原理(附例题+Python实现)中我们学习了朴素贝叶斯的概念:采用属性独立性假设对类后验概率建模,本节再次使用这个理论实现一个有趣的应用——单词拼写修正器,并梳理一些朴素贝叶斯原理中的细节,以期固本强基。

在这里插入图片描述

1 语言中的贝叶斯公式

我们的目标是找到原拼写错误单词 w w w的修正单词 c c c,一个事实是,我们没有办法给出确定性的答案,例如

例1:错误单词lates应该被修正为latelatest还是lattes…?

因此,我们要找的是一个 w w w所有潜在修正单词中可能性最大的那一个,用概率表示为

c ∗ = a r g m a x c ∈ c a n d i d a t e P ( c ∣ w ) c^*= argmax_{c\in candidate} P(c|w) c=argmaxccandidateP(cw)

其中candidate就是所有候选单词的集合。根据贝叶斯公式,有

c ∗ = a r g m a x c ∈ c a n d i d a t e P ( w ∣ c ) P ( c ) P ( w ) c^*= argmax_{c\in candidate} \frac{P(w|c)P(c)}{P(w)} c=argmaxccandidateP(w)P(wc)P(c)

因为 P ( w ) P(w) P(w)对每个候选单词 c c c都相同,因此可以忽略,所以重点关注

c ∗ = a r g m a x c ∈ c a n d i d a t e P ( w ∣ c ) P ( c ) c^*= argmax_{c\in candidate} P(w|c)P(c) c=argmaxccandidateP(wc)P(c)

其中

  • P ( w ∣ c ) P(w|c) P(wc):称为误差模型,表示的是作者想打出单词 c c c却误写成单词 w w w的概率,例如 P ( t e h ∣ t h e ) P(teh|the) P(tehthe)the打成teh的概率相对而言远大于 P ( t h e e e x y z ∣ t h e ) P(theeexyz|the) P(theeexyzthe)
  • P ( c ) P(c) P(c):称为语言模型,表示的是单词 c c c出现的概率,例如搜索引擎提供用户输入的所有文本中,单词the的占了7%,那么 P ( t h e ) = 0.07 P(the) = 0.07 P(the)=0.07

一个很自然的问题是:为什么要把简单的表达式 P ( c ∣ w ) P(c|w) P(cw)用一个更复杂的 P ( w ∣ c ) P ( c ) P(w|c)P(c) P(wc)P(c)来代替?我相信这也是很多同学初学贝叶斯公式时的困惑,这里用实例说明。

答案很简单:后验概率 P ( c ∣ w ) P(c|w) P(cw)无法直接计算,但是将其拆成两个因子后计算相对简便,而且可以透过现象看到其中的本质。

例2:考虑一个错误拼写的单词w="thew",以及两个候选修正c="the"c="thaw",哪个有更高的 P ( c ∣ w ) P(c|w) P(cw)

c="thaw"似乎更可能,因为从ae只是一个很小的变化,但另一方面,c="the"似乎可能性也很大,因为the是一个非常常用的单词(生僻字出现概率低,自然不容易误写)。从我们正常的分析思路就可以看出,这个后验概率其实包含两个部分,一个是从单词 c c c误写成 w w w的可能性,一个是单词 c c c是否常见。所以贝叶斯公式抽丝剥茧地告诉了我们后验概率的内在逻辑

2 朴素贝叶斯建模

2.1 单词异化

包含四个异化操作产生候选单词集合candidate

  • 删除word中的某个字母deletes
  • word中相邻字母交换顺序transposes
  • word中字母突变(用新字母代替)replaces
  • word中在某位置插入新字母inserts
'''
* @breif: 对单词进行异化操作,产生与原词有微小差异的新词
* @param[in]: word -> (str)原词汇
* @retval: 与原词有微小差异的新词
'''
def editsOnce(self, word):
    # 字母表
    letters    = 'abcdefghijklmnopqrstuvwxyz'
    # 将词汇分解为左右组合,例如tree分解为[(t,ree),(tr,ee),(tre,e),(tree, )]
    splits     = [(word[:i], word[i:])    for i in range(len(word) + 1)]
    deletes    = [L + R[1:]               for L, R in splits if R]
    transposes = [L + R[1] + R[0] + R[2:] for L, R in splits if len(R)>1]
    replaces   = [L + c + R[1:]           for L, R in splits if R for c in letters]
    inserts    = [L + c + R               for L, R in splits for c in letters]
    return set(deletes + transposes + replaces + inserts)

2.2 语言模型建模

搜集一大段文本作为数据集

在这里插入图片描述
接着直接计算词频作为语言模型 P ( c ) P(c) P(c)

'''
* @breif: 查询词汇word的频率
* @param[in]: word -> (str)待查词文本
* @retval: 词汇word的频率p(word)
'''    
def p(self, word):
    self.wordsCnt = Counter(re.findall(r'\w+', text.lower()))
    self.wordsNum = sum(self.wordsCnt.values())
    return self.wordsCnt[word] / self.wordsNum

2.3 误差模型建模

采用短路表达式划分优先级,即优先级为该词汇(在词典中)>经过一次编辑>经过二次编辑>该词汇(不在词典中),若高优先级词汇存在会直接返回,相当于argmaxP(w|c)的操作。

def candidates(self, word): 
    return (self.known([word]) or self.known(self.editsOnce(word)) 
            or self.known(self.editsTwice(word)) or [word])

3 单词修正测试

在这里插入图片描述
首先做一个简单的测试:

def correction(self, word): 
    return max(self.candidates(word), key=self.p)

随便挑几个单词

print(c.correction('worl'))

>>> work

print(c.correction('traon'))

>>> train

print(c.correction('inteligent'))

>>> intelligent

效果还不错,接着拿个大的测试集来测试一下

trainPath = os.path.abspath(os.path.join(__file__, "../../data/big.txt"))
testPath = os.path.abspath(os.path.join(__file__, "../../data/spell_test.txt"))
c = WordsCorrector(trainPath)
c.predict(testPath)

>>> 75% of 270 correct (6% unknown) at 56 words per second

完整代码与数据集联系下方博主名片获取


🔥 更多精彩专栏

  • 《ROS从入门到精通》
  • 《机器人原理与技术》
  • 《机器学习强基计划》
  • 《计算机视觉教程》

👇源码获取 · 技术交流 · 抱团学习 · 咨询分享 请联系👇

相关文章:

  • 【DjangoDRF+缓存 五万字总结】预计在2022.11月份会再次进行更新
  • 猿创征文|实战开发openGauss DataStudio的sql联想结构
  • VMware创建Linux虚拟机之(三)Hadoop安装与配置及搭建集群
  • 在halcon中使用模板匹配助手进行定位真的很好用!!!
  • 青少年python系列 7.函数
  • python入门——m个位置,每个位置有n种可能,求所有排列结果
  • C | 妙用异或
  • 采用uni-app开发的多端圈子社区论坛系统
  • Java语言特点
  • 读书笔记1|深度学习入门:Machine Learning Yearning
  • matplotlib+cartopy+geopandas,实现专业地图可视化
  • 【网络安全篇】php伪协议-漏洞及其原理
  • 【操作系统】实时调度
  • 【python】之序列及其基本操作
  • 温湿度传感器实验-传感器原理及应用实验
  • 002-读书笔记-JavaScript高级程序设计 在HTML中使用JavaScript
  • 2018一半小结一波
  • CoolViewPager:即刻刷新,自定义边缘效果颜色,双向自动循环,内置垂直切换效果,想要的都在这里...
  • ES6 ...操作符
  • ES6 学习笔记(一)let,const和解构赋值
  • iOS筛选菜单、分段选择器、导航栏、悬浮窗、转场动画、启动视频等源码
  • log4j2输出到kafka
  • Median of Two Sorted Arrays
  • Python进阶细节
  • REST架构的思考
  • 计算机在识别图像时“看到”了什么?
  • 模仿 Go Sort 排序接口实现的自定义排序
  • 微信小程序上拉加载:onReachBottom详解+设置触发距离
  • 学习JavaScript数据结构与算法 — 树
  • 掌握面试——弹出框的实现(一道题中包含布局/js设计模式)
  • 追踪解析 FutureTask 源码
  • ​低代码平台的核心价值与优势
  • ​虚拟化系列介绍(十)
  • #1015 : KMP算法
  • #鸿蒙生态创新中心#揭幕仪式在深圳湾科技生态园举行
  • #我与Java虚拟机的故事#连载14:挑战高薪面试必看
  • (23)Linux的软硬连接
  • (第8天)保姆级 PL/SQL Developer 安装与配置
  • (附源码)springboot猪场管理系统 毕业设计 160901
  • (全部习题答案)研究生英语读写教程基础级教师用书PDF|| 研究生英语读写教程提高级教师用书PDF
  • (一)Spring Cloud 直击微服务作用、架构应用、hystrix降级
  • (转)shell调试方法
  • (自适应手机端)响应式新闻博客知识类pbootcms网站模板 自媒体运营博客网站源码下载
  • .NET MVC之AOP
  • .net获取当前url各种属性(文件名、参数、域名 等)的方法
  • @RequestParam详解
  • [ JavaScript ] JSON方法
  • [23] GaussianAvatars: Photorealistic Head Avatars with Rigged 3D Gaussians
  • [BZOJ5250][九省联考2018]秘密袭击(DP)
  • [C# 开发技巧]如何使不符合要求的元素等于离它最近的一个元素
  • [C#]使用DlibDotNet人脸检测人脸68特征点识别人脸5特征点识别人脸对齐人脸比对FaceMesh
  • [C++核心编程](四):类和对象——封装
  • [IE9] IE9 Beta崩溃问题解决方案
  • [ios-必看] IOS调试技巧:当程序崩溃的时候怎么办 iphone IOS
  • [JavaScript]如何讓IE9, IE8, IE7, IE6關閉視窗時不彈出對話訊息