引入

大家在使用谷歌或者百度搜索时,输入搜索内容时,谷歌总是能提供很好的拼写检查,比方你输入 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. NHibernate3.2学习笔记-几种查询方式

    一.开发环境 数据库:SQLServer2008 编译器:VS2010 .Net版本:.Net Framework 4.0 二.开发过程 1.项目结构 承接上一篇 2.执行sql语句 (1)基本语法 ...

  2. jQuery学习笔记(4)-设置元素的属性和样式

    一.前言 本篇主要讲解如何使用jQuery获取和操作元素的属性和css样式 二."DOM属性"与元素属性 1.运行一下代码 <img src="/images/lo ...

  3. 通过重写.htaccess文件添加404

    如果说是用linux服务器的系统 想要给自己的网站设置404怎么弄?如果你不会给自己的Ecs服务器添加服务器管理系统,或是你购买的云虚拟主机没有304.404设置,那么就要通过自己重写文件来设置404 ...

  4. Web性能测试术语

    并发用户: 并发一般分为2种情况.一种是严格意义上的并发,即所有的用户在同一时刻做同一件事情或者操作,这种操作一般指做同一类型的业务.比如在信用卡审批业 务中,一定数目的用户在同一时刻对已经完成的审批 ...

  5. iOS中ARC和非ARC混用

    如果在使用第三方类库的时候,我们可能会遇到一些内存管理的问题   那么如何在一个工程中实现ARC和非ARC混用呢,例如你创建一个ARC的工程,但是你引用的第三方类库是非ARC管理内存的   首先点击工 ...

  6. 【译】x86程序员手册27-7.6任务链

    7.6 Task Linking 任务链 The back-link field of the TSS and the NT (nested task) bit of the flag word to ...

  7. Ps 快捷键全解

    一.工具箱(多种工具共用一个快捷键的可同时按[Shift]加此快捷键选取)矩形.椭圆选框工具 [M]移动工具 [V]套索.多边形套索.磁性套索 [L]魔棒工具 [W]裁剪工具 [C]切片工具.切片选择 ...

  8. tomcat 访问IP直接访问项目

    apache-tomcat-7.0.52\conf下server.xml文件 <Connector connectionTimeout="20000" port=" ...

  9. HDU_1242_Rescue

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=1242 大意:迷宫搜索,'#'代表墙,'.'代表路,'x'代表守卫,每移动1格用1秒,杀死守卫用1秒,ang ...

  10. 【OptiX】第5个示例 递归反射、抗锯齿

    运行结果如下: [抗锯齿] 可以看到中间那个竖线的右侧从地面上看有款明显的锯齿,而左边就没有.包括球的反射出来的三角形和地面也有明显的锯齿.那么抗锯齿究竟本例中是怎么做的呢? 首先在采样时,当场景需要 ...