您的位置:首页 > 编程语言 > Python开发

写程序学ML:朴素贝叶斯算法原理及实现(一)

2017-10-01 21:26 375 查看
[题外话]近期申请了一个微信公众号:平凡程式人生。有兴趣的朋友可以关注,那里将会涉及更多更新机器学习、OpenCL+OpenCV以及图像处理方面的文章。

1、朴素贝叶斯算法的原理

朴素贝叶斯法是基于贝叶斯定理与特征条件独立假设的分类方法。

和决策树模型相比,朴素贝叶斯分类器(NaiveBayes Classifier,或 NBC)发源于古典数学理论,有着坚实的数学基础,以及稳定的分类效率。同时,NBC模型所需估计的参数很少,对缺失数据不太敏感,算法也比较简单。理论上,NBC模型与其他分类方法相比具有最小的误差率。但是实际上并非总是如此,这是因为NBC模型假设属性之间相互独立,这个假设在实际应用中往往是不成立的,这给NBC模型的正确分类带来了一定影响。

         朴素贝叶斯的优缺点

优点:在数据较少的情况下仍然有效,可以处理多类别问题。

缺点:对于输入数据的准备方式较为敏感。

适用数据类型:标称型数据。

 

贝叶斯决策理论的核心思想:选择具有最高概率的决策。

贝叶斯准则告诉我们如何交换条件概率中的条件与结果,即如果已知P(x|c),要求P(c|x),那么可以使用下面的计算方法: p(c|x)=p(x|c)p(c)/p(x)

 

         如何使用条件概率分类

给定某个由x,y表示的数据点,那么该数据点来自类别c1的概率是多少,即p(c1 | x, y);数据点来自类别c2的概率是多少,即p(c2 | x, y)。应用贝叶斯准则可以得到:

P(ci | x, y) = p(x, y | ci) * p(ci) / p(x, y)

使用这些定义,可以定义贝叶斯分类准则为:

如果P(c1 | x, y)> P(c2 | x, y),那么属于类别c1;

如果P(c1 | x,y) < P(c2 | x, y),那么属于类别c2;

 

朴素贝叶斯的一般过程

1>    收集数据:可以使用任何方法。本章使用RSS源。

2>    准备数据:需要数值型或者布尔型数据。

3>    分析数据:有大量特征时,绘制特征作用不大,此时使用直方图效果更好。

4>    训练算法:计算不同的独立特征的条件概率。

5>    测试算法:计算错误率。

6>    使用算法:一个常见的朴素贝叶斯应用是文档分类。可以在任意的分类场景中使用朴素贝叶斯分类器,不一定非要是文本。

 

由统计学知,如果每个特征需要N个样本,那么对于10个特征将需要N的10次方个样本,对于包含1000个特征的词汇表将需要N的1000次方个样本。可以看到,所需要的样本数会随着特征数目增大而迅速增大。

如果特征之间相互独立,那么样本数就会从N的1000次方减少到1000xN。所谓独立(independence)指的是统计意义上的独立,即一个特征或者单词出现的可能性与它和其它单词相邻没有关系。

朴素贝叶斯的假设

1>    特征之间相互独立:即一个特征或者单词出现的可能性与它和其他单词相邻没有关系。

2>    每个特征同等重要。

 

朴素贝叶斯分类器实现方式

朴素贝叶斯分类器通常有两种实现方式:一种基于贝努利模型实现,一种基于多项式模型实现。

贝努利模型为纪念瑞士科学家雅各布·贝努利而命名。对随机试验中某事件是否发生,实验的可能结果只有两个,这个只有两个可能结果的实验被称为贝努利实验。

伯努利模型中,每个特征的取值是布尔型的,即true和false,或者1和0。在文本分类中,就是一个特征有没有在一个文档中出现。

如果特征值xi值为1,那么

P(xi | yk) = P(xi= 1 | yk)

如果特征值xi值为0,那么

P(xi | yk) = 1 −P(xi = 1 | yk)

这意味着,“没有某个特征”也是一个特征。

 

多项式模型常用于文本分类,特征是单词,值是单词的出现次数。

P(xi | yk) = Nykxi+ αNyk + αn

其中,Nykxi是类别yk下特征xi出现的总次数;Nyk是类别yk下所有特征出现的总次数。对应到文本分类里,如果单词word在一篇分类为label1的文档中出现了5次,那么Nlabel1,word的值会增加5。如果是去除了重复单词的,那么Nlabel1,word的值会增加1。n是特征的数量,在文本分类中就是去重后的所有单词的数量。α的取值范围是[0,1],比较常见的是取值为1。

待预测样本中的特征xi在训练时可能没有出现,如果没有出现,则Nykxi值为0,如果直接拿来计算该样本属于某个分类的概率,结果都将是0。在分子中加入α,在分母中加入αn可以解决这个问题。

 

下溢问题

利用贝叶斯分类器对文档进行分类时,要计算多个概率的乘积以获得文档属于某个类别的概率,即计算p(w0|ci)p(w1|ci)p(w2|ci)…p(wN|ci)。

当计算乘积p(w0|ci)p(w1|ci)p(w2|ci)…p(wN|ci)时,由于大部分因子都非常小,所以程序会下溢或者得到不正确的答案。一种解决方法是对乘积取自然对数。在代数中有ln(a*b)=ln(a)+ln(b),于是通过求对数可以避免下溢出或者浮点数舍入导致的错误。同时,采用自然对数进行处理不会有任何损失。图4-4给出函数f(x)与ln(f(x))的曲线。检查这两条曲线,就会发现它们在相同区域内同时增加或者减少,并且在相同点上取到极值。它们的取值虽然不同,但不影响最终结果。



(未完待续)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息