贝叶斯公式

1、举例:一个学校有N名学生,其中男生占60%,女生占40%,男生全部传长裤,女生一半穿长裤,一半穿裙子,现在看见一个学生穿着长裤,看不清是男生还是女生。请问是女生的概率有大?

count(女生穿长裤的人数) = N * P(女生) * P(长裤| 女生)

count (穿长裤的总人数) = N * P(男生) * P(长裤 | 男生) + N * P(女生) * P(长裤 | 女生)

P(女生 | 长裤) = count(女生穿长裤的人数)  /  count(穿长裤的总人数)

                    = N * P(女生) * P(长裤| 女生)  /  ( N * P(男生) * P(长裤 | 男生) + N * P(女生) * P(长裤 | 女生) )

                    P(女生) * P(长裤| 女生)  /  ( P(男生) * P(长裤 | 男生) +  P(女生) * P(女生,长裤) )

                    = P(女生) *  P(长裤| 女生) / P(长裤)

上述结果与N无关。

这其实就是贝叶斯公式:P(A | B) = P(A) * P(B | A) / P(B)

2、模型比较理论

最大似然:最符合观测数据( P(D|w) )的最有优势。

抛掷一枚硬币,观察到“正面朝上”,根据最大似然,应该猜测这枚硬币掷出正面朝上的概率为1,这样才能最大化P(D|w)的这个猜测 。

奥卡姆剃刀:P(w) 最大的模型有较大的优势。

如果平面上有N个点,近似构成一条直线,但绝不精确地位于一条直线上,我们可以使用一阶,二阶,甚至N-1阶多项式完美地通过N个数据点,哪个模型最靠谱?根据奥卡姆剃刀原则,越是高阶的多项式越不常见。

3、贝叶斯公式的应用

拼写检查,P(D|w),D是我们的输入单词,w是我们要预测的单词。P(w|D) = P(w) * P(D|w) / P(D),其中P(D)可以忽略。

代码自动补全;

垃圾邮件过滤。一封邮件D有N个单词组成,使用h+表示垃圾邮件,h-表示正常邮件,则

P(h+ | D) = P(h+) * P(D | h+) / P(D)

P(h- | D) = P(h-) * P(D | h-) / P(D)

其中P(D)可以忽略。

 

4、贝叶斯实现拼写检查

import re,collections

# 求解 argmaxc P(c|w) ->argmaxc P(w|c)*P(c)/P(w)
# 其中,P(c) 是文章中出现一个正确拼写词c的概率,即在英文文章中c出现的概率多大。
# P(w|c),表示用户想输入正确单词c的情况下,敲错成w的概率,因为这个是代表用户会以多大的概率把c敲错成w
# argmaxc,用来枚举所有可能的c并且选取概率最大的那个单词c

# 把语料库中的单词全部抽取出来,转成小写。并去除单词间的特殊符号。
def words(text):
  return re.findall('[a-z]+', text.lower())

# 统计每个单词出现的个数
def train(features):
  # defaultdict类的初始化函数接受一个类型作为参数,当所访问的键不存在的时候,可以实例化一个值作为默认值。
  model = collections.defaultdict(lambda:1)
  for f in features:
    model[f] += 1
  return model

words_num = train(words(open("/content/sample_data/big.txt").read()))
# print(len(words_num))  
# 要是遇到从未见过的新词,比如说,一个词拼写完全正确,语料库中这个词,
# 从而这个词也永远不会出现在训练集中,于是返回出现这个单词的概率为0,
# 这样可不行,因为0代表永远不可能发生,我们期望使用一个很小的概率来代表这种情况lambda:1。

# 字母表
alphabet = 'abcdefghijklmnopqrstuvwxyz'

# P(D|w),D是我们的输入单词,w是我们要预测的单词。P(w|D) = P(w) * P(D|w) / P(D),其中P(D)可以忽略。
# P(D|w)使用编辑距离衡量
# 编辑距离: 
# 两个单词之间的编辑距离定位为使用了几次插入(在一个词中插入一个单字母),删除(删除一个单字母),
# 交换(交换相邻连个字母),替换(把一个字母换成另一个字母)的操作将一个词变成另一个词。
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] +  # alternation,替换一个单词
        [word[0:i] + c + word[i:] for i in range(n+1) for c in alphabet]    # insertion,插入一个单词
        )

# 与something编辑距离为2的单词有114324个!
# 优化,只返回计算的编辑距离形成的单词在单词表中有的单词
def known_edits2(word):
  return set(e2 for e1 in edits1(word) for e2 in edits1(e1) if e2 in words_num)

def known(words):
  return set(w for w in words if w in words_num)

def correct(word):
  # 找出在词库中与输入单词最相近的单词,得出候选预测词
  candidates = known([word]) or known(edits1(word)) or known_edits2(word) or [word]
  print(candidates) 
  # 从候选预测词中选择一个出现罪数最多的作为待预测的词
  return max(candidates, key=lambda w: words_num[w])


correct('corrr')
# print(known(['corrr']))

输出:(不同的语料库输出结果可能不一样)

'core'

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值