一个21行Python代码实现拼写检查器的方法

引入

大家在使用谷歌或者百度搜索时,输入搜索内容时,谷歌总是能提供非常好的拼写检查,比如你输入 speling,谷歌会马上返回 spelling
下面是用21行python代码实现的一个简易但是具备完整功能的拼写检查器。

代码

import re, collectionsdef 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 modelNWORDS = 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 modelNWORDS = 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代码实现拼写检查器的方法的详细内容,更多请关注【创想鸟】其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至253000106@qq.com举报,一经查实,本站将立刻删除。

发布者:PHP中文网,转转请注明出处:https://www.chuangxiangniao.com/p/2276295.html

(0)
上一篇 2025年2月27日 15:06:08
下一篇 2025年2月23日 18:11:47

AD推荐 黄金广告位招租... 更多推荐

相关推荐

  • 17个Python奇技淫巧分享

    显示有限的接口到外部 当发布python第三方package时,并不希望代码中所有的函数或者class可以被外部import,在init.py中添加all属性,该list中填写可以import的类或者函数名, 可以起到限制的import的作…

    2025年2月27日
    200
  • python学习进阶之socket详细介绍

    Socket的英文原义是“孔”或“插座”。作为BSD UNIX的进程通信机制,通常也称作”套接字”,用于描述IP地址和端口,是一个通信链的句柄,可以用来实现不同虚拟机或不同计算机之间的通信。 网络上的两个程序通过一个…

    编程技术 2025年2月27日
    200
  • 关于python的super()的作用和原理详细介绍

    Python中对象方法的定义很怪异,第一个参数一般都命名为self(相当于其它语言的this),用于传递对象本身,而在调用的时候则不必显式传递,系统会自动传递。 今天我们介绍的主角是super(), 在类的继承里面super()非常常用, …

    编程技术 2025年2月27日
    200
  • 如何在Python中添加自定义模块

    一般来说,我们会将自己写的python模块与python自带的模块分开存放以达到便于维护的目的。那么如何在python中添加自定义的模块呢? 在解答这个问题之前,我们首先要明确两点: 1.严格区分包(package)和文件夹。包的定义就是包…

    编程技术 2025年2月27日
    200
  • 详解Python判断上传文件类型

    在开发上传服务时,经常需要对上传的文件进行过滤。 本文为大家提供了python通过文件头判断文件类型的方法,非常实用。 代码如下 import struct # 支持文件类型 # 用16进制字符串的目的是可以知道文件头是多少字节 # 各种文…

    编程技术 2025年2月27日
    200
  • 详解Python使用signal模块实现定时执行方法

    在liunx系统中要想每隔一分钟执行一个命令,最普遍的方法就是crontab了,如果不想使用crontab,经同事指点在程序中可以用定时器实现这种功能,于是就开始摸索了,发现需要一些信号的知识… 查看你的linux支持哪些信号:…

    编程技术 2025年2月27日
    200
  • 详解python读取与写入csv格式文件方法

    python读取与写入csv格式文件 在数据分析中经常需要从csv格式的文件中存取数据以及将数据写书到csv文件中。将csv文件中的数据直接读取为dict类型和dataframe是非常方便也很省事的一种做法,以下代码以鸢尾花数据为例。 cs…

    编程技术 2025年2月27日
    200
  • 解析Python常用的机器学习库

    python在科学计算中用途广泛:计算机视觉、人工智能、数学、天文等。它同样适用于机器学习也是意料之中的事。 这篇文章就列举并描述Python的最有用的机器学习工具和库。这个列表中,我们不要求这些库是用Python写的,只要有Python接…

    编程技术 2025年2月27日
    200
  • Python开发WEB框架Flask详细介绍

    flask简介 Flask是一个相对于Django而言轻量级的Web框架。 和Django大包大揽不同,Flask建立于一系列的开源软件包之上,这其中 最主要的是WSGI应用开发库Werkzeug和模板引擎Jinja: 策略 :werkze…

    2025年2月27日 编程技术
    200
  • Python字符串的基础知识详细介绍

    在python中最重要的数据类型包括字符串、列表、元组和字典等。本篇文章主要讲述python的字符串基础知识。下面跟着小编一起来看下吧 一.字符串基础 字符串指一有序的字符序列集合,用单引号、双引号、三重(单双均可)引号引起来.如: s1=…

    编程技术 2025年2月27日
    200

发表回复

登录后才能评论