贝叶斯算法详解

来源:互联网 发布:thumbnails java 编辑:程序博客网 时间:2024/06/03 13:54

在很多应用中,属性集和类变量之间的关系是不确定的。换句话说,尽管测试记录的属性集和某些训练样例相同,但是也不能正确地预测它的类标号。这种情况产生的原因可能是噪声,或者出现了某些影响分类的因素却没有包含在分析中。例如考虑根据一个人的饮食和锻炼的频率来预测他是否有患心脏病的危险。尽管大多数饮食健康、经常锻炼身体的人患心脏病的几率较小,是否充分也是需要论证的课题,这反过来也会给学习问题带来不确定性。

贝叶斯定理
它是一种把类的先验知识从数据中收集的新证据相结合的统计原理;然后解释贝叶斯定理在分类问题中的应用,接下来描述贝叶斯分类器的两种实现:朴素贝叶斯分类器和贝叶斯信念网络。

这里写图片描述

假设学校里面总人数有U个
穿长裤的(男生):U x P(Boy) x P(Pants|Boy)
P(Boy)=60%
P(Pants|Boy)=100%
同理:女生穿长裤的:U x P(Girl) x P(Pants|Girl)
求解:穿长裤中女生的概率

穿长裤总数:U x P(Boy) x P(Pants|Boy)+U x P(Girl) x P(Pants|Girl)
穿长裤中女生概率:
P(Girl|Pants)=U x P(Pants|Girl) x P(Girl)/U x P(Boy) x P(Pants|Boy)+U x P(Girl) x P(Pants|Girl)

可见与总人数没什么关系
分母其实就是穿裤子的概率P(Pants)
分子是女生穿裤子的概率P(Pants|Girl)

可得P(Girl|Pants)=P(Pants|Girl) x P(Girl)/P(Pants)
也就是P(A|B)=P(B|A) x P(A)/P(B)

贝叶斯拼音纠错
P(我们猜测他想输入的单词|他实际输入的单词)
用户实际输入的D(Data,观测数据)
猜测1:P(h1|D) 猜测2:P(h2|D) 猜测3:P(h3|D)….

P(h|D)=P(D|h) x P(h)/P(D)

P(D|h):先验概率表示你想输入的词输错成D的概率
P(D):可以干掉,因为它的意义表示输入了一个任意的单词一切都有可能

P(h|D)∝P(D|h) x P(h)

垃圾邮件过滤
模型比较理论:
最大似然估计:最符合观测数据的(即P(D|h)最大的)最有优势
奥卡姆剃刀:P(h)模型较大的有较大优势
掷一枚硬币,观测到的是“正”,根据最大似然估计的精神,我们应该猜测这枚硬币掷出“正”的概率是1,因为这样才能最大化P(D|h)的猜测

问题:给定一封邮件判定它是否属于垃圾邮件
D来表示这封邮件,注意D由N个单词组成。我们用h+来表示垃圾邮件,h-表示正常邮件
P(h+|D)=P(h+) x P(D|h+)/P(D)
P(h-|D)=P(h-) x P(D|h-)/P(D)
同样的P(D)可以先干掉,因为这个概率没什么价值,有一封邮件存在是客观事实

这里写图片描述

转换成朴素贝叶斯问题:
假设特征之间相互独立没有影响
即d1 d2 d3…之间没有关系
简化为P(d1|h+) x P(d2|h+) x P(d3|h+)……
对于P(d1|h+) x P(d2|h+) x P(d3|h+)……
只要统计di在垃圾邮件中出现的频率就可以了

Python3拼音检查器代码:

import re,collectionsdef train(features):    model = collections.defaultdict(lambda: 1)    for f in features:        model[f] += 1    return modeldef words(text): return re.findall('[a-z]+', text.lower()) def edits1(word):    n = len(word)    return set([word[0:i]+word[i+1:] for i in range(n)] +                     # deletion               [word[0:i]+word[i+1]+word[i]+word[i+2:] for i in range(n-1)] + # transposition               [word[0:i]+c+word[i+1:] for i in range(n) for c in alphabet] + # alteration               [word[0:i]+c+word[i:] for i in range(n+1) for c in alphabet])  # insertiondef known_edits2(word):    return set(e2 for e1 in edits1(word) for e2 in edits1(e1) if e2 in NWORDS)def known(words): return set(w for w in words if w in NWORDS)def correct(word):    candidates = known([word]) or known(edits1(word)) or known_edits2(word) or [word]    return max(candidates, key=lambda w: NWORDS[w])if __name__=='__main__':    NWORDS = train(words(open('big.txt').read()))    alphabet = 'abcdefghijklmnopqrstuvwxyz'    print(correct('morw'))

返回结果:
more

关于lambda表达式,re.findall,reduce()可以查看下面文章
http://blog.csdn.net/imzoer/article/details/8667176
http://www.cnpythoner.com/post/300.html
http://www.cnblogs.com/fengzheng/p/3945932.html

原创粉丝点击