当前位置:小鱼儿玄机二站 > 编程应用 > 21行Python代码实现拼写检查器,用快速使用Pytho

21行Python代码实现拼写检查器,用快速使用Pytho

文章作者:编程应用 上传时间:2019-09-03

21行Python代码完成拼写检查器,21行python

引入

世家在应用谷歌(Google)还是百度搜索时,输入寻觅内容时,谷歌接二连三能提供非常好的拼写检查,举个例子您输入 speling,Google会立即重返 spelling。
下边是用21行python代码完结的叁个简易不过全部完整意义的拼写检查器。

代码

import re, collections

def words(text): return re.findall('[a-z]+', text.lower()) 

def train(features):
  model = collections.defaultdict(lambda: 1)
  for f in features:
    model[f] += 1
  return model

NWORDS = train(words(file('big.txt').read()))

alphabet = 'abcdefghijklmnopqrstuvwxyz'

def edits1(word):
  splits   = [(word[:i], word[i:]) for i in range(len(word) + 1)]
  deletes  = [a + b[1:] for a, b in splits if b]
  transposes = [a + b[1] + b[0] + b[2:] for a, b in splits if len(b)>1]
  replaces  = [a + c + b[1:] for a, b in splits for c in alphabet if b]
  inserts  = [a + c + b   for a, b in splits for c in alphabet]
  return set(deletes + transposes + replaces + inserts)

def known_edits2(word):
  return set(e2 for e1 in edits1(word) for e2 in edits1(e1) if e2 in NWORDS)

def known(words): return set(w for w in words if w in NWORDS)

def correct(word):
  candidates = known([word]) or known(edits1(word)) or known_edits2(word) or [word]
  return max(candidates, key=NWORDS.get)
correct函数是程序的入口,传进去错误拼写的单词会返回正确。如:

>>> correct("cpoy")
'copy'
>>> correct("engilsh")
'english'
>>> correct("sruprise")
'surprise'

除了这一个之外这段代码外,作为机器学习的一有的,明确还应有有恢宏的样书数量,筹划了big.txt作为大家的范本数量。

专断原理

上边的代码是基于贝叶斯来兑现的,事实上Google百度贯彻的拼写检查也是透过贝叶斯完成,不太早晚比这一个纷比非常多了。
率先简介一下从容不迫的原理,假诺读者之前通晓过了,能够跳过这段。
给一个词,我们试图选拔三个最大概的不错的的拼写提出(提出也说不定就是输入的单词)。有的时候也不晓得(比方lates应该被校正为late或然latest?),我们用概率决定把哪多少个当作建议。大家从跟原始词w相关的有所大概的不利拼写中找到或者性最大的拾壹分拼写提议c:

argmaxc P(c|w)

通过贝叶斯定理,上式能够转化为

argmaxc P(w|c) P(c) / P(w)

上面介绍一下上式中的含义:

  • P(c|w)代表在输入单词w 的气象下,你当然想输入 单词c的可能率。
  • P(w|c)代表顾客想输入单词c却输入w的可能率,这些能够大家以为给定的。
  • P(c)表示在样本数量中单词c出现的概率
  • P(w)代表在样本数字中单词w出现的几率

能够规定P(w)对此持有望的单词c可能率都以完全一样的,所以上式能够转移为
argmaxc P(w|c) P(c)
大家具备的代码都以基于那么些公式来的,下边深入分析具体代码落成

代码剖判

动用words()函数提取big.txt中的单词

def words(text): return re.findall('[a-z]+', text.lower())

re.findall(‘[a-z]+'是选取python正则表明式模块,提取全部的符合'[a-z]+'条件的,也等于由字母组成的单词。(这里不详细介绍正则表明式了,风乐趣的同窗能够看 正则表明式简单介绍。text.lower()是将文件转化为小写字母,也正是“the”和“The”同样定义为同二个单词。

应用train()函数计算种种单词出现的次数然后练习出多少个相宜的模型

def train(features):
  model = collections.defaultdict(lambda: 1)
  for f in features:
    model[f] += 1
  return model
NWORDS = train(words(file('big.txt').read()))

这样NWORDS[w]意味着了单词w在样本中出现的次数。假使有二个单词并不曾出现在大家的样本中该如何做?管理措施是将她们的次数暗中认可设为1,这里通过collections模块和lambda说明式完毕。collections.defaultdict()创制了五个暗中认可的字典,lambda:1将以此字典中的每一种值都默许设为1。

目前大家处理完了公式argmaxc P(w|c) P(c)中的P(c),接下去管理P(w|c)即想输入单词c却错误地输入单词w的可能率,通过 “edit distance“--将二个单词变为另二个单词所要求的编纂次数来衡量,贰次edit或者是二次删除,三个沟通(四个相邻的假名),贰回插入,三遍修改。下边包车型大巴函数再次回到三个将c举行贰回编辑全数希望赢得的单词w的集聚:

def edits1(word):
  splits   = [(word[:i], word[i:]) for i in range(len(word) + 1)]
  deletes  = [a + b[1:] for a, b in splits if b]
  transposes = [a + b[1] + b[0] + b[2:] for a, b in splits if len(b)>1]
  replaces  = [a + c + b[1:] for a, b in splits for c in alphabet if b]
  inserts  = [a + c + b   for a, b in splits for c in alphabet]
  return set(deletes + transposes + replaces + inserts)

连带故事集展现,80-95%的拼写错误跟想要拼写的单词都独有1个编辑距离,假使认为贰次编辑相当不足,那我们再来一次

def known_edits2(word):
  return set(e2 for e1 in edits1(word) for e2 in edits1(e1) if e2 in NWORDS)

何况还会有编写制定距离为0次的即小编就拼写正确的:

def known(words):
  return set(w for w in words if w in NWORDS)

咱俩只要编辑距离1次的概率远大于2次的,0次的远大于1次的。上面通过correct函数先选择编辑距离最小的单词,其对应的P(w|c)就能够越大,作为候选单词,再选择P(c)最大的极其单词作者为拼写提出

def correct(word):
  candidates = known([word]) or known(edits1(word)) or known_edits2(word) or [word]
  return max(candidates, key=NWORDS.get)

如上便是本文的全体内容,希望对大家学习python程序设计具备协理。

简轻便单介绍

拼写检查器是个要命常用的工具,将来大概全部涉嫌到寻找的网址都已经落实了那几个功效。那拼写检查器是否很复杂呢?不是的,只要你通晓有个别贝叶斯公式的规律,你就能够写出二个拼写检查器来。

你或者感兴趣的篇章:

  • PHP webshell检查工具 python达成代码
  • python代码检查工具pylint 让您的python更标准
  • python定期检查运维有些exe程序符合检查测量检验exe是或不是挂了
  • Python 检查数组成分是还是不是留存类似PHP isset()方法
  • Python达成单词拼写检查
  • python定期检查某个进程是不是早就关门的方式
  • python检查字符串是或不是是正确ISBN的点子
  • 使用python检查测量试验主机存活端口及检查存活主机

引进我们在选用谷歌(Google)或许百度找出时,输入寻觅内容时,谷歌(Google)连日来能提供足够好的拼写检查,比如...

什么样是贝叶斯公式

贝叶斯定理是有关自由事件A和B的法规可能率的一则定理。
P(c|w) = P(w|c) P(c) / P(w)

P(c|w):指的是w意况下c发生的可能率
P(w|c):指的是已知c发生后,产生w的概率
P(c) , P(w):分别指的是c,w独立产生的可能率。

以此公式用处非平常见,概率论和计算学都离不了它。
那么在拼写检查器中贝叶斯公式起什么效用吗?
很简短,大家得以把 P(c|w)看开支来要输入c结果输入成w的概率。今后遵照贝叶斯公式的扩充,那些可能率等于P(w|c) P(c) / P(w)
内部P(c) , P(w)分别为c和w三个单词在语料库中冒出的票房价值,供给出其余几个单词出现的概率其实很简短,只要透过大气的语言质感磨炼就能够寻觅来了。而在那一个地点,p(w)仍是能够省略掉,应该为我们并非要适度的求出一个可能率来,我们只须要一个可能率来协助大家看清出哪位词是最或然正确的。而在三回输入错误中,p(w)是永远的,所以可以省略。P(w|c) 则比较费心,它表示在拼写c的图景下,出现拼写错误w的可能率。这里就须求概率学做冲突帮助了。一般的话,看起来越像的单词拼错的票房价值越大,而八个单词有多少种拼错的恐怕吧?无非就少拼,多拼,地点不对,拼错多种或然。

love 少拼:lov,多拼:lovee,位置不对:loev,拼错:lova

理所必然现实生活中不确定只出现一个假名内的不当,但倘使不当过多则作用则有非常大希望将以此单词错拼为另一没有错的单词。这里为了便于开垦,大家就暂且允许客户出现小于等于多少个假名的荒唐。这里就造成了大家以此拼写检查的率先片段。

以此艺术也许有其一格局的局限性,比如出现以下错误时

You wlere a student

程序怎样抉择出科学的单词呢?是选项where依旧were?为了缓慢解决这么些难点,大家可以安顿一个有向图(directed graph),个中的节点(Node)表示单词,而节点之间的edge则意味着单词之间的关系。让后透过大气的预想,我们就可以练习出贰个得以领会上下文的拼写检查器,提高算法的科学。

率先要化解的是单词的涉嫌怎么计算,总括单词之间的涉及有非常多样措施。比较成熟的章程有经过深入分析句子中单词的词性,计算其左右单词所出现的次数,将这一个次数最为距离。或许以那些单词为着力,将它紧埃着的单词作者为距离为一的单词,间隔贰个的偏离为二,就这样类推。然后计算距离。但今新加坡人要用一个更简便易行的艺术,仅仅使用一个单词在另贰个单词之后出现的次数作为 edge ,那样的法子相当粗糙,然则我们的问题是‘快捷‘,那些艺术确实相当慢。

小编们应用 networkx 中的 DiGraph 来组织有向图,networkx 是三个用于组织图的 python 扩充包,特别有益,我们能够理解下。然后自个儿选用了《哈利Porter和魔法石》,《飘》,《傲慢与偏见》作为预料。第一步就是读取这个预料,然后建设构造互联网。在 networkx 的增加援助下,这一步变得极其简单,关键代码唯有一行。

ex:love you 在图中是这样表示的:
graph[‘love‘][‘you‘]]['DISTANCE']

每出现一次,[‘DISTANCE’]就加一

其次步是写三个生成备选词的函数,前边早就提过,一的单词在二个字母内的拼写错误只会有两种状态,以往大家只需求枚举在那八种情状中出现的享有单词就好了。

def edit_distance_one(word):
    alphabet = 'qwertyuioplkjhgfdsazxcvbnm'
    splits = [(word[:i], word[i:]) for i in range(len(word) + 1)]
    deletes = [a + b[1:] for a, b in splits if b]
    transposes = [a + b[1] + b[0] + b[2:] for a, b in splits if len(b) > 1]
    replaces = [a + c + b[1:] for a, b in splits for c in alphabet if b]
    inserts = [a + c + b for a, b in splits for c in alphabet]
    return set(deletes + transposes + replaces + inserts)

可是这么枚举出来的单词未必正确,大家还需求组织二个论断这些单词是不是存在的函数,也很简单,就是读入三个单词表,然后看所给的单词在不在单词表中。

#data 即为单词表
return set(w for w in words if w in data)

到那边,早先时代筹划已经基本做到了,将来要做的便是填补流程。
率先步,输入一句话,将其拆分成有独立单词构成的数组。
其次步,遍历这一个数组,借使数组中的单词存在,再次来到垓单词。不设有,再次来到该单词的候选词。
其三部,重回候选词种类之间的笛Carl积,重返distance最大的组成。

到此处,大家的spell corrector尽管实现了,完整代码戳这里。近期的拼写检查器,尽管轻便,不过也是足以用的。假设你想活动在进级一下精度,小编这边还会有多少个提出。
1,扩张大家的语言材质库,三本书照旧有一些少。
2,思索到构词法,譬喻形容词后缀,副词后缀之类的。
3,选拔再燃语言识别的点子,思量词性以及句子的语法结构。那样既可以找寻荒谬的词,以至还能够寻找语法错误。

本文由小鱼儿玄机二站发布于编程应用,转载请注明出处:21行Python代码实现拼写检查器,用快速使用Pytho

关键词: