21行python代码实现拼写检查器

时间:2022-09-14 21:56:13

引入

大家在使用谷歌或者百度搜索时,输入搜索内容时,谷歌总是能提供很好的拼写检查,比方你输入 speling,谷歌会立即返回 spelling

前几天,看到http://norvig.com/spell-correct.html这篇文章,于是翻译过来。再加上自己的理解,有了以下的博文。

以下是用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作为我们的样本数据。

背后原理

上面的代码是基于贝叶斯来实现的,其实谷歌百度实现的拼写检查也是通过贝叶斯实现。只是肯定比这个复杂多了。

首先简单介绍一下背后的原理,假设读者之前了解过了。能够跳过这段。

给一个词,我们试图选取一个最可能的正确的的拼写建议(建议也可能就是输入的单词)。有时也不清楚(比方lates应该被更正为late或者latest?),我们用概率决定把哪一个作为建议。我们从跟原始词w相关的全部可能的正确拼写中找到可能性最大的那个拼写建议c:

argmaxc  P(c|w)

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

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

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

  1. P(c|w)代表在输入单词w 的情况下,你本来想输入 单词c的概率。
  2. P(w|c)代表用户想输入单词c却输入w的概率,这个能够我们觉得给定的。
  3. P(c)代表在样本数据中单词c出现的概率
  4. 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。

(lambda表达式能够看lambda简单介绍

如今我们处理完了公式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)

21行python代码实现拼写检查器的更多相关文章

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

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

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

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

  3. 200行PYTHON代码实现贪吃蛇

    200行Python代码实现贪吃蛇 话不多说,最后会给出全部的代码,也可以从这里Fork,正文开始: 目前实现的功能列表: 贪吃蛇的控制,通过上下左右方向键: 触碰到边缘.墙壁.自身则游戏结束: 接触 ...

  4. 15行python代码,帮你理解令牌桶算法

    本文转载自: http://www.tuicool.com/articles/aEBNRnU   在网络中传输数据时,为了防止网络拥塞,需限制流出网络的流量,使流量以比较均匀的速度向外发送,令牌桶算法 ...

  5. 一个 11 行 Python 代码实现的神经网络

    一个 11 行 Python 代码实现的神经网络 2015/12/02 · 实践项目 · 15 评论· 神经网络 分享到:18 本文由 伯乐在线 - 耶鲁怕冷 翻译,Namco 校稿.未经许可,禁止转 ...

  6. 200行Python代码实现2048

    200行Python代码实现2048 一.实验说明 1. 环境登录 无需密码自动登录,系统用户名shiyanlou 2. 环境介绍 本实验环境采用带桌面的Ubuntu Linux环境,实验中会用到桌面 ...

  7. 40多行python代码开发一个区块链。

    40多行python代码开发一个区块链?可信吗?我们将通过Python 2动手开发实现一个迷你区块链来帮你真正理解区块链技术的核心原理.python开发区块链的源代码保存在Github. 尽管有人认为 ...

  8. [Swift]LeetCode966.元音拼写检查器 | Vowel Spellchecker

    Given a wordlist, we want to implement a spellchecker that converts a query word into a correct word ...

  9. 30行Python代码实现人脸检测

    参考OpenCV自带的例子,30行Python代码实现人脸检测,不得不说,Python这个语言的优势太明显了,几乎把所有复杂的细节都屏蔽了,虽然效率较差,不过在调用OpenCV的模块时,因为模块都是C ...

随机推荐

  1. json对象数组按对象属性排序

    var array = [ {name: 'a', phone: 1, value: 'val_4'}, {name: 'b', phone: 5, value: 'val_3'}, {name: ' ...

  2. UI基础之UIButton相关

    UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom]; 1.按钮透明效果 btn.alpha = 0.8; 2.按钮圆角处理 btn ...

  3. JavaScript基础系列(变量与类型)

    以下内容将JavaScript简称为JS 打开本文时不管你是零基础的初学者还是其他语言的老兵,我都想说程序语言的基础支撑起了整个网络世界,不把这些基础学透之后稍复杂的内容会让你寸步难行. 现在先给编程 ...

  4. hdu 5773 The All-purpose Zero 最长上升子序列+树状数组

    题目链接:hdu 5773 The All-purpose Zero 官方题解:0可以转化成任意整数,包括负数,显然求LIS时尽量把0都放进去必定是正确的. 因此我们可以把0拿出来,对剩下的做O(nl ...

  5. 指针数组vs数组指针 指针函数vs函数指针

    在分辨这些重要的概念时,我们先回顾一下前面所讲的C之三值合一,由于三个值所求出的地址是相同的,所以经常有传言说他们都是首元素的地址.这种说法是不正确的.为什么说它是不正确的呢? 首先定义一个指针,将三 ...

  6. 【翻译自mos文章】当指定asm disk 为FRA时,11.2.0.3的dbua hang住

    当指定asm disk 为FRA时.11.2.0.3的dbua hang住 来源于: 11.2.0.3 DBUA Hangs While Specifying ASM Disk To FRA (文档 ...

  7. [TroubleShooting] The server network address can not be reached or does not exist

    Backtround: I'm trying to set up mirroring between two sql 2008 R2 databases on different servers in ...

  8. APACHE启动失败是SYSTEM对apache目录没权限导致

    表现如下: Apache: 1.The Apache service named reported the following error:>>> (OS 5)拒绝访问. : htt ...

  9. Linux终端、控制台复制粘贴

    1. 在终端下:          复制命令:Ctrl + Shift + C  组合键.          粘贴命令:Ctrl + Shift + V  组合键.  2. 在控制台下:        ...

  10. js双向绑定和地址传递带来的痛苦解决方案之对象拷贝

    function cloneObj(obj) { var newObj = {}; if (obj instanceof Array) { newObj = []; } for (var key in ...