这篇文章的初始是源于一篇基于朴素贝叶斯进行拼写检查的文章,我做了这个文章,同时写了一些自己的感悟在里面。
文章请见:怎样写一个拼写检查器。http://blog.youxu.info/spell-correct.html
问题:拼写错误这个例子就我们在百度谷歌搜索时,打错了某个单词,会发现搜索引擎能够自动识别拼写错误,显示正确单词?
解决:如何做呢?可以根据简单的统计和朴素贝叶斯公式去计算得到。
首先看贝叶斯公式,规定我们真正想打的单词事件为p(想打c),我们实际出来的单词事件为p(实际打w)
对于想打c,却打出w这种事件的贝叶斯等式: p(想打c|实际打w)*p(实际打w)=p(实际打w|想打c)*p(想打c),
其中
化简
p(想打c|实际打w)
= p(实际打w|想打c)*p(想打c)/p(实际打w)
= p(实际打w|想打c)*p(想打c)
现在我们面临了两个项:
1) p(想打c)这个先验概率如何算呢? 这个可以理解我,某个人闲着没事随便打些话,某个单词的概率,这个和我们的使用习惯有关,从大众来看,通过一本小说啊可以大概算出来各个单词出现的频率的
那么我们如何获取数据集,计算各个单词出现频率呢?
import re, collections #re是正则式模块,用于文本数据集处理;collections是字典模块,生成一种特殊字典 def words(text): return re.findall('[a-z]+', text.lower()) #查找所有单词,变成小写 def train(features): model = collections.defaultdict(lambda: 1) #生成特殊字典,key可以动态增加,且所有value默认值为1 for f in features: model[f] += 1 return model NWORDS = train(words(file('big.txt').read())) #将文本集处理为单词的dictionary,也就是做wordcount
alphabet = 'abcdefghijklmnopqrstuvwxyz' #一个字母表 def edits1(word): #将word打错一个字的情况 s = [ (word[:i], word[i:]) for i in range(len(word) + 1) ] #将word半劈,一般a,一般b deletes = [a + b[1:] for a, b in s if b] #缺 transposes = [a + b[1] + b[0] + b[2:] for a, b in s if len(b)>1] #调换1个字母 replaces = [a + c + b[1:] for a, b in s for c in alphabet if b] #替换1个字母 inserts = [a + c + b for a, b in s for c in alphabet] #插入1个字母 return set(deletes + transposes + replaces + inserts) def known_edits2(word): #错2个字母,就是在edits1()函数基础上嵌套一层 return set(e2 for e1 in edits1(word) for e2 in edits1(e1) if e2 in NWORDS)
</pre><p><pre name="code" class="python">def correct(word): candidates = known([word]) or known(edits1(word)) or known_edits2(word) or [word] return max(candidates, key=lambda w: NWORDS[w]) #拼写分为四种情况:完全正确,错1,错2,词典没这个词,通过or匹配了之前的就无法匹配后面了,我们可以按顺序从中得到其中一种情况的集合 # 同一集合再根据文本数据集出现频率的高低进行筛选也就是max()函数的作用