机器学习方法总结(七):朴素贝叶斯

朴素贝叶斯

1.简介

    朴素贝叶斯法是典型的生成学习方法,生成方法由训练数据得到联合概率分布P(X,Y)和先验概率P(X),在训练的过程中求得后验概率P(Y|X),即:P(X,Y)=P(Y|X)P(Y),在测试时去求P(X|Y),而前几篇文章介绍的算法都是基于判别的模型,直接去拟合后验概率,注意这里为什么要叫朴素贝叶斯,朴素的原因就是因为它的特征都是独立不会互相影响的。

2.流程

    举一个例子说明:以在线社区留言板文档分类为例,P(C1)就是A类的比例,P(C2)就是B类文档的比例,P(W|Ci)是值Ci类的文档中出现特征W的概率,这里的W其实是一个特征向量W=[W1,W2...Wn],在这个例子中每一个特征就是某一个单词:

                                                          P(W|Ci)=P(W1|Ci)*P(W2|Ci)*P(Wn|Ci),

    这样在训练过程中我们是不是可以把P(W|Ci)统计出来,P(W)也是可以统计出来的,所以由下列公式可以得出先验概率:

                                                                        P(C_{i}|W)=\frac{P(W|C_{i})P(C)}{P(W)}

     机器学习学习实战上有这个例子的伪代码:

             计算每个类别中的文档数目

             对每篇训练文档:

                        对每个类别:

                                如果词条出现在文档中-->增加该词条的计数值

                                增加所有词条的计数值(此类别下词条总数)

            对每个类别:

                        对每个词条:

                               将该词条的数目除以总词条数目得到的条件概率(P(词条|类别))

            返回该文档属于每个类别的条件概率(P(类别|文档的所有词条))

3.优缺点

  • 优点:在数据较少的情况下仍然有效,可以处理多类别问题。
  • 缺点:对于输入数据的准备方式较为敏感。

4.实现

    朴素贝叶斯原理简单,应用却很广泛,我这举一个搜索引擎的自动检错的功能,代码如下:

#朴素贝叶斯是是一种学习生成数据机制的生成模型,给定输入x后,通过计算最大后验概率p(c/x)来进行分类输出,训练机制就是通过训练算出先验概率p(c)
#和条件概率p(x/c)。解决此问题的思路是:对一个文本中的单词进行两次字母的增删改查(edit)得到一个错误单词的list
#p(c)就是正确单词文本集合中改c(iphone)的频率,p(x/c)就是当单词为c是出现错误拼写(ipone)的概率,取它们乘积最大就可以得到正确单词
#代码中先求p(x/c),通过频数表示,然后取最大p(c)

import re
from collections import Counter
text='iphone,recall,iphone,call,iponea'
word=re.findall(r'\w+', text.lower())
#返回text中每个单词的每个单词的频率
def train(features):
    counter = dict()
    for kw in features:
        counter.setdefault(kw, 0)
        counter[kw] += 1
    return counter
NWORDS = train(words(text)) 
#对每个单词进行增删改查
def edits1(word):  
    # 字母集  
    alphabet = 'abcdefghijklmnopqrstuvwxyz'  
    # 返回所有将单词分成两半元组列表  
    splits = [(word[:i], word[i:]) for i in range(len(word) + 1)]  
    # 返回所有删去一个字母后的列表  
    deletes = [a + b[1:] for a, b in splits if b]  # a,b 在元组中  
    # 交换相邻两个字母的列表  
    transpose = [a + b[1] + b[0] +b[2:] for a,b in splits if len(b)>1]  
    # 将word每一位替换成其他25个字母,形成新的单词  
    replaces = [a + c + b[1:] for a,b in splits for c in alphabet if b]  
    # 将word中插入一个字母,形成新的单词  
    inserts = [a + c + b for a, b in splits for c in alphabet]  
    return set(deletes + transpose + replaces + inserts)  
#用两次edits
def known_edits(word):  
    return set(e2 for e1 in edits1(word) for e2 in edits1(e1) if e2 in NWORDS)  
#返回words中在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_edits(word) or [word]  
    return max(candidates, key=NWORDS.get)  
if __name__ == '__main__':  
    print(correct('iponele'))  

    

猜你喜欢

转载自blog.csdn.net/qq_38593211/article/details/81333025
今日推荐