小專案--貝葉斯實現拼寫檢查
阿新 • • 發佈:2018-11-04
求解:argmaxc P(c|w) -> argmaxc P(w|c)P©/P(w)
P©:文章中出現一個正確拼寫詞c的概率,也就是語料庫中c出現的概率有多大
P(w|c):在使用者想鍵入c的情況下敲成w的概率,也就是使用者會以多大的概率把c敲錯成w
argmaxc:用來列舉所有可能的c並且選取概率最大的
import re #正則表示式 from collections import defaultdict # #定義一個函式將文字中所有的單詞抽取出來,轉換成小寫並去除特殊字元 def words(text): return re.findall("[a-z]+",text.lower()) #定義詞頻函式 def wordsFrequency(word): #定義一個字典 model = defaultdict(lambda:1) #定義一個字典預設值為1,因為當我們遇到沒有見過的新詞,因為語料庫沒有這個詞則返回的概率為0 #就是表示不能發生事件,而在我們的概率模型中我們期望用一個很小的概率代替這種情況,所以初始的詞頻都為1 print(type(model)) #<class 'collections.defaultdict'> for w in word: model[w] += 1 #如果語料庫出現了這個詞則加一 return model nwords = wordsFrequency(words(open(r'big.txt').read())) #print(nwords) alphabet = "abcdefghijklmnopqrstuvwxyz" #print(len(alphabet)) #編輯距離 #兩個詞之間的編輯距離定義為使用了幾次插入(插入一個單字母)、刪除、交換、替換的操作從一個詞變到另一個詞 def edits1(word): #返回所有與單詞w編輯距離為1(做一次操作)的集合 n = len(word) #刪除、交換、替換、插入 return set([word[0:i]+word[i+1:] for i in range(n)] + [word[0:i]+word[i+1]+word[i]+word[i+2:] for i in range(n-1)] + [word[0:i]+c+word[i+1:] for i in range(n) for c in alphabet] + [word[0:i]+c+word[i:] for i in range(n) for c in alphabet]) #與something編輯距離為2(做兩個操作,如替換兩個字母)的單詞居然達到了114324個 def edits2(word): #編輯距離為2的集合 return set(e2 for e1 in edits1(word) for e2 in edits1(e1)) #按照編輯距離來算資料量太大,我們需要優化,只返回在語料庫中出現的的詞"smoothing","something","soothing" 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=lambda w:nwords[w]) correctword = correct("morw") print(correctword) #more