scikit-learn朴素贝叶斯

一、什么是朴素贝叶斯

在所有的机器学习分类算法中,朴素贝叶斯和其他绝大多数的分类算法都不同。对于大多数的分类算法,比如决策树,KNN,逻辑回归,支持向量机等,他们都是判别方法,也就是直接学习出特征输出Y和特征X之间的关系,要么是决策函数Y=f(X),要么是条件分布P(Y|X)。但是朴素贝叶斯却是生成方法,也就是直接找出特征输出Y和特征X的联合分布P(X,Y),然后用P(Y|X)=P(X,Y)/P(X)得出。朴素贝叶斯很直观,计算量也不大,在很多领域有广泛的应用。

首先回顾一下朴素贝叶斯相关的统计学知识:

贝叶斯学派的思想可以概括为先验概率+数据=后验概率。也就是说我们在实际问题中需要得到的后验概率,可以通过先验概率和数据一起综合得到。

我们先看看条件独立公式,如果X和Y相互独立,则有:P(A,B)=P(A)P(B)

我们接着看看条件概率公式:P(AB)=P(A|B)P(B)=P(B|A)P(A)

接着看看全概率公式:这里写图片描述

从上面的公式很容易得出贝叶斯公式:这里写图片描述

二、scikit-learn 朴素贝叶斯类库

朴素贝叶斯是一类比较简单的算法,scikit-learn中朴素贝叶斯类库的使用也比较简单。相对于决策树,KNN之类的算法,朴素贝叶斯需要关注的参数是比较少的,这样也比较容易掌握。在scikit-learn中,一共有3个朴素贝叶斯的分类算法类。分别是GaussianNB,MultinomialNB和BernoulliNB。其中GaussianNB就是先验为高斯分布的朴素贝叶斯,MultinomialNB就是先验为多项式分布的朴素贝叶斯,而BernoulliNB就是先验为伯努利分布的朴素贝叶斯。

这三个类适用的分类场景各不相同,主要根据数据类型来进行模型的选择。一般来说,如果样本特征的分布大部分是连续值,使用GaussianNB会比较好。如果如果样本特征的分大部分是多元离散值,使用MultinomialNB比较合适。而如果样本特征是二元离散值或者很稀疏的多元离散值,应该使用BernoulliNB。

高斯分布又叫正太分布,我们把一个随机变量X服从数学期望为μ、方差为σ^2的数据分布称为正太分布,当数学期望μ=0,方差σ=1时称为标准正态分布。

                 正太分布概率图

多项式分布(Multinomial Distribution)是二项式分布的推广,二项分布是随机结果值只有两个(投硬币的结果),多项式分布是指随机结果值有多个(摇骰子的结果)。

 

伯努利分布又称“零一分布”、“两点分布”(即结果要么是0要么是1),是二项分布的特殊情况,之所以是特殊的二项分布,是因为二项分布是多重伯努利实验的概率分布。举个例子就是,伯努利分布是只扔一次硬币正面反面的概率,而二项分布是扔多次硬币以后得到正面反面的概率。

 

a>>>GaussianNB Naive_Bayes
GaussianNB类的主要参数仅有一个,即先验概率priors,对应Y的各个类别的先验概率P(Y=Ck)。这个值默认不给出,如果不给出此时P(Y=Ck)=mk/m。其中m为训练集样本总数量,mk为输出为第k类别的训练集样本数。如果给出的话就以priors 为准。 在使用GaussianNB的fit方法拟合数据后,我们可以进行预测。此时预测有三种方法,包括predict,predict_log_proba和predict_proba。

predict方法就是我们最常用的预测方法,直接给出测试集的预测类别输出。

predict_proba则不同,它会给出测试集样本在各个类别上预测的概率。容易理解,predict_proba预测出的各个类别概率里的最大值对应的类别,也就是predict方法得到类别。

predict_log_proba和predict_proba类似,它会给出测试集样本在各个类别上预测的概率的一个对数转化。转化后predict_log_proba预测出的各个类别对数概率里的最大值对应的类别,也就是predict方法得到类别。

下面给一个具体的例子:

import numpy as np
X = np.array([[-1, -1], [-2, -1], [-3, -2], [1, 1], [2, 1], [3, 2]])
Y = np.array([1, 1, 1, 2, 2, 2])
from sklearn.naive_bayes import GaussianNB
clf = GaussianNB()
#拟合数据
clf.fit(X, Y)
print("==Predict result by predict==")
print(clf.predict([[-0.8, -1]]))
print("==Predict result by predict_proba==")
print(clf.predict_proba([[-0.8, -1]]))
print("==Predict result by predict_log_proba==")
print(clf.predict_log_proba([[-0.8, -1]]))

 

高斯朴素贝叶斯算法是假设特征的可能性(即概率)为高斯分布。

class sklearn.naive_bayes.GaussianNB(priors=None)

priors:先验概率大小,如果没有给定,模型则根据样本数据自己计算(利用极大似然法)。

对象

class_prior_:每个样本的概率 class_count:每个类别的样本数量 theta_:每个类别中每个特征的均值 sigma_:每个类别中每个特征的方差

此外,GaussianNB一个重要的功能是有 partial_fit方法,这个方法的一般用在如果训练集数据量非常大,一次不能全部载入内存的时候。这时我们可以把训练集分成若干等分,重复调用partial_fit来一步步的学习训练集,非常方便。后面讲到的MultinomialNB和BernoulliNB也有类似的功能。

 

 

b>>>MultinomialNB Naive_Bayes

MultinomialNB参数比GaussianNB多,但是一共也只有仅仅3个。其中,参数alpha即为上面的常数λ,如果你没有特别的需要,用默认的1即可。如果发现拟合的不好,需要调优时,可以选择稍大于1或者稍小于1的数。布尔参数fit_prior表示是否要考虑先验概率,如果是false,则所有的样本类别输出都有相同的类别先验概率。否则可以自己用第三个参数class_prior输入先验概率,或者不输入第三个参数class_prior让MultinomialNB自己从训练集样本来计算先验概率,此时的先验概率为P(Y=Ck)=mk/m。其中m为训练集样本总数量,mk为输出为第k类别的训练集样本数。

原型

class sklearn.naive_bayes.MultinomialNB(alpha=1.0fit_prior=Trueclass_prior=None)

这里写图片描述

适用于服从多项分布的特征数据。

class sklearn.naive_bayes.MultinomialNB(alpha=1.0, fit_prior=True, class_prior=None)

alpha:先验平滑因子,默认等于1,当等于1时表示拉普拉斯平滑。

fit_prior:是否去学习类的先验概率,默认是True

class_prior:各个类别的先验概率,如果没有指定,则模型会根据数据自动学习, 每个类别的先验概率相同,等于类标记总个数N分之一。

对象

class_log_prior_:每个类别平滑后的先验概率

intercept_:是朴素贝叶斯对应的线性模型,其值和class_log_prior_相同

feature_log_prob_:给定特征类别的对数概率(条件概率)。 特征的条件概率=(指定类下指定特征出现的次数+alpha)/(指定类下所有特征出现次数之和+类的可能取值个数*alpha)

coef_: 是朴素贝叶斯对应的线性模型,其值和feature_log_prob相同

class_count_: 训练样本中各类别对应的样本数

feature_count_: 每个类别中各个特征出现的次数

 

 

c>>>BernoulliNB Naive_Bayes

BernoulliNB一共有4个参数,其中3个参数的名字和意义和MultinomialNB完全相同。唯一增加的一个参数是binarize。这个参数主要是用来帮BernoulliNB处理二项分布的,可以是数值或者不输入。如果不输入,则BernoulliNB认为每个数据特征都已经是二元的。否则的话,小于binarize的会归为一类,大于binarize的会归为另外一类。

用于多重伯努利分布的数据,即有多个特征,但每个特征都假设是一个二元 (Bernoulli, boolean) 变量。

class sklearn.naive_bayes.BernoulliNB(alpha=1.0, binarize=0.0, fit_prior=True, class_prior=None)

alpha:平滑因子,与多项式中的alpha一致。

binarize:样本特征二值化的阈值,默认是0。如果不输入,则模型会认为所有特征都已经是二值化形式了;如果输入具体的值,则模型会把大于该值的部分归为一类,小于的归为另一类。

fit_prior:是否去学习类的先验概率,默认是True

class_prior:各个类别的先验概率,如果没有指定,则模型会根据数据自动学习, 每个类别的先验概率相同,等于类标记总个数N分之一。

对象

class_log_prior_:每个类别平滑后的先验对数概率。

feature_log_prob_:给定特征类别的经验对数概率。

class_count_:拟合过程中每个样本的数量。

feature_count_:拟合过程中每个特征的数量。

方法

贝叶斯的方法和其他模型的方法一致。

fit(X,Y):在数据集(X,Y)上拟合模型。

get_params():获取模型参数。

predict(X):对数据集X进行预测。

predict_log_proba(X):对数据集X预测,得到每个类别的概率对数值。

predict_proba(X):对数据集X预测,得到每个类别的概率。

score(X,Y):得到模型在数据集(X,Y)的得分情况。

在使用BernoulliNB的fit或者partial_fit方法拟合数据后,我们可以进行预测。此时预测有三种方法,包括predict,predict_log_proba和predict_proba。由于方法和GaussianNB完全一样,这里就不累述了。

三、朴素贝叶斯的主要优缺点

朴素贝叶斯的主要优点有:

    1)朴素贝叶斯模型发源于古典数学理论,有稳定的分类效率。

    2)对小规模的数据表现很好,能个处理多分类任务,适合增量式训练,尤其是数据量超出内存时,我们可以一批批的去增量训练。

    3)对缺失数据不太敏感,算法也比较简单,常用于文本分类。

朴素贝叶斯的主要缺点有:   

    1) 理论上,朴素贝叶斯模型与其他分类方法相比具有最小的误差率。但是实际上并非总是如此,这是因为朴素贝叶斯模型假设属性之间相互独立,这个假设在实际应用中往往是不成立的,在属性个数比较多或者属性之间相关性较大时,分类效果不好。而在属性相关性较小时,朴素贝叶斯性能最为良好。对于这一点,有半朴素贝叶斯之类的算法通过考虑部分关联性适度改进。

    2)需要知道先验概率,且先验概率很多时候取决于假设,假设的模型可以有很多种,因此在某些时候会由于假设的先验模型的原因导致预测效果不佳。

    3)由于我们是通过先验和数据来决定后验的概率从而决定分类,所以分类决策存在一定的错误率。

    4)对输入数据的表达形式很敏感。

posted @ 2020-02-09 17:48  CeasonCing  阅读(87)  评论(0)    收藏  举报