zoukankan      html  css  js  c++  java
  • (含部分转载)贝叶斯推断应用之英文单词纠错

    本文参考资料来自:

    程序源码作者及来源:http://norvig.com/spell-correct.html

    中文翻译版:http://www.ruanyifeng.com/blog/2012/10/spelling_corrector.html

    这段程序比较有意思,可以实现英文单词的纠错,实现的思想也非常简单,但效果却比较不错

    举例,譬如用户想输入单词somebody,但却误输入成somebady,程序就可以帮你就纠正出来

    使用方法为 correction('你所输入的单词')

    就个人看来,程序有些可以改进的地方,比如提供单词库更大的文件(作者所提供的big.txt含有32198个单词),

    或者直接使用纯词典式的单词库;提供给用户更多的选项,而不仅仅是一个;算法的部分还可以进一步改进。

    程序主要思路:

    第一步,建立一个足够大的文本库。

    网上有一些免费来源,比如古登堡计划Wiktionary英国国家语料库等等。

    第二步,取出文本库的每一个单词,统计它们的出现频率。

    第三步,根据用户输入的单词,得到其所有可能的拼写相近的形式。

    所谓"拼写相近",指的是两个单词之间的"编辑距离"(edit distance)不超过2。也就是说,两个词只相差1到2个字母,只通过----删除、交换、更改和插入----这四种操作中的一种,就可以让一个词变成另一个词。

    第四步,比较所有拼写相近的词在文本库的出现频率。频率最高的那个词,就是正确的拼法。

    根据Peter Norvig(原作者)的验证,这种算法的精确度大约为60%-70%(10个拼写错误能够检查出6个。)虽然不令人满意,但是能够接受。毕竟它足够简单,计算速度极快。(本文的最后部分,将详细讨论这种算法的缺陷在哪里。)

    当然程序也不是万能的:

    (1)文本库必须有很高的精确性,不能包含拼写错误的词。

    如果用户输入一个错误的拼法,文本库恰好包含了这种拼法,它就会被当成正确的拼法。

    (2)对于不包含在文本库中的新词,没有提出解决办法。

    如果用户输入一个新词,这个词不在文本库之中,就会被当作错误的拼写进行纠正。

    (3)程序返回的是"编辑距离"为1的词,但某些情况下,正确的词的"编辑距离"为2。

    比如,用户输入reciet,会被纠正为recite(编辑距离为1),但用户真正想要输入的词是receipt(编辑距离为2)。也就是说,"编辑距离"越短越正确的规则,并非所有情况下都成立。

    (4)有些常见拼写错误的"编辑距离"大于2。

    这样的错误,程序无法发现。下面就是一些例子,每一行前面那个词是正确的拼法,后面那个则是常见的错误拼法。

    purple perpul
    curtains courtens
    minutes muinets
    successful sucssuful
    inefficient ineffiect
    availability avaiblity
    dissension desention
    unnecessarily unessasarily
    necessary nessasary
    unnecessary unessessay
    night nite
    assessing accesing
    necessitates nessisitates

    (5)用户输入的词的拼写正确,但是其实想输入的是另一个词。

    比如,用户输入是where,这个词拼写正确,程序不会纠正。但是,用户真正想输入的其实是were,不小心多打了一个h。

    (6)程序返回的是出现频率最高的词,但用户真正想输入的是另一个词。

    比如,用户输入ther,程序会返回the,因为它的出现频率最高。但是,用户真正想输入的其实是their,少打了一个i。也就是说,出现频率最高的词,不一定就是用户想输入的词。

    (7)某些词有不同的拼法,程序无法辨别。

    比如,英国英语和美国英语的拼法不一致。英国用户输入'humur',应该被纠正为'humour';美国用户输入'humur',应该被纠正为'humor'。但是,我们的程序会统一纠正为'humor'。

    关于算法思想的介绍可以参见以上的中文翻译版以及原版

    附上原作者提供的big.txt(为福尔摩斯探案集)地址:http://norvig.com/big.txt

    以下为源码:

    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))
    
  • 相关阅读:
    警告:ORA-00600 2252 错误正在SCN问题下不断爆发(转)
    Linux批量清除木马文件photo.scr
    500 OOPS: vsftpd: refusing to run with writable root inside chroot() Login failed. 421 Service not available, remote server has closed connection
    Linux后门入侵检测工具(转)
    解决Docker无法删除镜像
    通过DataX从Oracle同步数据到MySQL-安装配置过程
    Server2008 R2安装、配置Freesshd(Jenkins持续集成-Windows)
    Mysql死锁解决办法
    Mssql 2017修改master默认排序规则
    可能需要用到的Mac技巧or软件
  • 原文地址:https://www.cnblogs.com/lomooo/p/6358279.html
Copyright © 2011-2022 走看看