朴素贝叶斯拼写检查

使用每个词作为特征并观察它们是否出现,这样得到的特征数目会有多少呢?针对的是哪一种人类语言呢?当然不止一种语言。据估计,仅在英语中,单词的总数就有500 000①之多。为了能进行英文阅读,估计需要掌握数千单词。

朴素贝叶斯的一般过程
(1) 收集数据:可以使用任何方法。本章使用RSS源。
(2) 准备数据:需要数值型或者布尔型数据。
(3) 分析数据:有大量特征时,绘制特征作用不大,此时使用直方图效果更好。
(4) 训练算法:计算不同的独立特征的条件概率。
(5) 测试算法:计算错误率。
(6) 使用算法:一个常见的朴素贝叶斯应用是文档分类。可以在任意的分类场景中使用朴
素贝叶斯分类器,不一定非要是文本。

假设词汇表中有1000个单词。要得到好的概率分布,就需要足够的数据样本,假定样本数为
N。前面讲到的约会网站示例中有1000个实例,手写识别示例中每个数字有200个样本,而决策树
示例中有24个样本。其中,24个样本有点少,200个样本好一些,而1000个样本就非常好了。约
会网站例子中有三个特征。由统计学知,如果每个特征需要N个样本,那么对于10个特征将需要
N10个样本,对于包含1000个特征的词汇表将需要N1000个样本。可以看到,所需要的样本数会随
着特征数目增大而迅速增长。
如果特征之间相互独立,那么样本数就可以从N1000减少到1000×N。所谓独立(independence)
指的是统计意义上的独立,即一个特征或者单词出现的可能性与它和其他单词相邻没有关系。举
个例子讲,假设单词bacon出现在unhealthy后面与出现在delicious后面的概率相同。当然,我们知
道这种假设并不正确,bacon常常出现在delicious附近,而很少出现在unhealthy附近,这个假设正
是朴素贝叶斯分类器中朴素(naive)一词的含义。朴素贝叶斯分类器中的另一个假设是,每个特征同等重要①。其实这个假设也有问题。 如果要判断留言板的留言是否得当,那么可能不需要看
完所有的1000个单词,而只需要看10~20个特征就足以做出判断了。尽管上述假设存在一些小的
瑕疵,但朴素贝叶斯的实际效果却很好。
到目前为止,你已经了解了足够的知识,可以开始编写代码了。如果还不清楚,那么了解代
码的实际效果会有助于理解。下一节将使用Python来实现朴素贝叶斯分类器,实现中会涉及利用
Python进行文本分类的所有相关内容。

#P(know|knon) = P(knon|know) * P(know)
#P(knob|knon) = P(knon|knob) * P(knob)

#P(?|床前明月光) = P(床前明月光|?)P(?)
#简化,一次编辑距离
#1.统计词频
#2.计算编辑距离

import re
from collections import Counter
import collections


alphabet = 'abcdefghijklmnopqrstuvwxyz'

all_alpha = open("big.txt").read()
#英语分词
words = re.findall('[A-Za-z]+', all_alpha)
#print(words)

#print(Counter(words)){}
#统计词频
count_dict = collections.defaultdict(lambda :1)
for w in words:
    count_dict[w.lower()] += 1


#knon ---> non  kon knn kno
#knon ---->nkon  konn knno #交换距离
#knon ----> kaon kbon kcon............
#knon ---->aknon bknon......kanon kbnon kcnon........
def edit1(word):
    n = len(word)
    delete_distance = [(word[0:i] + word[i+1:]) for i in range(n)]
    switch_distance = [word[0:i] + word[i + 1] + word[i] + word[i + 2:] for i in range(n - 1)]
    alert_distance  = [word[0:i] + c + word[i + 1:] for i in range(4) for c in alphabet]
    insert_distance = [word[0:i]+c+word[i:] for i in range(4) for c in alphabet]
    return set(delete_distance + switch_distance + alert_distance + insert_distance)


candiates = edit1("knon")
correcr_words =  [w for w in candiates if w in count_dict]
print("knon的矫正结果是:",max(candiates,key=lambda x:count_dict[x]))

class SpellCheck(object):
    """
    使用贝叶斯进行错词矫正,假定P(knon|know)是一次编辑距离错误的概率,所有一次编辑距离错误的概率是等价的
    P(know) 该单词在语料库中的词频,由于是同一个语料库,直接比较分子,分子是该单词出现的次数
    #P(know|knon) = P(knon|know) * P(know)
    #P(knob|knon) = P(knob|know) * P(knob)
    """
    def __init__(self, file_name):
        """
        初始还参数
        :param file_name: 语料库文件的名字
        """
        content       = open(file_name).read()
        self.words    = re.findall('[A-Za-z]+',content)
        self.alphabet = 'abcdefghijklmnopqrstuvwxyz'
        self.count_dict = collections.defaultdict(lambda: 1)

    def fit(self):
        """
        训练过程就是统计语料库中各个词的词频
        :return:
        """
        for w in self.words:
            self.count_dict[w.lower()] += 1

    # def edit2(self, words):
    #     return [edit1(w) for w in words]

    def edit1(self,word):
        """
        生成一次编辑距离
        :param word:
        :return:
        """
        n = len(word)
        #一次删除距离
        delete_distance = [(word[0:i] + word[i + 1:]) for i in range(n)]
        #一次交换距离
        switch_distance = [word[0:i] + word[i + 1] + word[i] + word[i + 2:] for i in range(n - 1)]
        #一次修改距离
        alert_distance = [word[0:i] + c + word[i + 1:] for i in range(4) for c in alphabet]
        #一次添加距离
        insert_distance = [word[0:i] + c + word[i:] for i in range(4) for c in alphabet]
        #set去重,返回结果
        return set(delete_distance + switch_distance + alert_distance + insert_distance)

    def known(self,words):
        """
        判断单词是否拼写正确,所谓的正确,及在语料库中存在该单词
        :param words:
        :return:
        """
        return set([w for w in words if w in self.count_dict])

    def predict(self, word):
        """
        对每一个单词进行拼写检查
        :param word: 需要检查的单词
        :return:
        """
        #先检测单词是否拼写正确,如果拼错,检测一次编辑距离,否则返回单词本身
        canditates_spell = self.known([word]) or self.known(self.edit1(word)) or [word]
        print(canditates_spell)
        print(self.count_dict['abc'])
        return max(canditates_spell,key=lambda x:self.count_dict[x])


sp = SpellCheck("big.txt")
sp.fit()

print("sp算法的预测结果是:", sp.predict("knon"))

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值