当前位置:   article > 正文

朴素贝叶斯原理【详细介绍,一文看懂】_朴素贝叶斯分类的基本原理

朴素贝叶斯分类的基本原理

贝叶斯分类算法是统计学是一种概率分类方法,朴素贝叶斯分类时贝叶斯分类中最简单的一种。利用贝叶斯公式根据某特征的先验概率计算出其后延概率,然后选择具有最大后延概率的类作为该特征所属的类。朴素贝叶斯,称之为“朴素”,是因为整个形式化过程只做了最原始、最简单的假设,具体假设如下:

  1. 特征之间相互独立
  2. 每个特征同等重要

1. 概率相关

先验概率: 比如向女生表白成功的概率是20%,记为P(A)=20%

条件概率:在事件B发生的情况下,事件A发生的概率,用P(A|B)表示,具体计算公式如下。如帅的前提下,向女生表白成功的概率为50%,记为P(A|B)=50%。
P ( A ∣ B ) = P ( A ∩ B ) P ( B ) P ( A ∩ B ) = P ( A ∣ B ) P ( B ) P(A|B) = \frac{P(A∩B)}{P(B)}\\P(A∩B)=P(A|B)P(B) P(AB)=P(B)P(AB)P(AB)=P(AB)P(B)
同理可得:在事件A发生的情况下,事件B发生的概率,用P(B|A)表示,具体计算公式如下:
P ( B ∣ A ) = P ( A ∩ B ) P ( A ) P ( A ∩ B ) = P ( B ∣ A ) P ( A ) P(B|A) = \frac{P(A∩B)}{P(A)}\\P(A∩B)=P(B|A)P(A) P(BA)=P(A)P(AB)P(AB)=P(BA)P(A)

联合概率:事件A和B同时发生的概率 。比如,长得帅且向女生表白成功的概率为1%,记为P(A∩B)=1%

条件概率和联合概率之间的关系,可用下式表示
P ( A ∩ B ) = P ( A ∣ B ) P ( B ) = P ( B ∣ A ) P ( A ) P(A∩B)=P(A|B)P(B)=P(B|A)P(A) P(AB)=P(AB)P(B)=P(BA)P(A)
所以就会有:
P ( A ∣ B ) = P ( B ∣ A ) P ( A ) P ( B ) P(A|B) = \frac{P(B|A)P(A)}{P(B)} P(AB)=P(B)P(BA)P(A)
全概率: 如果事件A不是一个条件,而是一堆条件,这些条件互斥且能穷尽所有可能 。则对任意一个事件B则有
P ( B ) = ∑ i = 1 m P ( B ∣ A i ) P ( A i ) P(B)=\sum_{i=1}^{m}{P(B|A_i)P(A_i)} P(B)=i=1mP(BAi)P(Ai)

2. 贝叶斯准则

如果已知P(B|A_i),要求P(A_i|B),应用贝叶斯准则得到:
P ( A i ∣ B ) = P ( B ∣ A i ) P ( A i ) P ( B ) P(A_i|B)=\frac{P(B|A_i)P(A_i)}{P(B)} P(AiB)=P(B)P(BAi)P(Ai)

要求解 P ( A i ∣ B ) P(A_i|B) P(AiB),只需要知道 P ( A i ) P(A_i) P(Ai) P ( B ∣ A i ) P(B|A_i) P(BAi)。因为对于同一个数据集,P(B)是一个常量,可以不参与计算。

先验概率 P ( A i ) P(A_i) P(Ai)的计算公式如下
P ( A i ) = ∣ D A i ∣ ∣ D ∣ P(A_i) = \frac{|D_{A_i}|}{|D|} P(Ai)=DDAi
其中, ∣ D A i ∣ |D_{A_i}| DAi表示数据集D中A_i类样本组成的样本数,|D|表示数据集D的样本数。

如果B是多维属性,那么可以假设 P ( B 1 ∣ A i ) , P ( B 2 ∣ A i ) , . . . , P ( B n ∣ A i ) P(B_1|A_i),P(B_2|A_i),...,P(B_n|A_i) P(B1Ai),P(B2Ai),...,P(BnAi)对应的事件是彼此独立的,这些值连乘在一起得到** P ( B ∣ A i ) P(B|A_i) P(BAi) ,具体计算公式如下**:
P ( B ∣ A i ) = P ( B 1 ∣ A i ) ∗ P ( B 2 ∣ A i ) ∗ ⋅ ⋅ ⋅ ∗ P ( B n ∣ A i ) P(B|A_i) = P(B_1|A_i)*P(B_2|A_i)*···*P(B_n|A_i) P(BAi)=P(B1Ai)P(B2Ai)P(BnAi)

3. 使用条件概率来分类

如果给定某个由 B 1 , B 2 , ⋅ ⋅ ⋅ , B n B_1,B_2,···,B_n B1,B2,,Bn属性表示的数据点,那么该数据点来自类别 A 1 A_1 A1的概率是多少?数据点来自类别 A 2 A_2 A2的概率有事多少?可以应用贝叶斯准则得到:
P ( A i ∣ B 1 , B 2 , ⋅ ⋅ ⋅ , B n ) = P ( B 1 , B 2 , ⋅ ⋅ ⋅ , B n ∣ A i ) P ( A i ) P ( B 1 , B 2 , ⋅ ⋅ ⋅ , B n ) P(A_i|B_1,B_2,···,B_n)=\frac{P(B_1,B_2,···,B_n|A_i)P(A_i)}{P(B_1,B_2,···,B_n)} P(AiB1,B2,,Bn)=P(B1,B2,,Bn)P(B1,B2,,BnAi)P(Ai)
使用这些定义,可以定义贝叶斯分类准则:

  • 如果 P ( A 1 ∣ B 1 , B 2 , . . . , B n ) > P ( A 2 ∣ B 1 , B 2 , . . . , B n ) P(A_1|B_1,B_2,...,B_n) > P(A_2|B_1,B_2,...,B_n) P(A1B1,B2,...,Bn)>P(A2B1,B2,...,Bn), 则属于类别A_1
  • 如果 P ( A 1 ∣ B 1 , B 2 , . . . , B n ) < = P ( A 2 ∣ B 1 , B 2 , . . . , B n ) P(A_1|B_1,B_2,...,B_n) <= P(A_2|B_1,B_2,...,B_n) P(A1B1,B2,...,Bn)<=P(A2B1,B2,...,Bn), 则属于类别A_2

使用贝叶斯准测,可以通过已知的三个概率值来计算未知的概率值。

4. 嫁还是不嫁?

通过嫁还是不嫁这个二分类问题,来更加了解朴素贝叶斯。假设由颜值,性格,是否上进这三个属性来决定最终嫁还是不嫁。如果现在有一个男生是:帅 & 性格不好 & 不上进,预测女生嫁还是不嫁该男生呢?

​ 数据集如下:

颜值性格是否上进是否嫁
上进
不帅一般不嫁
不帅不好不上进不嫁
一般
不帅上进
不好一般不嫁
不上进
不帅不好上进不嫁
不好上进
不帅不上进不嫁

由于朴素贝叶斯公式如下:
P ( A ∣ B ) = P ( B ∣ A ) P ( A ) P ( B ) P(A|B) = \frac{P(B|A)P(A)}{P(B)} P(AB)=P(B)P(BA)P(A)
换种更清楚的表达如下:

P ( 类 别 ∣ 特 征 ) = P ( 特 征 ∣ 类 别 ) P ( 类 别 ) P ( 特 征 ) P(类别|特征) = \frac{P(特征|类别)P(类别)}{P(特征)} P()=P()P()P()

在这个例子中,就是要求 P ( 嫁 ∣ 帅 , 性 格 不 好 , 不 上 进 ) P(嫁|帅,性格不好,不上进) P(,,) P ( 不 嫁 ∣ 帅 , 性 格 不 好 , 不 上 进 ) P(不嫁|帅,性格不好,不上进) P(,,)这两个概率,选取概率大的来做决策。

通过朴素贝叶斯公式:
P ( 嫁 ∣ 帅 , 性 格 不 好 , 不 上 进 ) = P ( 帅 , 性 格 不 好 , 不 上 进 ∣ 嫁 ) P ( 嫁 ) P ( 帅 , 性 格 不 好 , 不 上 进 ) P ( 不 嫁 ∣ 帅 , 性 格 不 好 , 不 上 进 ) = P ( 帅 , 性 格 不 好 , 不 上 进 ∣ 不 嫁 ) P ( 不 嫁 ) P ( 帅 , 性 格 不 好 , 不 上 进 ) P(嫁|帅,性格不好,不上进)=\frac{P(帅,性格不好,不上进|嫁)P(嫁)}{P(帅,性格不好,不上进)}\\P(不嫁|帅,性格不好,不上进)=\frac{P(帅,性格不好,不上进|不嫁)P(不嫁)}{P(帅,性格不好,不上进)} P(,,)=P(,,)P(,,)P()P(,,)=P(,,)P(,,)P()
在这两个公式里,因为 P ( 帅 , 性 格 不 好 , 不 上 进 ) P(帅,性格不好,不上进) P(,,)都是一样的,所以,想要获取 P ( 嫁 ∣ 帅 , 性 格 不 好 , 不 上 进 ) P(嫁|帅,性格不好,不上进) P(,,) P ( 不 嫁 ∣ 帅 , 性 格 不 好 , 不 上 进 ) P(不嫁|帅,性格不好,不上进) P(,,)这两个概率中的最大值,就等价于求 P ( 帅 , 性 格 不 好 , 不 上 进 ∣ 嫁 ) P ( 嫁 ) P(帅,性格不好,不上进|嫁)P(嫁) P(,,)P() P ( 帅 , 性 格 不 好 , 不 上 进 ∣ 不 嫁 ) P ( 不 嫁 ) P(帅,性格不好,不上进|不嫁)P(不嫁) P(,,)P()中的最大值。只需计算出**P(帅,性格不好,不上进|嫁)、P(帅,性格不好,不上进|不嫁)、P(嫁)、P(不嫁)**这四个概率,即可求出 P ( 嫁 ∣ 帅 , 性 格 不 好 , 不 上 进 ) P(嫁|帅,性格不好,不上进) P(,,) P ( 不 嫁 ∣ 帅 , 性 格 不 好 , 不 上 进 ) P(不嫁|帅,性格不好,不上进) P(,,)这个两个概率中最大概率对应的类别。

由于
P ( 嫁 ) = 1 2 P ( 不 嫁 ) = 1 2 P ( 帅 , 性 格 不 好 , 不 上 进 ∣ 嫁 ) = P ( 帅 ∣ 嫁 ) ∗ P ( 性 格 不 好 ∣ 嫁 ) ∗ P ( 不 上 进 ∣ 嫁 ) = 4 5 ∗ 1 5 ∗ 1 5 = 4 125 P ( 帅 , 性 格 不 好 , 不 上 进 ∣ 不 嫁 ) = P ( 帅 ∣ 不 嫁 ) ∗ P ( 性 格 不 好 ∣ 不 嫁 ) ∗ P ( 不 上 进 ∣ 不 嫁 ) = 1 5 ∗ 3 5 ∗ 2 5 = 6 125 P(嫁)=\frac{1}{2}\\P(不嫁)=\frac{1}{2}\\P(,,|)=P(|)P(|)P(|)=451515=4125\\P(,,|)=P(|)P(|)P(|)=153525=6125 P()=21P()=21P(,,)=P()P()P()=545151=1254P(,,)=P()P()P()=515352=1256
则有
P ( 帅 , 性 格 不 好 , 不 上 进 ∣ 嫁 ) P ( 嫁 ) = 4 125 ∗ 1 2 = 2 125 P ( 帅 , 性 格 不 好 , 不 上 进 ∣ 不 嫁 ) P ( 不 嫁 ) = 6 125 ∗ 1 2 = 3 125 P(,,|)P()=412512=2125\\P(,,|)P()=612512=3125 P(,,)P()=125421=1252P(,,)P()=125621=1253
由于
P ( 帅 , 性 格 不 好 , 不 上 进 ∣ 嫁 ) P ( 嫁 ) < P ( 帅 , 性 格 不 好 , 不 上 进 ∣ 不 嫁 ) P ( 不 嫁 ) P(帅,性格不好,不上进|嫁)P(嫁)<P(帅,性格不好,不上进|不嫁)P(不嫁) P(,,)P()<P(,,)P()
所以, 根据朴素贝叶斯算法可以给这个女生答案,是不嫁

5. 朴素贝叶斯种类

在sklearn中,朴素贝叶斯种类有三种,分别是GaussianNB、MultinomialNB和BernoulliNB。

5.1 高斯朴素贝叶斯(GaussianNB)

GaussianNB是先验为高斯分布(正态分布)的朴素贝叶斯,假设每个标签的数据都服从高斯分布(正态分布)。正态分布的概率密度函数计算公式如下
P ( X i = x i ∣ Y = C k ) = 1 2 π σ k 2 e − ( x i − μ k ) 2 2 σ k 2 P(X_i=x_i|Y=C_k)= \frac{1}{\sqrt{2\pi\sigma_{k}^2}}e^{-\frac{(x_i-\mu_{k})^2}{2\sigma_{k}{^2}}} P(Xi=xiY=Ck)=2πσk2 1e2σk2(xiμk)2
其中, C k C_k Ck为Y的第k类类别。 μ k \mu_{k} μk σ k 2 \sigma_{k}{^2} σk2为第k类样本在第i个属性上的取值的均值和方差。

sklearn中的GaussianNB实现

下面采用sklearn中的鸾尾花数据集,由于数据集都是连续属性,所以采用GaussianNB来进行实现,看下预测情况。

# 导入包
from sklearn.naive_bayes import GaussianNB  # 高斯分布,假定特征服从正态分布的
from sklearn.model_selection import train_test_split # 数据集划分
from sklearn.metrics import accuracy_score

# 导入数据集
from sklearn import datasets
iris = datasets.load_iris()

# 拆分数据集,random_state:随机数种子
train_x,test_x,train_y,test_y = train_test_split(iris.data,iris.target,random_state=12) 

# 建模
gnb_clf = GaussianNB()
gnb_clf.fit(train_x,train_y)

# 对测试集进行预测
# predict():直接给出预测的类别
# predict_proba():输出的是每个样本属于某种类别的概率
predict_class = gnb_clf.predict(test_x)
# predict_class_proba = gnb_clf.predict_proba(test_x)
print("测试集准确率为:",accuracy_score(test_y,predict_class))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

运行结果如下

测试集准确率为: 0.9736842105263158

可以看到,测试集准确率97%,准确率挺高。

5.2 多项式朴素贝叶斯(MultinomialNB)

多项式朴素贝叶斯是先验为多项式分布的朴素贝叶斯。 它假设特征是由一个简单多项式分布生成的。多项分布可以描述各种类型样本出现次数的概率,因此多项式朴素贝叶斯非常适合用于描述出现次数的特征。该模型常用于文本分类,特征表示的是次数,例如某个词语的出现次数。

多项式分布

多项式分布来源于统计学中的多项式实验,这种实验可以解释为:实验包括n次重复试验,每次试验都有不同的可能结果。在任何给定的试验中,特定结果发生的概率是不变的。

多项式分布公式
P ( X = x i ∣ Y = c ) = ∣ D c , x i ∣ + λ ∣ D c ∣ + λ N i P(X=x_{i}|Y=c)= \frac{|D_{c,x_i}|+\lambda}{|D_c|+\lambda N_i} P(X=xiY=c)=Dc+λNiDc,xi+λ
其中, P ( X = x i ∣ Y = c ) P(X=x_{i}|Y=c) P(X=xiY=c)表示c类别下第i个属性上取值为 x i x_i xi的条件概率。 ∣ D c , x i ∣ |D_{c,x_i}| Dc,xi是c类别下第i个属性上取值为 x i x_i xi的样本数, ∣ D c ∣ |D_c| Dc是c类的样本数。 N i N_i Ni表示第i个属性可能的取值数。λ被称为平滑系数,令λ>0来防止训练数据中出现过的一些词汇没有出现在测试集中导致的0概率。如果λ=1,则这个平滑叫做拉普拉斯平滑,λ<1,叫做利德斯通平滑。

sklearn中的MultinomialNB实现

多项式所涉及的特征往往是次数,频率,计数这样的概念,这些概念都是离散的正整数,因此,sklearn中的MultinomialNB不接受负值的输入

MultinomialNB包含如下的参数和属性:

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

其中

  • alpha : 浮点数, 可不填 【默认为1.0】

平滑系数λ,如果为0,则表示完全没有平滑选项。需注意,平滑相当于人为给概率加上一些噪音,因此λ设置得越大,精确性会越低(虽然影响不是非常大)

  • fit_prior : 布尔值, 可不填【默认为True】

    是否学习先验概率P(Y=c)。如果为False,则所有的样本类别输出都有相同的类别先验概率。即认为每个标签类出现的概率是1/总类别数

  • class_prior:形似数组的结构,结构为(n_classes,),可不填【默认为None】
    表示类的先验概率P(Y=c)。如果没有给出具体的先验概率则自动根据数据来进行计算。

    总结如下:

fit_priorclass_prior最终先验概率
False填或不填都没有意义 P ( Y = c k ) = 1 / k P(Y=c_k)=1/k P(Y=ck)=1/k
True不填 P ( Y = c k ) = m k / m P(Y=c_k)=m_k/m P(Y=ck)=mk/m
True P ( Y = c k ) = P(Y=c_k)= P(Y=ck)=class_prior

其中,k为总类别数,m为训练集样本总数量, m k m_k mk为输出为第k个类别的训练集样本数。

实例

建一个简单多项式朴素贝叶斯(让所有的参数保持默认)的例子。

# 导⼊入需要的模块和库
from sklearn.naive_bayes import MultinomialNB
import numpy as np
# 建立数据集
X = np.random.randint(5, size=(6, 100))
y = np.array([1, 2, 3, 4, 5, 6])
# 建立一个多项式朴素贝叶斯分类器
mnb = MultinomialNB(alpha=1.0, fit_prior=True, class_prior=None)
mnb.fit(X, y)
# 由于概率永远是在[0,1]之间,mnb给出的是对数先验概率,因此返回的永远是负值
# 类先验概率=各类的个数/类的总个数
print("类先验概率:", np.exp(mnb.class_log_prior_))

# 返回一个固定标签类别下的每个特征的对数概率log(P(Xi | y))
# print("每个特征的对数概率:",mnb.feature_log_prob_)
# '''重要属性:在fit时每个标签类别下包含的样本数。
# 当fit接口中的sample_weight被设置时,
# 该接口返回的值也会受到加权的影响'''
print("每个标签类别下包含的样本数:",mnb.class_count_)
print("预测的分类:", mnb.predict([X[2]]))  # 输出3
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

运行结果如下:

在这里插入图片描述

5.3 伯努利朴素贝叶斯(BernoulliNB)

BernoulliNB就是先验为伯努利分布的朴素贝叶斯。假设特征的先验概率为二元伯努利分布,在文本分类中 ,就是一个特征有没有在一个文档中出现。

伯努利分布公式如下
P ( X = x i ∣ Y = c ) = P ( x i = 1 ∣ Y = c ) x i + P ( x i = 0 ∣ Y = c ) x i P(X=x_{i}|Y=c)= P(x_i=1|Y=c)x_{i}+P(x_i=0|Y=c)x_{i} P(X=xiY=c)=P(xi=1Y=c)xi+P(xi=0Y=c)xi
此时, x i x_{i} xi只能取0和1。

由于 x i = 0 x_i=0 xi=0,所以上式可变为
P ( X = x i ∣ Y = c ) = P ( x i = 1 ∣ Y = c ) ∗ 1 = ∣ D c , x i = 1 ∣ + λ ∣ D c ∣ + λ × 2 P(X=xiY=c)=P(xi=1Y=c)1=Dc+λ×2Dc,xi=1+λ
∣ D c , x i = 1 ∣ |D_{c,x_i=1}| Dc,xi=1是c类别下第i个属性上取值为1的样本数, ∣ D c ∣ |D_c| Dc是c类的样本数。 2 2 2表示第i个属性可能的取值数,这里只有0和1两种取值,所以是2。

sklearn中的BernoulliNB实现

类BernoulliNB包含如下的参数和属性:

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

其中

binarize:将数据特征二值化的阈值,大于binarize的值处理为1 ,小于等于binarize的值处理为0;

其他参数说明见5.2中多项式的参数说明;

实例

先来建一个简单伯努利朴素贝叶斯的例子。

import numpy as np
from sklearn.naive_bayes import BernoulliNB  # 伯努利朴素贝叶斯
x = np.array([[1, 2, 3, 4], [1, 3, 4, 4], [2, 4, 5, 5]])
y = np.array([1, 1, 2])
bnb = BernoulliNB(alpha=2.0, binarize=3.0, fit_prior=True)
bnb.fit(x, y)
print("预测结果:\n",bnb.predict(np.array([[1, 2, 3, 4]])))  # 输出1
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

打印相关属性语句如下:

# class_log_prior_:类先验概率对数值
print("类先验概率对数值:",bnb.class_log_prior_)
# 类先验概率=各类的个数/类的总个数
print("类先验概率:",np.exp(bnb.class_log_prior_))

# feature_log_prob_:指定类的各特征概率(条件概率)对数值
print("指定类的各特征概率(条件概率)对数值:\n",bnb.feature_log_prob_)
print("指定类的各特征概率(条件概率):\n", np.exp(bnb.feature_log_prob_))

# 用伯努利分布公式计算,结果与上面的一样
p_A_c1 = [(0 + 2) / (2 + 2 * 2) * 1,
          (0 + 2) / (2 + 2 * 2) * 1,
          (1 + 2) / (2 + 2 * 2) * 1,
          (2 + 2) / (2 + 2 * 2) * 1]
#          A   λ     B   λ
# 上面A列表示:类别1中1的个数
# 上面B列表示:类别1中样本数
p_A_c2 = [(0 + 2) / (1 + 2 * 2) * 1,
          (1 + 2) / (1 + 2 * 2) * 1,
          (1 + 2) / (1 + 2 * 2) * 1,
          (1 + 2) / (1 + 2 * 2) * 1]

feature_prob = [p_A_c1,p_A_c2]
print("公式计算得到的指定类的各特征概率:\n",np.array(feature_prob))

# class_count_:按类别顺序输出其对应的样本数
print("各类别的样本数:\n",bnb.class_count_)

# feature_count_:各类别各特征值之和,按类的顺序输出
print("各类别各特征值之和:\n",bnb.feature_count_)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

运行结果如下

在这里插入图片描述

小结

  • 如果样本特征的分布大部分是连续值(如人的身高,体重等),建议使用GaussianNB会比较好;

  • 如果样本特征的分布大部分是多元离散值(如在文档分类中特征是单词出现次数),建议使用MultinomialNB比较好;

  • 如果样本特征是二元离散值(如在文档分类中特征是单词是否出现) ,建议使用BernoulliNB比较好。

朴素贝叶斯算法优缺点

优点: 在属性相关性较小时效果较好,可以处理多类别问题;算法逻辑简单,易于实现 ;

缺点: 在属性个数比较多或者属性之间相关性较大时,分类效果不好;

如果本文对你有帮助,记得“点赞”哦~

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/运维做开发/article/detail/869213
推荐阅读
相关标签
  

闽ICP备14008679号