开篇先看几张张熟悉的图:




很多朋友可能都熟悉这种界面,那今天我们就揭开其中奥秘

一、贝叶斯公式是什么

回忆里想起小时候,不对, 应该是高中的时候咱都学过一些概率知识 ,什么排列、组合,古典概型。。。等名词,不过如此,那就直入主题先简单聊聊贝叶斯公式。

说起贝叶斯公式,不得不提 条件概率:

所考虑的是事件A已发生的条件下B发生的概率

为此我翻看了尘封已久的《概率论》 ,有如下结论:

P(AB)=P(A)P(B|A)

翻译过来AB就是同时发生的概率等于A发生的概率乘上A发生的条件下B发生的概率,其中人们习惯用P(某事)来表示某事发生的概率。

举个形象的例子:

将一枚硬币抛掷两次,观察其出现正反面的情况,设事件A为“至少有一次为正面”,事件B为“两次掷出同一面”。
那么这里抛两次一共有{正正,正反,反正,反反}四种可能
那么A有{正正,正反,反正}三种可能==》P(A)=3/4
而B则有{正正,反反}两种可能==》P(B)=1/2
那么重点来了,P(B|A)表示A发生的情况下也就是{正正,正反,反正}发生时,出现{正正,反反}的概率,显然{反反}在A发生的情况下不可能发生,而{正正}有1/3的概率发生,所以==》P(B|A)=1/3
同理P(A|B)表示B发生的情况下A发生的概率,显然就是1/2,==》P(A|B)=1/2
而P(AB)表示A、B同时发生的概率,观察发现只有{正正}能满足,得到==》P(AB)=1/4=P(B|A)*P(A)
这里买下一个伏笔,其实不难发现P(BA)=P(AB)=P(B|A)*P(A)=P(A|B)*P(B)


这点要是抗不住了中就不用往下看啦。

Ok,条件概率明白以后,我们开启揭开贝叶斯公式模式

上一个例子留下了一个伏笔:

P(AB)=P(B|A)*P(A)=P(A|B)*P(B)

这里就不给于证明了,想想应该是能明白的。其实说白了这就是贝叶斯公式,那位客观笑了,就这么简单?对,就是这么简单,可别小看了这个小公式,这可是一个思想,是在贝叶斯死后几十年才被世人所发现其用途的一个思想,俗称“逆概”

说可能没什么概念,再举个栗子,我们就能明白其中之奥妙了:

话说一个学校有男生女生,男生占比为60%,女生占比为40%,
而男生全是穿裤子的,女生则不然,女生有70%穿裤子,30%穿裙子
下面请听题:
1.对面走过来一个美眉,请问她穿裤子的概率是多大,想都不想是:70%
2.远处走过来一个穿裤子的学生,那么该学生是女生的概率有多大?这。。那,,,额,,我算算。。。。
怎么样,是不是比第一个问题复杂多了,这就是个典型的“逆概”问题,这个问题,不用贝叶斯公式,用点数学知识还是能求出来的:P(女|库)=女库/(男库+女库)就可以了,但是在自然界中,很多时候并不能求得(男裤+女裤)的数量(这种例子很多很多,就不列举了,毕竟咱目的不是为了研究数学,而是用数学)
第二个问题用贝叶斯公式来解释就是:P(女|库)=P(库|女)*P(女)/P(库)=70%*40%/(60%+28%)=7/22。

二、单词拼写纠错器实现原理分析

至此,今天咱们这个小算法所用到的数学知识就说完了,下面进入主题———–
就以开篇的图为例 ,咱们输入了一个lovl,首先这个单词是错误的,那么实际是想入的是什么呢?那位说话了,你二叉么,我怎么知道实际想输入什么?什么love、lovely、loll、lov 。。。。。。。。。,我怎么知道要输入哪个。
对,说的很对,鬼知道想输入哪个,他实际想输入什么咱不知道,那可不可以这样想,根据他输错的这个单词,咱们找出所有和他输错的这个单词像的单词,然后把其中在英文中出现频率最多的词作为他想输入的单词如何?

其实机器学习不就是以概率说话的么?

OK,继续,直接上公式,咱这里就是求P(love|lovl)、P(lovely|lovl)、P(loll|lovl)、P(lov|lovl)。。。。。。哪个概率最大不是么

P(love|lovl)为例,这个概率值得意思是输入了一个错误单词lovl,那么他是想输入love的概率。要求他的概率,套用贝叶斯公式,P(love|lovl)=P(lovl|love)*P(love)/P(lovl),这不就可以了么?
而分母中P(lovl)的值无法求得,但是这个单词确实是已经输错了,已经成了一个定值,所以说P(love|lovl)∝P(lovl|love)*P(love),而P(love)的使用频率我们是可以基于一个语料库求得到的,也就是说P(love)是一个先验概率,即已知值。

那么问题就转化为求P(lovl|love)得值,这个值是很不好求得,为什么呢?看个例子
把love输成lovl和把love输成oove的概率哪个大?这个显然前者可能性比后者大,大多少呢?这个就没办法量化了

但是我能肯定的是把love输入成lovl的概率要比把love输入成lovll的概率大

所以说咱这里只能定性的分析,即默认使 love输错一个字母得到错误单词的概率相等,即P(lovl|love)=P(lovel|lovle)=P(lvoe|love)=P(lov|love)(这里的转换要注意),而假设输错两个字母得到的错误单词的概率相等,但是这个概率值肯定要远远小于输入一个字母的概率,这个不用多做解释了吧。

那么问题最终转化为找先找一步输错时(包括增删改插四种情况)可能的正确单词的概率进行比较,即P(love)、P(lova)、P(loll)、P(lov)。。。。。谁的概率最大,当然一步纠错后得到的单词可能也不是正确单词,那么咱可以进行二步纠错,比如输入了lovlle,需要纠正两次才能得到正确单词love,或者loll。说了这么多啰嗦的话只为帮助各位理解,形象点表示就是:

P(正确单词|错误单词)∝P(错误单词|正确单词)*P(正确单词)∝P(正确单词)

三、python实现纠正器

下面直接上代码了,可能讲得原理什么的迷迷糊糊,但我保证,代码走一遍,绝对就明明白白了,毕竟实践出真知嘛。

首先声明,我是用python中最简单的语法实现此功能,帮助大家理解,用高级语法二十行就搞定就什么都看不明白了。

首先得到每个单词的使用频率,即P(正确单词)

# 读取big.txt 内容,big.txt就是原理中提到的语料库,这个不是死的
open_r = open("big.txt", 'r')
big_info = open_r.read()
open_r.close()# 提炼出单词的方法,即把标点符号什么的都去掉了,并且把单词都转化为小写
def words(info):return re.findall("[a-z]+", info.lower())
# 计算词出现的次数
def wordIndex(wordtext):words = {}for word in wordtext:if word in words:words[word] = words[word] + 1else:words[word] = 1return words#调用方法得到每个单词使用的次数
words_map = wordIndex(words(big_info))

其中alphabet = 'abcdefghijklmnopqrstuvwxyz'

OK,words_map 就是我们得到的以正确单词为key,使用次数为value的一个字典。

下面进行第一步排除,毕竟不是每次输入的都是错误单词对吧,也就是说,输入的一个单词如果在words_map中有这个key,那么就认为输入的是正确的单词,返回他就好了

# 如果存在该单词则返回该单词
def known(word):word1 = []for word_one in word:if word_one in words_map:word1.append(word_one)return word1

紧接着,如果发现输入的单词words_map中没有,那么我们就进行一步纠正看他在words_map中有多少个单词能满足。

# 一次纠正得到一个集合
def knomn_edit1(words):edit1_word = []n = len(words)for j in range(n):# print(i)word = words[j]m = len(word)for i in range(m):if i != m - 1:edit1_word.append(word[0:i] + word[i + 1:])  # 删if i != m - 2:edit1_word.append(word[0:i] + word[i + 1] + word[i] + word[i + 2:])  # 移动else:edit1_word.append(word[0:i] + word[i + 1] + word[i])  # 移动for ch in alphabet:edit1_word.append(word[0:i] + ch + word[i + 1:])  # 替换edit1_word.append(word[0:i] + ch + word[i:])  # 插入else:edit1_word.append(word[0:(m - 1)])  # 删for ch in alphabet:edit1_word.append(word[0:(m - 1)] + ch)  # 替换edit1_word.append(word[0:m] + ch)  # 插入return edit1_word

对一步纠正这里的情况想象不出来的,可以在纸上画几张图试试,就能明白其中奥秘了。
如果一步纠正得到的结果中没有正确单词,那么我们有必要进行二步纠正了,也就是循环调用下一步纠正的方法:

# 二次纠正
def know_edit2(word):words1 = knomn_edit1(word)words2 = knomn_edit1(words1)edit2_word = []for word2 in words2:if word2 in words_map:edit2_word.append(word2)return edit2_word

下面整合方法:

def correct(word):canword = known([word]) or known(knomn_edit1([word])) or know_edit2([word])if len(canword) == 0:#如果两步纠正还是没得到正确单词,那么就默认返回输入的错误单词canword = [word]print(canword)else:#得到words_map 中value值最大的keymax_info = max(canword, key=lambda w: words_map[w])#打印出找到的使用次数最多的单词和使用次数print(str(max_info) + "----P---" + str(words_map[max_info]))

四、测试:

测试一:

word2 = 'misk'
correct(word2)

得到:

miss----P---112

测试二:

word2 = 'lovl'
correct(word2)

得到:

love----P---484

Tips:

代码中所用语料库不是特别大 ,用时基本在毫秒级别,效果还是可以的。
有问题欢迎加群:780239930 ,共同探讨。
代码和数据集已上传github,点击查看,欢迎star、fork

机器学习入门--带着贝叶斯公式一步步实现单词拼写纠正器,这一篇就够了相关推荐

  1. 机器学习:单词拼写纠正器python实现

    01 朴素贝叶斯分类实战 前面介绍了贝叶斯的基本理论,朴素贝叶斯分类器,拉普拉斯修正,文章的链接如下: 机器学习:说说贝叶斯分类 朴素贝叶斯分类器:例子解释 朴素贝叶斯分类:拉普拉斯修正 在这3篇推送 ...

  2. 《C语言入门指南》合集版,学习c语言有这一篇就够了?

    前言: <C语言入门指南>,全文分为3篇,共计34248字,此为合集版,适用初学者入门C语言,非初学者也可以通过本文复习C语言相关知识点,强化记忆!十三肝7天才弄完,贼累了,发布这篇笔记也 ...

  3. 黑客零基础入门教程及方法,从零开始学习黑客技术,看这一篇就够了

    黑客,对于很多人来说,是一个神秘的代名词,加之影视作品夸张的艺术表现,使得黑客这个本来只专注于技术的群体,散发出亦正亦邪的神秘色彩. 黑客源自英文hacker一词,最初曾指热心于计算机技术.水平高超的 ...

  4. 导入drf_Django后端rest最简洁最快最全入门指南,1天学会DRF后端不夸张,看这篇就够了!!...

    Django REST framework 模型 字段类型 #BooleanField # CharField(max_length=none[, **options]) # DateField Da ...

  5. 机器学习入门学习资料推荐

    今天介绍一些机器学习的学习资料,主要是分为以下几个方面的内容: 编程语言:实现机器学习,主要是介绍 Python 方面的语言: 书籍:看书通常是入门的一种方法,比较适合自律性强的同学: 视频:入门的第 ...

  6. 留言送书:又一机器学习入门力作

    送书方式见文末,先听我好好介绍这本书. 近日,公众号"量子位(ID:QbitAI)编译的一组数据曝光了爱彼迎(Airbnb).AR新锐Magic Leap等12家独角兽公司的工程师薪酬水平. ...

  7. 机器学习入门篇【一】:以拉家常的方式讲机器学习

    前言 因为对机器学习比较感兴趣,最近也可能会用得上,所以想浅浅的谈一谈机器学习,大佬就不用在这浪费时间了,不涉及公式推导.甚至该篇都称不上是什么经验贴,只能说是最近搜寻有些资料有感而发. 那么想通过这 ...

  8. 十年公务员转行IT,自学AI三年,他淬炼出746页机器学习入门笔记

    整理 | Jane 编辑 | Just 出品 | AI科技大本营(ID:rgznai100) 近期,梁劲传来该笔记重大更新的消息.<机器学习--从入门到放弃>这本笔记的更新没有停止,在基于 ...

  9. 我的机器学习入门清单及路线!

    Datawhale干货 作者:桔了个仔,南洋理工大学,Datawhale成员 知乎:https://www.zhihu.com/people/huangzhe 这是我个人的机器学习入门清单及路线,所以 ...

最新文章

  1. 每日一皮:实习生将他的代码交给高级开发人员,高级开发反手一个...
  2. POJ 1236 学校网络间的强连通
  3. 运用node实现简单爬虫
  4. jdbc增删改查_JDBC第二期
  5. get/post 接口调用
  6. leetcode1041困于环中的机器人
  7. web开发——Flask框架
  8. 常用的一些页面操作 js jsp check
  9. bootstrap pagewrapper_BootStrap table服务端分页
  10. 新辰:传统行业进军互联网 怎样颠覆网络获得新生?
  11. atitit 解决教学记忆问题 压缩算法原理  哈夫曼 LZ77 gzip  zlib deflate算法.docx 目录 1. 压缩理论 1 1.1. 柯氏复杂性 1 2. 1 RLE 1
  12. ENVI5.3安装中国国产卫星支持工具
  13. 产品基础——认识竞品分析
  14. Arcgis中的空间插值
  15. 继续惨...555555555
  16. 机票订票b系统的服务器,飞机订票系统分析与总结
  17. 计算机硬件及装机视频,超详细图文 视频电脑组装教程,装机之家手把手教你组装一台电脑(9)...
  18. jquery获取ip地址
  19. 核实c#语言教程,C#教程方法用法 _C#语言-w3school教程
  20. 【ELT.ZIP】OpenHarmony啃论文俱乐部——综述视角解读压缩编码

热门文章

  1. SQL注入绕过--emoji表情包绕过 waf
  2. serialization的真情自述
  3. Kylin(一)概念介绍
  4. 美国波音在中国市场颗粒无收全靠美国市场遮羞,空客和中国商飞成赢家
  5. sweetalert 显示html,sweetalert.html
  6. Python库Pandas数据可视化实战案例
  7. 2018.3.20 一周第二次课
  8. 众昂矿业:神奇的萤石无处不在
  9. 【Django】用file.chunks()代替file.read()
  10. 真正好家庭幸福教育机构