机器学习算法总结--朴素贝叶斯

这次需要总结的是朴素贝叶斯算法,参考文章:

  • 《统计学习方法》
  • 机器学习常见算法个人总结(面试用)
  • 朴素贝叶斯理论推导与三种常见模型
  • 朴素贝叶斯的三个常用模型:高斯、多项式、伯努利

简介

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

贝叶斯定理是基于条件概率来计算的,条件概率是在已知事件B发生的前提下,求解事件A发生的概率,即P(A|B)=P(AB)P(B),而贝叶斯定理则可以通过P(A|B)来求解P(B|A)

P(B|A)=P(A|B)P(B)P(A)

其中分母 P(A)可以根据全概率公式分解为: P(A)=ni=1P(Bi)P(A|Bi)

特征条件独立假设是指假设各个维度的特征x1,x2,...,xn互相独立,则条件概率可以转化为:

P(x|yk)=P(x1,x2,...,xn|yk)=i=1nP(xi|yk)

朴素贝叶斯分类器可表示为:
f(x)=argmaxykP(yk|x)=argmaxykP(yk)ni=1P(xi|yk)kP(yk)ni=1P(xi|yk)

而由于对上述公式中分母的值都是一样的,所以可以忽略分母部分,即可以表示为:
f(x)=argmaxP(yk)i=1nP(xi|yk)

这里 P(yk)是先验概率,而 P(yk|x)则是后验概率,朴素贝叶斯的目标就是最大化后验概率,这等价于期望风险最小化。

参数估计

极大似然估计

朴素贝叶斯的学习意味着估计P(yk)P(xi|yk),可以通过极大似然估计来估计相应的概率。

这里写图片描述

如上图所示,分别是P(yk)P(xi|yk)的极大似然估计。

当求解完上述两个概率,就可以对测试样本使用朴素贝叶斯分类算法来预测其所属于的类别,简单总结的算法流程如下所示:

这里写图片描述

贝叶斯估计/多项式模型

极大似然估计可能会出现所要估计的概率值为0的情况,这会影响到后验概率的计算,使分类产生偏差。解决这个问题的办法是使用贝叶斯估计,也被称为多项式模型。

特征是离散的时候,使用多项式模型。多项式模型在计算先验概率P(yk)和条件概率P(xi|yk)时,会做一些平滑处理,具体公式为:

P(yk)=Nyk+αN+kα

N是总的样本个数,k是总的类别个数,Nyk是类别为yk的样本个数,α是平滑值。

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

Nyk是类别为yk的样本个数,n是特征的维数,Nyk,xi是类别为yk的样本中,第i维特征的值是xi的样本个数,α是平滑值。

α=1时,称作Laplace平滑,当0<α<1时,称作Lidstone平滑,α=0时不做平滑。

如果不做平滑,当某一维特征的值xi没在训练样本中出现过时,会导致P(xi|yk)=0,从而导致后验概率为0。加上平滑就可以克服这个问题。

高斯模型

当特征是连续变量的时候,运用多项式模型会导致很多P(xi|yk)=0(不做平滑的情况下),即使做平滑,所得到的条件概率也难以描述真实情况,所以处理连续变量,应该采用高斯模型。

高斯模型是假设每一维特征都服从高斯分布(正态分布):

P(xi|yk)=12πσ2ykexp((xiμyk)22σ2yk)

μyk,i表示类别为yk的样本中,第i维特征的均值;
σ2yk,i表示类别为yk的样本中,第i维特征的方差。

伯努利模型

与多项式模型一样,伯努利模型适用于离散特征的情况,所不同的是,伯努利模型中每个特征的取值只能是1和0(以文本分类为例,某个单词在文档中出现过,则其特征值为1,否则为0).

伯努利模型中,条件概率P(xi|yk)的计算方式是:

当特征值xi为1时,P(xi|yk)=P(xi=1|yk)

当特征值xi为0时,P(xi|yk)=1P(xi=1|yk)

工作流程

  1. 准备阶段
    确定特征属性,并对每个特征属性进行适当划分,然后由人工对一部分待分类项进行分类,形成训练样本。
  2. 训练阶段
    计算每个类别在训练样本中的出现频率及每个特征属性划分对每个类别的条件概率估计
  3. 应用阶段
    使用分类器进行分类,输入是分类器和待分类样本,输出是样本属于的分类类别

属性特征

  1. 特征为离散值时直接统计即可(表示统计概率)
  2. 特征为连续值的时候假定特征符合高斯分布,则有

P(xi|yk)=12πσ2ykexp((xiμyk)22σ2yk)

优缺点

优点

  1. 对小规模的数据表现很好,适合多分类任务,适合增量式训练。

缺点

  1. 对输入数据的表达形式很敏感(离散、连续,值极大极小之类的)。

代码实现

下面是使用sklearn的代码例子,分别实现上述三种模型,例子来自朴素贝叶斯的三个常用模型:高斯、多项式、伯努利。
下面是高斯模型的实现

>>> from sklearn import datasets
>>> iris = datasets.load_iris()
>>> iris.feature_names  # 四个特征的名字
['sepal length (cm)', 'sepal width (cm)', 'petal length (cm)', 'petal width (cm)']
>>> iris.data
array([[ 5.1,  3.5,  1.4,  0.2],[ 4.9,  3. ,  1.4,  0.2],[ 4.7,  3.2,  1.3,  0.2],[ 4.6,  3.1,  1.5,  0.2],[ 5. ,  3.6,  1.4,  0.2],[ 5.4,  3.9,  1.7,  0.4],[ 4.6,  3.4,  1.4,  0.3],[ 5. ,  3.4,  1.5,  0.2],......[ 6.5,  3. ,  5.2,  2. ],[ 6.2,  3.4,  5.4,  2.3],[ 5.9,  3. ,  5.1,  1.8]]) #类型是numpy.array
>>> iris.data.size  
600  #共600/4=150个样本
>>> iris.target_names
array(['setosa', 'versicolor', 'virginica'], dtype='|S10')
>>> iris.target
array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,....., 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ......, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2])
>>> iris.target.size
150
>>> from sklearn.naive_bayes import GaussianNB
>>> clf = GaussianNB()
>>> clf.fit(iris.data, iris.target)
>>> clf.predict(iris.data[0])
array([0])   # 预测正确
>>> clf.predict(iris.data[149])
array([2])   # 预测正确
>>> data = numpy.array([6,4,6,2])
>>> clf.predict(data)
array([2])  # 预测结果很合理

多项式模型如下:

>>> import numpy as np
>>> X = np.random.randint(5, size=(6, 100))
>>> y = np.array([1, 2, 3, 4, 5, 6])
>>> from sklearn.naive_bayes import MultinomialNB
>>> clf = MultinomialNB()
>>> clf.fit(X, y)
MultinomialNB(alpha=1.0, class_prior=None, fit_prior=True)
>>> print(clf.predict(X[2]))
[3]

值得注意的是,多项式模型在训练一个数据集结束后可以继续训练其他数据集而无需将两个数据集放在一起进行训练。在sklearn中,MultinomialNB()类的partial_fit()方法可以进行这种训练。这种方式特别适合于训练集大到内存无法一次性放入的情况。

在第一次调用partial_fit()时需要给出所有的分类标号。

>>> import numpy
>>> from sklearn.naive_bayes import MultinomialNB
>>> clf = MultinomialNB() 
>>> clf.partial_fit(numpy.array([1,1]), numpy.array(['aa']), ['aa','bb'])
GaussianNB()
>>> clf.partial_fit(numpy.array([6,1]), numpy.array(['bb']))
GaussianNB()
>>> clf.predict(numpy.array([9,1]))
array(['bb'], dtype='|S2')

伯努利模型如下:

>>> import numpy as np
>>> X = np.random.randint(2, size=(6, 100))
>>> Y = np.array([1, 2, 3, 4, 4, 5])
>>> from sklearn.naive_bayes import BernoulliNB
>>> clf = BernoulliNB()
>>> clf.fit(X, Y)
BernoulliNB(alpha=1.0, binarize=0.0, class_prior=None, fit_prior=True)
>>> print(clf.predict(X[2]))
[3]

朴素贝叶斯的总结就到这里为止。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/408935.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

行添加DataGridView导出Excel的数据表格

最近研究行添加&#xff0c;稍微总结一下&#xff0c;以后继续补充&#xff1a; 将DataGridView中的据数导出为Excel的据数表格&#xff0c;方法有很多种&#xff0c;面下供提一种本人认为是一个好解理&#xff0c;较单简的方法。步调如下&#xff1a; 1、添加引用 2、编写码代…

机器学习算法总结--K近邻

参考文章&#xff1a; 《统计学习方法》机器学习常见算法个人总结&#xff08;面试用&#xff09;机器学习系列(9)_机器学习算法一览&#xff08;附Python和R代码&#xff09; 简介 k近邻&#xff08;KNN)是一种基本分类与回归方法。 其思路如下&#xff1a;给一个训练数据集…

机器学习算法总结--提升方法

参考自&#xff1a; 《统计学习方法》浅谈机器学习基础&#xff08;上&#xff09;Ensemble learning:Bagging,Random Forest,Boosting 简介 提升方法(boosting)是一种常用的统计学习方法&#xff0c;在分类问题中&#xff0c;它通过改变训练样本的权重&#xff0c;学习多个分…

matlab画x的1 3次方,如何用Matlab画出f(x)=f(x-1)+2的x次方*3的图像

如何用Matlab画出f(x)f(x-1)2的x次方*3的图像以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;如何用Matlab画出f(x)f(x-1)2的x次方*3的图像你要画的范围假设是0到10Fzeros(1,10);F(1)1;要有初…

机器学习算法总结--GBDT

参考如下 机器学习&#xff08;四&#xff09;— 从gbdt到xgboost机器学习常见算法个人总结&#xff08;面试用&#xff09;xgboost入门与实战&#xff08;原理篇&#xff09; 简介 GBDT是一个基于迭代累加的决策树算法&#xff0c;它通过构造一组弱的学习器&#xff08;树&a…

机器学习算法总结--EM算法

参考自 《统计学习方法》机器学习常见算法个人总结&#xff08;面试用&#xff09;从最大似然到EM算法浅解&#xff08;EM算法&#xff09;The EM Algorithm 简介 EM算法&#xff0c;即期望极大算法&#xff0c;用于含有隐变量的概率模型的极大似然估计或极大后验概率估计&am…

CPP第四版第四章:创建动态数组

数组类型的变量有三个重要限制&#xff1a; 数组长度固定不变 在编译时必须知道其长度 数组只在定义它的块语句内存在 每一个程序在执行时都占用一块可用的内存空间&#xff0c;用于存放动态分配的对象&#xff0c;此内存空间称为程序的自由存储区或堆…

(转)非极大抑制(Non-Maximum Suppression)

转载自非极大抑制&#xff08;Non-Maximum Suppression&#xff09;。 参考文章&#xff1a; 1. Non-Maximum Suppression for Object Detection in Python 2. NMS非极大值抑制 最近在做人脸识别的项目&#xff0c;其中在人脸检测算法中MTCNN算法是用到了NMS算法来筛选候选…

安装配置Eclipse开发PHP环境配置

文章结束给大家来个程序员笑话&#xff1a;[M] Eclipse发开PHP环境配置 首先准备好件软&#xff1a; 1. Apache,到这里找个最新本版 2. PHP&#xff0c;到这里下载 3. Eclipse IDE for Java EE Developers&#xff0c;到这里下载 4. DLTK Core Frameworks 1.0 Integration buil…

C++ 输入一行未知个数的整数

最近笔试的时候&#xff0c;编程题遇到这样要求的输入&#xff0c;需要输入一行整数&#xff0c;个数未知&#xff0c;然后整数之间用空格间隔&#xff0c;如下所示&#xff1a; 11 22 333 45 62 代码如下所示&#xff1a; int main() {vector<int> inputs;int n 0, …

[原]好玩的Linux,关于时间cal命令

我们都知道&#xff0c;在Linux中&#xff0c;可以通过cal命令来查看日历。Cal怎么用呢&#xff0c;我们可以man一下&#xff0c;可以看到如下结果&#xff1a; 我们可以看到cal命令的基本用法如下&#xff1a;cal [-smjy13] [[[day] month] year] 当然如果不加指定参数的话&a…