• 基贝叶斯后验概率的拼写检查器实现 python


    首先,我们从头开始说起。相信大家都学习过概率与数理统计这门课程,其中有一个贝叶斯公式,如下:

    clip_image002

    也就是条件概率公式。可以由下面的式子推得:

    clip_image004

    即,A与B同时发生的概率等于,B发生的概率乘以,在B发生的条件下A发生的概率。

    好了,前面引出这个公式,就是为了解决我们的拼写检查器的问题。既然是检查器,就得把我们写错的词给改正确。怎么改呢?我们仔细来分析一下这个过程:

    1. 首先,我们有一个词典,里面全包含的是正确的词。

    2. 输入一个词,若这个词在词典里面有,其本身为正确,不需要改;若这个词是错误的,问题一:我们应该把它改成哪个词呢?

    看下面的公式,

    clip_image002[1]

    在我们输入的word是Wrong的情况下,我们要把他改成正确的词,哪个正确的词的概率高,我们就把他改成哪个词。即clip_image007最大的那个词clip_image009。假设你有一个备选正确词的集合set,你需要的就是计算set中每个词的clip_image007[1]

    问题二:怎么样确定备选正确词的集合set?

    我们假定,错误词的产生是由下列几种情况产生:

    1. 漏了一个字母,如你输入china,输成了chna

    2. 两个相邻字母换位了,如chnia

    3. 输错了一个字母,如chjna

    4. 插入了一个字母,如 chijna

    以上这四种操作,我们称之为china的一步变换。

    那么反过来,如果我们输入了chijna,我们会得到一个由以上四种操作得到的另外的词,我们把这个集合作为备选正确词集合set

    问题三:怎么样计算clip_image007[2]呢?

    这里我们来分析,首先,clip_image011对于set中的每个词都是一样的,因为每个词都是由wrong word经过一步变换得来,所以clip_image013都相等。那么只剩下clip_image015了,这个由我们去统计获得,哪些正确的词在我们的训练文本集中出现的概率高。

    至此,问题已经全部分析完。下面python代码实现,其实在代码中,他使用了一次变换和二次变换所得到的词作为备选set。

     1 #-*- coding:utf-8 -*-
     2 import re, collections
     3 def words(text): return re.findall('[a-z]+', text.lower())
     4 
     5 #返回值是一个dict
     6 def train(features):
     7     #model是一个字典
     8     model = collections.defaultdict(lambda: 0)
     9     for f in features:
    10         model[f] += 1
    11     return model
    12 
    13 NWORDS = train(words(file("big.txt").read()))
    14 alphabet = 'abcdefghijklmnopqrstuvwxyz'
    15 
    16 #word is string
    17 def edits1(word):
    18     splits = [(word[: i], word[i: ]) for i in range(len(word) + 1)]
    19     deletes = [ a + b[1: ] for a, b in splits if b]
    20     transposes = [a + b[1] + b[0] + b[2:] for a, b in splits if len(b) > 1]
    21     replaces = [a + c + b[1:] for a,b in splits for c in alphabet if b]
    22     inserts = [a + c + b for a,b in splits for c in alphabet]
    23     return set(deletes + transposes + replaces + inserts)
    24 
    25 def know_edits2(word):
    26     return set(e2 for e1 in edits1(word) for e2 in edits1(e1) if e2 in NWORDS)
    27 
    28 def known(words):
    29     return set(w for w in words if w in NWORDS)
    30 
    31 def correct(word):
    32     candidates = known([word]) or known(edits1(word)) or know_edits2(word) or [word]
    33     return max(candidates, key = lambda w: NWORDS[w])
    34 
    35 print correct('hte')
    36 print correct('babyu')
    37     

    语料库下载 :big.txt

    参考:http://www.oschina.net/code/snippet_218146_14045

    严重推荐:http://norvig.com/spell-correct.html

     

     

  • 相关阅读:
    paramiko操作详解(封装好的类,可以直接使用)
    更换mysql数据目录后出现 ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2) 的解决办法
    mysql5.1的编译安装 ----针对第一次安装mysql的
    mysql错误-修改mysql.sock位置
    python打印进度条
    php 中_set()_get()实例解析
    php 中PHP_EOL使用
    转载自php 大牛的学习计划 人生规划
    jquery下 选择器整理
    linux 下 重启apache
  • 原文地址:https://www.cnblogs.com/hengli/p/2732886.html
Copyright © 2020-2023  润新知