机器学习(6)-贝叶斯算法

来源:互联网 发布:html5app源码 编辑:程序博客网 时间:2024/06/06 12:33

什么是贝叶斯算法

  • 正向概率:假设袋子里有N个白球,M个黑球,那出黑球的概率有多大
  • 逆向改率:假设不知道黑白球的分布,摸出一个或者多个球,观察后推测球的分布
  • 正向概率容易求,而逆向概率却很难求,贝叶斯算法就是把逆向概率转换为正向概率来进行求解
  • 公式 P(A|B)=P(B|A)P(A)P(B)

算法推理

  • 男生占了60%,女生占了40%,男生总是穿长裤,女生则一半穿长裤一半穿裙子
    正向概率:随机选取一个学生,他(她)穿长裤的概率和穿裙子的概率是多大
    逆向概率:迎面走来一个穿长裤的学生,你只看得见他(她)穿的是否长裤,
    而无法确定他(她)的性别,你能够推断出他(她)是女生的概率是多大吗?

  • 假设学校里面人的总数是 U 个

  • 对面穿长裤的是女生的概率P(Girl|Pants)=穿穿
  • 穿长裤的女生 P(Pants|Girl)=U*P(Girl)*P(Pants|Girl)
  • 所以穿长裤的数量=U*P(Pants)
  • 所以P(Girl|Pants)=UP(Girl)P(Pants|Girl)UP(Pants)
  • 约去U等于P(Girl|Pants)=P(Girl)P(Pants|Girl)P(Pants),也就是叶贝斯公式

朴素叶贝斯算法

  • 假设所有的条件都是独立的,这样做虽然和实际情况有些差别,但是可以大量的减少计算量。
  • 垃圾邮件过滤案例
  • 如果词之间不是独立的,那么计算方式就是P(d1|h+) * P(d2|d1, h+) * P(d3|d2,d1, h+) * ..
  • 假设词都是对的,计算方式简化为:P(d1|h+) * P(d2|h+) * P(d3|h+) *…

代码实现 - 拼写纠错

计算公式

  • argmaxc P(c|w)=argmax P(w|c)P(c)/P(w)
  • P(c|w):用户敲成w实际是c的概率
  • P(c):文章中出现该单词的概率
  • P(w|c):用户原本输入c的情况下,敲成w的概率,用距离算法表示
  • argmax:枚举所有可能取最大值
# 获取数据import re # 正则表达式import collections# 转小写后,返回a-z的所有内容def words(text): return re.findall('[a-z]+',text.lower())# 统计词频def train(featrues):    # 获取一个字典,该字典如写入一个新的key,默认调用匿名函数lamdba:1,也就是默认值是1    dc = collections.defaultdict(lambda: 1)    for f in featrues:        dc[f] += 1    return dc# 读取big.txtdata = words(open('big.txt').read())# 统计词频NWORDS = train(data)alphabet ='abcdefghijklmnopqrstuvwxyz'# 单词距离算法,距离为1def edits1(word):    n = len(word)    return set(        [word[0:i]+word[i+1:] for i in range(n)] + # 删除一个字母的        [word[0:i]+word[i+1]+word[i]+word[i+2:] for i in range(n-1)]+ # 临近字母换位        [word[0:i]+c+word[i+1:] for i in range(n) for c in alphabet]+ # 变换一个字母        [word[0:i]+word[i:] for i in range(n) for c in alphabet] # 插入一个字母        )# 单词距离算法,距离为2def 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)# 贝叶斯,由于P(w)都是一样的,可以不计算。def correct(word):    # 先取P(w|c)较大,即单词距离最近的    candidates = known([word]) or known(edits1(word)) or edits2(word) or [word]    # 再获取词频最大的的值    return max(candidates,key = lambda w:NWORDS[w])#测试correct('lovv')