贝叶斯分类是一类分类算法的总称,这类算法均以贝叶斯定理为基础,故统称为贝叶斯分类。而朴素贝叶斯分类是贝叶斯分类中最简单,也是常见的一种分类方法。
贝叶斯定理
贝叶斯定理实际上就是计算”条件概率”的公式。条件概率(Conditional Probability)是指在事件B发生的情况下,事件A发生的概率,用P(A|B)表示,读作在B条件下的A的概率。
根据上图,可以很清楚地看到在事件B发生的情况下,事件A发生的概率就是P(A∩B)除以P(B)。
P(A|B)=P(A∩B)P(B)
同时,P(A∩B)又可以由P(A∩B)=P(B|A)P(A)表示,然后我们就可以推得贝叶斯公式:
P(A|B)=P(B|A)P(A)P(B)
贝叶斯定理之所以有用,是因为我们在生活中经常遇到这种情况:我们可以很容易直接得出P(A|B),P(B|A)则很难直接得出,但我们更关心P(B|A),贝叶斯定理就为我们打通从P(A|B)获得P(B|A)的道路。
在分类任务中,我们可以把贝叶斯定理换一个更清楚的形式:
朴素贝叶斯分类器
朴素贝叶斯,英文叫 Naive Bayes。之所以称为”朴素”是因为整个形式化过程只做最原始、最简单的假设。朴素贝叶斯算法是假设输入变量之间是相互独立的,没有概率依存关系。(若相互依存,那叫贝叶斯网络)。是监督学习里面的一种分类算法,使用场景为:给定训练集(X,Y),其中每个样本x都包含n维特征,即x=(x1,x2,…,xn),标签集合含有k种类别,即y=(y1,y2,…,yk)。如果现在来了一个新的样本x,我们如何判断它属于哪个类别?解决思路是:从概率的角度看,这个问题就是给定x,它属于哪个类别的概率最大。那么问题就转化为求解P(y1|x),P(y2|x),…,P(yk|x)中最大的那个,即求后验概率最大的那个:
argmaxyP(y|x)
所以朴素贝叶斯分类器就是求上式的最大值,根据贝叶斯公式将上面式子展开后如下:
P(y|x1,…,xn)=P(y)P(x1,…,xn|y)P(x1,…,xn)
可以看到,上面的式子中:
- P(y)是先验概率,可以直接根据数据集计算出来。
- P(x1,…,xn)如何计算?
- P(x1,…,xn|y)如何计算?
首先来看P(x1,…,xn|y)的计算。这里需要用到条件联合概率分解公式:
P(XY|Z)=P(X|YZ)P(Y|Z)
P(UVWX|YZ)=P(U|VWXYZ)P(V|WXYZ)P(W|XYZ)P(X|YZ)P(Y|Z)
利用条件联合概率分解公式:
P(x1,…,xn|y)=P(x1|x2,…,xn,y)P(x2|x3,…,xn,y)…P(xn|y)
上面式子很难计算,所以朴素贝叶斯理论对条件概率分布做了独立性假设,就是在我们的场景下各个维度特征x1,…,xn相互独立,即:
P(xi|y,x1,…,xi−1,xi+1,…,xn)=P(xi|y)
有了上面的假设,之前那个难计算的公式就好计算了:
P(x1,…,xn|y)=P(x1|x2,…,xn,y)P(x2|x3,…,xn,y)…P(xn|y)=P(x1|y)P(x2|y)…P(xn|y)=P(y)∏ni=1P(xi|y)P(x1,…,xn)
对于确定的输入,不论y取哪个值,P(x1,…,xn)都是一样的,所以:
P(x1,…,xn|y)∝P(y)n∏i=1P(xi|y)
所以新样例x=(x1,…,xn)所属的类别y的计算公式为:
ˆy=argmaxyP(y|x)n∏i=1P(xi|y)
所以,NB分类器最后就是求先验概率P(y)和xi的条件概率P(xi|y),这两个概率都是可以计算的。
三种不同的朴素贝叶斯
朴素贝叶斯一共有三种方法,分别是高斯朴素贝叶斯、多项式分布贝叶斯、伯努利朴素贝叶斯,在介绍不同方法的具体参数前,我们先看看这三种方法有什么区别。这三种分类方法其实就是对应三种不同的数据分布类型。
高斯朴素贝叶斯
高斯朴素贝叶斯算法是假设特征属性为连续值时,而且分布服从高斯分布(正态分布)。正态分布的概率密度函数如图所示:
可以看出,正态分布像一个钟形,均值所对应的概率密度函数最高。我们假定某个特征I服从均值为μ,方差为σ2的正态分布,记为N(μ,σ2)。针对公式:
P(yk|X)==P(yk)∏Ni=1P(ai|yk)P(X)
我们可以假定样本X的特征I符合正态分布,此时上式中的P(ai|yk)的计算会变得十分容易:
P(ai|yk)=12π(σyk)2∗e−(ai−μyk)22(σyk)2
如上所示,其中(σyk)2代表类别为yk的样本中,第I维特征的方差。μ代表类别为yk的样本中,第I维特征的均值。
SKlearn中的方法:
class sklearn.naive_bayes.GaussianNB(priors=None)
- priors: 先验概率大小,如果没有给定,模型则根据样本数据自己计算(利用极大似然法)。
示例代码:
from sklearn.datasets import load_iris from sklearn.model_selection import train_test_split from sklearn.naive_bayes import GaussianNB X, y = load_iris(return_X_y=True) X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.5, random_state=0) gnb = GaussianNB() y_pred = gnb.fit(X_train, y_train).predict(X_test) print("Number of mislabeled points out of a total %d points: %d" % (X_test.shape[0], (y_test != y_pred).sum()))
多项式分布贝叶斯
当我们的特征都是分类型特征的时候,可以使用多项式模型。我们可以用它来计算特征中分类的出现频率。特别的是当特征只有两种的时候,我们将会使用多项式模型中的伯努利模型。
在多项式模型中,对于样本X的第I个特征,P(ai|yk)的计算十分容易:
P(ai|yk)=N(yk,ai)N(yk)
如上所示,其中N(yk,ai)代表类别为yk的样本中,第I维特征取值是ai的个数,N(yk)代表类别为yk的样本个数。
SKlearn中的方法:
class sklearn.naive_bayes.MultinomialNB(alpha=1.0, fit_prior=True, class_prior=None)
- alpha: 先验平滑因子,默认等于1,当等于1时表示拉普拉斯平滑。
- fit_prior: 是否去学习类的先验概率,默认是True
- class_prior: 各个类别的先验概率,如果没有指定,则模型会根据数据自动学习,每个类别的先验概率相同,等于类标记总个数N分之一。
示例代码:
from sklearn.datasets import load_iris from sklearn.model_selection import train_test_split from sklearn.naive_bayes import ComplementNB X, y = load_iris(return_X_y=True) X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.5, random_state=0) cnb = ComplementNB() y_pred = cnb.fit(X_train, y_train).predict(X_test) print("Number of mislabeled points out of a total %d points: %d" % (X_test.shape[0], (y_test != y_pred).sum()))
伯努利朴素贝叶斯
与多项式模型一样,伯努利模型适用于离散特征的情况,所不同的是,伯努利模型中每个特征的取值只能是1或0。伯努利模型中,条件概率$P(x_i|y)$的计算方式时:
- 当特征值$x_i=1$时,$P(x_i|y)=P(x_i=1|y)$
- 当特征值$x_i=0$时,$P(x_i|y)=1-P(x_i=1|y)$
SKlearn中的方法:
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分之一。
示例代码:
from sklearn.datasets import load_iris from sklearn.model_selection import train_test_split from sklearn.naive_bayes import BernoulliNB X, y = load_iris(return_X_y=True) X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.5, random_state=0) bnb = BernoulliNB() y_pred = bnb.fit(X_train, y_train).predict(X_test) print("Number of mislabeled points out of a total %d points: %d" % (X_test.shape[0], (y_test != y_pred).sum()))
朴素贝叶斯算法优缺点
优点:
- 朴素贝叶斯模型发源于古典数学理论,有稳定的分类效率
- 对小规模的数据表现很好,能个处理多分类任务,适合增量式训练,尤其是数据量超出内存时,我们可以一批批的去增量训练
- 对缺失数据不太敏感,算法也比较简单,常用于文本分类
- 算法逻辑简单,易于实现,分类过程中时空开销小
缺点:
- 理论上,朴素贝叶斯模型与其他分类方法相比具有最小的误差率。但是实际上并非总是如此,这是因为朴素贝叶斯模型给定输出类别的情况下,假设属性之间相互独立,这个假设在实际应用中往往是不成立的,在属性个数比较多或者属性之间相关性较大时,分类效果不好。而在属性相关性较小时,朴素贝叶斯性能最为良好。对于这一点,有半朴素贝叶斯之类的算法通过考虑部分关联性适度改进
- 需要知道先验概率,且先验概率很多时候取决于假设,假设的模型可以有很多种,因此在某些时候会由于假设的先验模型的原因导致预测效果不佳
- 由于我们是通过先验和数据来决定后验的概率从而决定分类,所以分类决策存在一定的错误率
- 对输入数据的表达形式很敏感
参考链接: