分享一个很优秀且简短的自动化拼写检查器,用Python来完成的,个人觉得挺好玩的,也很有趣。
当然,不是由我来搞定的,是来自谷歌Norvig大神的杰作
当我们使用谷歌搜索内容的时候,如果你拼错一个单词,网页会提醒你可能的正确拼法,这就是所谓的"拼写检查"(spelling corrector)。谷歌使用的是基于贝叶斯推断的统计学方法。这种方法的特点就是快,很短的时间内处理大量文本,并且有很高的精确度(90%以上)。
效果大概是下面这个样子:
当用户输入一个单词的时候,分为了两种情况:
- 拼写正确,记为 (correct)
- 拼写错误,记为 (wrong)
所谓的"拼写检查",从概率论的角度看,就是已知 ,然后在若干个备选方案中,找出可能性最大的那个 ,也就是求式(1)的最大值。
根据贝叶斯定理可得:
对于所有的备选项C来说,W都是相同的,因此可以将上式简化为:
所以,实际上可以看成是求式(3)的最大值
的含义是,某个正确的词的出现"概率",它可以用"频率"代替。如果我们有一个足够大的文本库,那么这个文本库中每个单词的出现频率,就相当于它的发生概率。某个词的出现频率越高, 就越大。
的含义是,在试图拼写 的情况下,出现拼写错误 的概率。这需要统计数据的支持,但是为了简化问题,我们假设两个单词在字形上越接近,就有越可能拼错, 就越大。
举例来说,相差一个字母的拼法,就比相差两个字母的拼法,发生概率更高。
例如,如果你想拼写单词 Serendipity,那么错误拼成 Serendipitu(相差一个字母)的可能性,就比拼成 Serendipituu 要高(相差两个字母)。
所以,我们只要找到与输入单词在字形上最相近的那些词,再在其中挑出出现频率最高的一个,就能实现 的最大值。
实现代码如下:
import re
from collections import Counter
def words(text): return re.findall(r'\w+', text.lower())
WORDS = Counter(words(open('big.txt').read()))
def P(word, N=sum(WORDS.values())):
"Probability of `word`."
return WORDS[word] / N
def correction(word):
"Most probable spelling correction for word."
return max(candidates(word), key=P)
def candidates(word):
"Generate possible spelling corrections for word."
return (known([word]) or known(edits1(word)) or known(edits2(word)) or [word])
def known(words):
"The subset of `words` that appear in the dictionary of WORDS."
return set(w for w in words if w in WORDS)
def edits1(word):
"All edits that are one edit away from `word`."
letters = 'abcdefghijklmnopqrstuvwxyz'
splits = [(word[:i], word[i:]) for i in range(len(word) + 1)]
deletes = [L + R[1:] for L, R in splits if R]
transposes = [L + R[1] + R[0] + R[2:] for L, R in splits if len(R)>1]
replaces = [L + c + R[1:] for L, R in splits if R for c in letters]
inserts = [L + c + R for L, R in splits for c in letters]
return set(deletes + transposes + replaces + inserts)
def edits2(word):
"All edits that are two edits away from `word`."
return (e2 for e1 in edits1(word) for e2 in edits1(e1))当然, 工业强度的拼写校正器的完整细节是非常复杂的,不过从这个玩具拼写校正器中,我们也可以学习到一些内容,而且其校正的准确率也是不错的。
更多内容可参考:
How to Write a Spelling Corrector
|