实战 | 单词拼写纠正器python实现
2017-12-14 00:00
197 查看
1 如用户输入了 hella,纠正后发现的3个最有可能的输入如下:'want to input: hello', 'hell', 'fella'2 如用户输入了appropreate,纠正器纠正后:'want to input: appropriate'3 如用户输入了owesomes,纠正器纠正后:'want to input: awesome'4 如用户输入了grduallyare,纠正器纠正后:
grduallyare not found in dictionary!
以上是纠正器能实现的纠正实例,那么该如何实现这么一个单词拼写错误检查和纠正的工具呢。
如果用户实际输入的单词为 w(word的简写), 然后拼写纠正器猜测用户实际想输入的单词为 c1, c2 , c3 , ....... 因此,我们可以猜测用户输入了 P(c1 | w) ,P(c2 | w),P(c3 | w)等等这些多种猜测。如果发现P(c1 | w) 的概率最大,那么用户很有可能想输入的那个单词为 c1 。这个概率可以统一表示为:P(c | w) 如何求解这个概率的最大值?
将以上概率做如下转化来求解:用户想输入的很可能在语料库的这个 c 时,有可能被错误的输入为了 w1,w2,w3 ,...... 则这个概率可以统一表示为:P(w | c) 用户错误地输入成 w1,w2,w3,......,它们之间是相互独立的,因此可以根据朴素贝叶斯分类器的理论,进一步将后验概率 P(c | w) 的求解转化为求解如下的目标函数:max ( P(c) * P(w | c) / P(w) ) 上式中 P(c)为先验概率,下载一个比较丰富的单词拼写都正确的英文单词库后,统计下每个单词出现的频次,就是单词 c 的出现的概率;P(w) 是与问题分类无关的量,因为用户有可能输入任意一个单词;P(w | c) 是一个类条件概率:用户想输入c(c在语料库中是有对应的,在此处需要注意:我们取的语料库不能100%保证一定存在任意一个正确的单词,所以在统计的过程中,假定单词至少出现1次),但是被错误地输入为了 wi 的概率。
P(w | c) 的求解方法通常会有很多种,比如用户想输入hello,但是实际输入了 hella,它们之间的区别仅仅是最后一个字符输入错误,这个出现的概率还是挺大的吧;但是,再看看下面这个例子。
如果用户想输入awesome, 但是实际输入成了owesomes,输错了1个字符,多添加了 1个字符,这种情况发生的概率就比上面那种小一些吧。
因此,在本文中设计的纠正器没有直接去量化 P(w | c) 这个概率,而是采取了从定性上进行分析,通常经过一步调整出现的概率大于经过两步调整出现的概率。所以,当纠正器遇到一个待纠正的词语时,它会纠正一步,如果发现了,就直接返回了;否则才会进行两步调整,这种调整的优先级的原理是根据 P(w | c) 。
这样先验概率 P(c) 和类条件概率 P(w | c) 的求解方法就弄明白了,当一步纠正就能在语料库找到对应后,就不会进行两步纠正,但是一步纠正会返回多个,此时再根据P(c)找出这些中的出现频次最多的,这样最终的结果便是猜测到的用户最有可能想输入的单词。
构建先验概率P(c)语料库下载了老友记的1-10部+呼啸山庄全部组成的单词库。import re, collectionsdef tolower(text): return re.findall('[a-z]+',text.lower())
def prior(cwords): model = collections.defaultdict(lambda:1) for f in cwords: model[f]+=1 return model
ipath = './bigword.txt'uipath = ipath.encode("utf8")htxt = open(uipath,'r',errors ='ignore')cwords = tolower(htxt.read())#get P(c)nwords = train(cwords) nwords
类条件概率
alpha = 'abcdefghijklmnopqrstuvwxyz'#一步调整def version1(word): n = len(word) add_a_char = [word[0:i] + c + word[i:] for i in range(n+1) for c in alpha] delete_a_char = [word[0:i] + word[i+1:] for i in range(n)] revise_a_char = [word[0:i] + c + word[i+1:] for i in range(n) for c in alpha] swap_adjacent_two_chars = [word[0:i] + word[i+1]+ word[i]+ word[i+2:] for i in range(n-1)] return set( add_a_char + delete_a_char + revise_a_char + swap_adjacent_two_chars)#两步调整 def version2(word): return set(e2 for e1 in edits1(word) for e2 in edits1(e1))
朴素贝叶斯分类器
def identify(words): return set(w for w in words if w in nwords)
def getMax(wanteds): threewanteds=[] maxword = max(wanteds,key=lambda w : nwords[w]) threewanteds.append('want to input: '+ maxword) wanteds.remove(maxword) if len(wanteds)>0: maxword = max(wanteds,key=lambda w : nwords[w]) threewanteds.append(maxword) wanteds.remove(maxword) if len(wanteds)>0: maxword = max(wanteds,key=lambda w : nwords[w]) threewanteds.append(maxword) return threewanteds
def bayesClassifier(word): #如果字典中有输入的单词,直接返回 if identify([word]): return 'found: '+ word #一步调整 wanteds = identify(version1(word)) if len(wanteds)>0: return getMax(wanteds) #两步调整 wanteds = identify(version2(word)) if len(wanteds)>0: return getMax(wanteds) #不再修正,直接提示这个单词不在当前的词典中 else: return [word + ' not found in dictionary!' ]
测试1 :
测试2 :
测试3 :
测试4 :
感谢伙伴公众号“算法channel”供稿。投稿请在本公众号后台回复 “投稿”。
相关文章推荐
- Python实现单词拼写检查
- 机器学习实战笔记(Python实现)-06-AdaBoost
- 机器学习实战笔记(Python实现)-01-机器学习实战
- Python实现计算一段文本中每个单词出现的次数
- Python实现单词查询&文件查找
- appium之基于Python实现自动化测试实战(Android)
- 21行python代码实现拼写检查器
- 21行Python代码实现拼写检查器
- Python数据分析与机器学习-贝叶斯实现拼写检查器
- python实战===实现读取txt每一行的操作,账号密码
- python3 实现统计单词表中每个字母的出现频率
- python实现单词计数的mapreduce
- python实现指定目录下JAVA文件单词计数的多进程版本
- 机器学习实战笔记(四):Logist线性回归算法的Python实现
- Python 1行代码实现文本分类(实战笔记),含代码详细说明及运行结果
- 超具实战意义的Python项目课程:四周实现爬虫系统 超经典的Python零基础实战化教程
- python实现找出所有包含元音aeiou且只有先后顺序为aeiou的单词
- py单词翻译小工具(python抓取html实现)
- Python实战之KNN实现
- Python机器学习之XGBoost从入门到实战(代码实现)