源碼請到:自然語言處理練習: 學習自然語言處理時候寫的一些代碼 (gitee.com) 數據來源:norvig.com/big.txt 貝葉斯原理可看這裡:機器學習演算法學習筆記 - 過客匆匆,沉沉浮浮 - 博客園 (cnblogs.com) 一、數據預處理 將輸入的數據全部變為小寫方便後續處理 de ...
源碼請到:自然語言處理練習: 學習自然語言處理時候寫的一些代碼 (gitee.com)
數據來源:norvig.com/big.txt
貝葉斯原理可看這裡:機器學習演算法學習筆記 - 過客匆匆,沉沉浮浮 - 博客園 (cnblogs.com)
一、數據預處理
將輸入的數據全部變為小寫方便後續處理
def words(text): return re.findall('[a-z]+', text.lower())
二、根據語料庫統計不同單詞出現的詞頻
單詞字典每個單詞詞頻預設為1,因為如果單詞字典預設值為為0,那麼出現了語料庫中沒有的單詞,就會預設概率為0,導致新的單詞無法被識別
def train(features): model = collections.defaultdict(lambda: 1) # 如果預設為0則出現語料庫中沒有的新詞會不識別,所以預設為1 for f in features: model[f] += 1 return model
三、打開語料庫與構建字母表
NWORDS = train(words(open('data/big.txt').read())) alphabet = 'abcdefghijklmnopqrstuvwxyz'
四、返回編輯距離為1的單詞
單詞a經過n次修改可以得到新的單詞b,那我們叫b為a的編輯距離為1的單詞,下麵函數就返回編輯距離為1的單詞
# 返回編輯距離為1的單詞 def editsl(word): 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 + 1) for c in alphabet]) # 字母打少了一個
五、返回編輯距離為2的單詞
# 考慮編輯距離為2的單詞 def known_edits2(word): return set(e2 for e1 in editsl(word) for e2 in editsl(e1) if e2 in NWORDS)
六、判斷單詞是否在語料庫中
def known(words): return set(w for w in words if w in NWORDS)
七、糾正拼寫錯誤的單詞
優先考慮原單詞a是否在語料庫中,如果存在就返回原單詞,不存在就考慮編輯距離為1的單詞,返回使用頻率最高的那個如果編輯距離為1的單詞也不在語料庫中,那麼就考慮編輯距離為2的單詞,同樣,如果編輯距離為2的單詞都不在語料庫中,那麼這可能是一個新的單詞,直接返回單詞本身
def correct(word): candidates = known([word]) or known(editsl(word)) or known_edits2(word) or [word] return max(candidates, key=lambda w: NWORDS[w])
八、測試結果
print(correct('appl')) print(correct('appla')) print(correct('learw')) print(correct('tess')) print(correct('morw'))