怎样写一个拼写检查器四

取自 自然语言处理百科

跳转到: 导航, 搜索

效果

现在我们看看算法效果怎么样. 在飞机上我尝试了好几个例子, 效果还行. 飞机着陆后, 我从牛津文本档案库 (Oxford Text Archive)下载了 Roger Mitton 的 Birkbeck 拼写错误语料库. 从这个库中, 我取出了两个集合, 作为我要做拼写检查的目标. 第一个集合用来作为在开发中作为参考, 第二个作为最后的结果测试. 也就是说, 我程序完成之前不参考它, 而把程序在其上的测试结果作为最后的效果. 用两个集合一个训练一个对照是一种良好的实践, 至少这样可以避免我通过对特定数据集合进行特殊调整从而自欺欺人. 这里我给出了一个测试的例子和一个运行测试的例子. 实际的完整测试例子和程序可以参见 spell.py.

tests1 = { 'access': 'acess', 'accessing': 'accesing', 'accommodation':
   'accomodation acommodation acomodation', 'account': 'acount', ...}
tests2 = {'forbidden': 'forbiden', 'decisions': 'deciscions descisions',
   'supposedly': 'supposidly', 'embellishing': 'embelishing', ...}
def spelltest(tests, bias=None, verbose=False):
   import time
   n, bad, unknown, start = 0, 0, 0, time.clock()
   if bias:
       for target in tests: NWORDS[target] += bias
   for target,wrongs in tests.items():
       for wrong in wrongs.split():
           n += 1
           w = correct(wrong)
           if w!=target:
               bad += 1
               unknown += (target not in NWORDS)
               if verbose:
                   print '%r => %r (%d); expected %r (%d)' % (
                       wrong, w, NWORDS[w], target, NWORDS[target])
   return dict(bad=bad, n=n, bias=bias, pct=int(100. - 100.*bad/n), 
               unknown=unknown, secs=int(time.clock()-start) )
print spelltest(tests1)
print spelltest(tests2) ## only do this after everything is debugged

这个程序给出了下面的输出:

{'bad': 68, 'bias': None, 'unknown': 15, 'secs': 16, 'pct': 74, 'n': 270}
{'bad': 130, 'bias': None, 'unknown': 43, 'secs': 26, 'pct': 67, 'n': 400}

在270个测试样本上 270 , 我大约能在13秒内得到 74% 的正确率 (每秒17个正确词), 在测试集上, 我得到 67% 正确率 (每秒 15 个).

更新: 在这篇文章的原来版本中, 我把结果错误的报告高了. 原因是程序中一个小bug. 虽然这个 bug 很不起眼, 但我实际上应该能够避免. 我为对阅读我老版本的这篇文章的读者造成感到抱歉. 在 spelltest 源程序的第四行, 我忽略了if bias: 并且把 bias 默认值赋值为0. 我原来想: 如果 bias 是0 , NWORDS[target] += bias 这个语句就不起作用. 而实际上, 虽然这个语句没有改变 NWORDS[target] 的值, 这个却让 (target in NWORDS) 为真. 这样的话, spelltest 就会把训练集合中那些不认识的正确拼写的单词都当成认识来处理了, 程序就会"作弊". 我很喜欢 defaultdict 的简洁, 所以在程序中使用了它, 如果使用 dicts 就不会有这个问题了.

结论: 我达到了简洁, 快速开发和运行速度这三个目标, 不过准确率不算太好.


转自Eric You XU翻译:http://blog.youxu.info/spell-correct.html

原文作者Peter Norvig,原始链接:http://norvig.com/spell-correct.html

个人工具
工具箱