当前位置:   article > 正文

朴素贝叶斯拼写检查

朴素贝叶斯拼写检查

使用每个词作为特征并观察它们是否出现,这样得到的特征数目会有多少呢?针对的是哪一种人类语言呢?当然不止一种语言。据估计,仅在英语中,单词的总数就有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]))

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
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"))

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/347807
推荐阅读
相关标签
  

闽ICP备14008679号