朴素贝叶斯算法综述

时间:2024-03-31 07:44:44
  • 朴素贝叶斯(Naive Bayers)是一种基于概率统计的分类方法。
  • 朴素贝叶斯在条件独立假设的基础上,使用贝叶斯定理构建算法,在本文处理领域有广泛的应用。

条件独立假设:用于分类的特征在类确定的条件下都是条件独立的。

朴素贝叶斯方法实际上学习到的是生成数据的机制。

  • 贝叶斯定理(Bayes theorem):

P(BiA)=P(Bi)P(ABi)j=1nP(Bj)P(ABj) P(B_i|A) = \frac{P(B_i)P(A|B_i)}{\sum_{j=1}^{n}P(B_j)P(A|B_j)}

朴素贝叶斯分类法

从训练数据集中,计算类别的先验分布 P(Y)P(Y) 和条件概率分布 P(XY)P(X|Y),然后就可以统计出联合概率分布 P(X,Y)=P(Y)P(XY)P(X,Y)=P(Y)P(X|Y)(就是贝叶斯公式分子的部分),进而得到后验概率分布。概率估计的方法可以是极大似然估计(其实就是数数字)或者贝叶斯估计(在数数字的基础上加上了拉普拉斯平滑)。

后验概率最大的类作为 xx 的输出(即每一个类别的概率都要算一遍,然后取概率最大的):
P(Y=ckX=x), P(Y=c_k|X=x),
所以,朴素贝叶斯分类器可以表示为:

y=f(x)=argmaxckP(Y=ck)jP(X(j)=x(j)Y=ck)kP(Y=ck)jP(X(j)=x(j)Y=ck) y = f(x) = \arg \max_{c_k} \frac{P(Y=c_k)\prod_{j}P(X^{(j)}=x^{(j)}|Y=c_k)}{\sum_k P(Y=c_k)\prod_{j}P(X^{(j)}=x^{(j)}|Y=c_k)}

朴素贝叶斯算法将实例分到“后验概率最大”的类中,这等价于期望风险最小化。

定义 0-1 损失函数,期望是对联合概率分布 P(X,Y)P(X,Y) 取的。

  • 理论上在做朴素贝叶斯的时候,先验概率和条件概率就是简单的数数字就可以完成了,这里用样本概率估计总体概率的方法叫做极大似然估计(即我们通过样本得到的概率值,就作为我们先验概率和条件概率的估计值)
  • 如果出现了概率为 0 的情况,就要使用贝叶斯估计了:
    常常取一个 λ=1\lambda=1 ,在分子分母同时做加法,使得分子分母都不为0。

(1)先验概率的贝叶斯估计

Pλ(Y=ck)=i=1NI(yi=ck)+λN+Kλ P_{\lambda} (Y=c_k) = \frac{\sum_{i=1}^{N}I(y_i=c_k)+\lambda}{N+K\lambda}

(2)条件概率的贝叶斯估计

Pλ(X(j)=ajlY=ck)=i=1NI(xi(j)=ajl,yi=ck)+λi=1NI(yi=ck)+Sjλ P_{\lambda} (X^{(j)}=a_{jl}|Y=c_k) = \frac{\sum_{i=1}^{N}I(x_i^{(j)}=a_{jl},y_i=c_k)+\lambda}{\sum_{i=1}^{N} I(y_i=c_k)+S_j\lambda}

SjS_j 表示第 jj 个特征 unique 以后得到的数,即第 jj 个特征的不同取值的个数。满足非负性和归一性,因此是概率分布
(1)二者的形式非常像。比起原来的数数字的方法而言,分子都加上 1,分母都加上的是这个类别的个数(去掉了重复);
(2)可以看看《统计学习方法》 P52例2,一下子就看懂了。

因为分母对所有的 ckc_k 都是相同的,所以,只看分子就好了。
7、后验概率最大化的含义:后验概率最大化等价于 0-1 损失函数时的期望风险最小化。
期望风险是损失函数对于联合概率分布的期望。

理解这个公式的文章:https://blog.csdn.net/zhengjihao/article/details/78064121

1、用于分类:朴素贝叶斯算法是使用统计学方法的一种分类方法。
基于的假设是:对于已知的类别 ,朴素贝叶斯分类器在估计类条件概率的时候假设特征之间条件独立(条件独立性)。这个假设使得原本难以计算的条件联合概率转化为每个类别的条件概率的乘积,尤其是在特征很多的时候,就显得很简便。
如果没有这个假设,就得遍历所有不同的条件组合,需要大量样本的支持。
具体方法是:比较独立特征的条件概率(这句话不严谨),将概率最大的那个类别,作为该样本的类别。
2、条件概率的定义,乘法原理就可以推导出贝叶斯公式。从贝叶斯公式中得出先验概率(两个先验概率,其中一个是标准化常量,因为它作为分母)、后验概率、条件概率、似然的定义。计算条件概率的时候,前提和结果可以反过来。

3、频率学派和贝叶斯学派
频率学派:认为概率是一个常数,是固定值,虽然未知但是是客观的。重点研究样本的分布。
贝叶斯学派:认为概率是人的主观概念,代表了对事件发生的相信程度。重点研究参数的分布。
4、朴素贝叶斯分类器是一种常见的且简单有效的贝叶斯分类算法。

拉普拉斯修正(Laplacian correction)

数值型特征的处理:假设这个连续性特征呈现出高斯分布,先计算均值和标准差,然后代入公式计算得到条件概率,作为这个类别前提下特征的条件概率的估计值。

高斯朴素贝叶斯(Gaussian naive Bayes):假设每个标签的数据都服从简单的高斯分布。

多项式朴素贝叶斯(Multinomial naive Bayes):假设特征是由一个简单的多项式分布生成的。在词频统计这件事情上,使用多项式分布作为概率估计是合理的。

朴素贝叶斯算法优点

1、对大数量训练和查询时具有较高的速度。即使使用超大规模的训练集,针对每个项目通常也只会有相对较少的特征数,并且对项目的训练和分类也仅仅是特征概率的数学运算而已。分类效果稳健,特别适合于大规模的数据集。
2、支持增量式运算。即可以实时的对新增的样本进行训练。
3、朴素贝叶斯对结果解释容易理解。
4、天然地支持多分类任务。
5、天生支持概率分类。
6、对缺失的数据和噪声数据都不敏感

朴素贝叶斯算法缺点

1、由于使用了样本属性独立性的假设,所以如果样本属性有关联时其效果不好。特征之间的相互独立的假设在实际应用中往往是不成立的,在特征个数比较多或者特征之间相关性较大的时候,分类效果一般
2、需要知道先验概率,而先验概率很多时候取决于假设,假设的模型可以有很多种,因此在某些时候会由于假设的先验模型的原因导致预测效果不佳;
3、对输入数据的表达形式很敏感,应用在含有大量的数值特征的数据集的时候并不理想。
三、朴素贝叶斯应用领域
1、欺诈检测中使用较多
2、一封电子邮件是否是垃圾邮件
3、一篇文章应该分到科技、政治,还是体育类
4、一段文字表达的是积极的情绪还是消极的情绪?
5、人脸识别

朴素贝叶斯算法的应用场景

朴素贝叶斯分类器对数据有严格的假设,因此它的训练效果通常比复杂的模型差。
1、训练和预测的速度非常快;
2、直接使用概率预测
3、通常很容易解释
4、可调参数(如果有的话)非常少

扩展阅读:半朴素贝叶斯分类器

朴素贝叶斯算法综述

实例:文档分类

1、下载文档

from time import time
from sklearn.datasets import load_files
import os


news_train = load_files('./datasets/mlcomp/379/train')
print('end')
print("summary: {0} documents in {1} categories.".format(len(news_train.data), len(news_train.target_names)))
print("done in {0} seconds".format(time() - t))

2、文本特征预处理

  • TF-IDF 用于评估一个词语对于一份文档的重要程度,我们利用 TF-IDF 这个工具,把一篇文档转换成一个向量。

  • TF 表示词频,对于一份文档而言,词频是特定的词语在这篇文档里出现的次数除以这篇文档的词语总数。
    例如:某指定的一篇文档,一共有 1000 个词,其中“朴素贝叶斯”出现了 5 次,它的词频就是 0.005。

  • IDF 表示一个词的逆向文档频率指数(Inverse Document Frequency),由总文档数目,除以包含指定词语的文档的数目,再将商取对数得到,它表达的是词语的权重指数。
    例如:数据集一共有 10000 篇文档,“朴素贝叶斯”只出现在 10 篇文档中,则“朴素贝叶斯”的权重指数 IDF=log1000010=3{\rm IDF} = \log \frac{10000}{10} = 3

  • 具体是这么做的:
    1、构建词典,如果词典有 10000 个词语,则每一篇文档就可以表示成一个 10000 维的向量,每一个分量就计算 TF-IDF 的值作为特征;
    2、一篇文档里词的数量相对于词典的数量是很少的,所以一篇文档转换成向量以后,绝大多数分量都为 0,因此得到的是一个稀疏的词向量矩阵。

from sklearn.feature_extraction.text import TfidfVectorizer

vectorizer = TfidfVectorizer(encoding='latin-1')

X_train = vectorizer.fit_transform(news_train.data)

# 查看非零元素的个数 X_train[0].getnnz()

3、模型训练:送入朴素贝叶斯算法

刘建平《scikit-learn 朴素贝叶斯类库使用小结》一文中说道:

在 scikit-learn 中,一共有 3 个朴素贝叶斯的分类算法类。分别是 GaussianNBMultinomialNBBernoulliNB。其中 GaussianNB 就是先验为高斯分布的朴素贝叶斯,MultinomialNB 就是先验为多项式分布的朴素贝叶斯,而 BernoulliNB 就是先验为伯努利分布的朴素贝叶斯。

文档分类问题中,文档的类别符合多项式分布,应该应该使用 MultinomialNB

多项式分布是指满足类别分布的实验,连续做 nn 次以后,每种类别出现的特定次数组合的概率分布情况。

  • alpha 表示平滑参数,其值越小,越容易过拟合;值太大,容易欠拟合。
from sklearn.naive_bayes import MultinomialNB

# MultinomialNB 表示多项式朴素贝叶斯
y_train = news_train.target
clf = MultinomialNB(alpha=0.0001)
clf.fit(X_train, y_train)
train_score = clf.score(X_train, y_train)
# 在训练数据集上的效果还是很不错的。

4、模型评价

from sklearn.metrics import classification_report

print(classification_report(y_test, pred,target_names=news_test.target_names))
from sklearn.metrics import confusion_matrix

cm = confusion_matrix(y_test,pred)
print(cm)

将混淆矩阵画成热力图:

# Show confusion matrix
plt.figure(figsize=(8, 8), dpi=100)
plt.title('Confusion matrix of the classifier')
ax = plt.gca()                                  
ax.spines['right'].set_color('none')            
ax.spines['top'].set_color('none')
ax.spines['bottom'].set_color('none')
ax.spines['left'].set_color('none')
ax.xaxis.set_ticks_position('none')
ax.yaxis.set_ticks_position('none')
ax.set_xticklabels([])
ax.set_yticklabels([])
plt.matshow(cm, fignum=1, cmap='gray')
plt.colorbar();

补充:如果数据的特征值是连续的话,可以使用高斯朴素贝叶斯进行分类。

# 假设特征呈正态分布

from sklearn import datasets
from sklearn.naive_bayes import GaussianNB
from sklearn.metrics import accuracy_score

iris = datasets.load_iris()
gnb = GaussianNB()
gnb.fit(iris.data, iris.target)
y_pred = gnb.predict(iris.data)
accuracy_score(iris.target, y_pred)

参考资料

1、李航《统计学习方法》第 4 章 朴素贝叶斯法
2、刘建平《scikit-learn 朴素贝叶斯类库使用小结》
https://www.cnblogs.com/pinard/p/6074222.html
3、scikit-learn 官方文档
http://scikit-learn.org/stable/modules/generated/sklearn.naive_bayes.MultinomialNB.html