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

作者:lxydo 时间:2023-10-11 03:33:03 

引入

大家在使用谷歌或者百度搜索时,输入搜索内容时,谷歌总是能提供非常好的拼写检查,比如你输入 speling,谷歌会马上返回 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作为我们的样本数据。

背后原理

上面的代码是基于贝叶斯来实现的,事实上谷歌百度实现的拼写检查也是通过贝叶斯实现,不过肯定比这个复杂多了。
首先简单介绍一下背后的原理,如果读者之前了解过了,可以跳过这段。
给一个词,我们试图选取一个最可能的正确的的拼写建议(建议也可能就是输入的单词)。有时也不清楚(比如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,拼写,检查器
0
投稿

猜你喜欢

  • div中class与id的区别及应用

    2007-09-22 08:37:00
  • 实例解析Python的Twisted框架中Deferred对象的用法

    2024-01-01 23:38:23
  • 非集成环境的php运行环境(Apache配置、Mysql)搭建安装图文教程

    2023-07-21 16:21:41
  • 微信小程序下拉加载和上拉刷新两种实现方法详解

    2024-04-23 09:30:52
  • ajax实现Dig程序中的投票

    2008-01-22 17:27:00
  • Python判断对象是否相等及eq函数的讲解

    2022-04-13 03:15:22
  • pycharm 无法加载文件activate.ps1的原因分析及解决方法

    2022-07-11 01:00:49
  • Discuz!NT 论坛整合ASP程序论坛教程

    2011-03-31 11:09:00
  • 10 个Python中Pip的使用技巧分享

    2023-08-02 17:52:45
  • sqlserver 2000 远程连接 服务器的解决方案

    2024-01-24 03:23:12
  • python tkinter组件摆放方式详解

    2021-09-23 01:50:23
  • Vue前端后端的交互方式 axios

    2024-05-21 10:28:58
  • 网页设计标准尺寸参考

    2007-12-29 20:42:00
  • PHP开发实现快递查询功能详解

    2023-11-24 12:19:39
  • 在python中画正态分布图像的实例

    2021-04-13 01:42:23
  • 详解python中的数据类型和控制流

    2022-08-11 14:32:50
  • 浅析python的优势和不足之处

    2021-06-11 02:33:20
  • Python Matplotlib库安装与基本作图示例

    2021-09-01 04:22:51
  • 小白讲座:在win下mysql备份恢复命令概括

    2009-09-05 09:43:00
  • python适合人工智能的理由和优势

    2021-08-10 11:01:12
  • asp之家 网络编程 m.aspxhome.com