朴素贝叶斯分类器

思维导图

在这里插入图片描述

第一章 简介

        朴素贝叶斯分类器是一种监督式机器学习,它常常被用于分类任务,比如,文本分类。它也是一种生成式机器学习算法,换句话说,通过该模型可以寻找给定类别特征的分布。

第二章 预备知识

        朴素贝叶斯算法也叫概率算法,因为它基于贝叶斯理论。如果没有概率统计知识,很难解释该算法。

2.1 随机事件和运算

2.1.1 随机事件

定义 2.1.1   一个试验如果满足下述条件:
        (1) 相同条件下,可以重复进行;
        (2) 试验所有可能结果不止一个,并且在试验之前这些结果都是已知的;
        (3) 试验之后所得的结果是事先无法预知的。
我们把这种试验称为随机试验

定义 2.1.2   一次随机试验可能出现的所有结果的集合,我们称为样本空间,通常用 Ω \Omega Ω 表示。其中,样本空间集合的一个子集我们称为随机事件,通常用大写英文字母 A , B , … A, B, \dots A,B,来表示。

定义 2.1.3   每次试验中,必然会出现的结果,称为必然事件,用 Ω \Omega Ω 表示必然事件囊括了所有的样本点。而每次试验中必然不会出现的结果,称为不可能事件,用 ∅ \empty 表示不可能事件中没有囊括任何样本点。

2.1.2 随机事件之间的关系和运算

        在样本空间中 Ω \Omega Ω(全集) 中有很多事件(子集),为了研究他们的规律,将给出如下事件之间的关系和运算的定义。既然事件是一个集合,必然满足集合的关系和运算。
1. 随机事件的关系

    (1) 包含关系
          如果事件 A A A 的发生必然导致事件 B B B 发生,则称事件 B B B 包含于事件 A A A,记为 B ⊂ A B \subset A BA

    (2) 相等关系
          如果 A ⊂ B A \subset B AB 并且 B ⊃ A B \supset A BA,则称事件 A A A 与事件 B B B 相等,记为 A = B A = B A=B

    (3) 互不相容
          如果事件 A A A B B B 不能同时发生,也就是说 A B AB AB 是不可能事件,即 AB = ∅ \empty ,则称事件 A A A 与事件 B B B 互不相容(互斥)。

    (4) 对立
          若事件 A A A B B B 互不相容,且它们的和事件为必然事件,即 AB = ∅ \empty A ∪ B = Ω A \cup B = \Omega AB=Ω 则称事件 A A A 与事件 B B B 互为对立事件或互为逆事件, 事件 A A A 的逆事件,记为 A ‾ \overline{A} A

2. 随机事件的运算

     (1) 两个事件的并或和事件
          如果事件 A A A B B B 中至少有一个发生,这样的事件称作 A A A B B B 的并(或和),记为 A ∪ B A \cup B AB

     (2) 两个事件的交或积事件
          如果事件 A A A B B B 同时发生,这样的事件称作 A A A B B B 的交(或积),记为 A ∩ B A \cap B AB

     (3) 两个事件差事件
          如果事件 A A A 发生与而 事件 B B B 不发生,这样的事件称作 A A A B B B 的差,记为 A − B A - B AB

3. 随机事件的运算性质
     (1) 交换律
           A ∪ B = B ∪ A A \cup B = B \cup A AB=BA A ∩ B = B ∩ A A \cap B = B \cap A AB=BA
     (2) 结合律
           A ∪ ( B ∪ C ) = ( A ∪ B ) ∪ C A \cup (B \cup C) = (A \cup B) \cup C A(BC)=(AB)C A ∩ ( B ∩ C ) = ( A ∩ B ) ∩ C A \cap (B \cap C) = (A \cap B) \cap C A(BC)=(AB)C
     (3) 分配律
           A ∩ ( B ∪ C ) = ( A ∩ B ) ∪ ( A ∩ C ) A \cap (B \cup C) = (A \cap B) \cup (A \cap C) A(BC)=(AB)(AC) A ∪ ( B ∩ C ) = ( A ∪ B ) ∩ ( A ∪ C ) A \cup (B \cap C) = (A \cup B) \cap (A \cup C) A(BC)=(AB)(AC)
     (4) 摩尔根对偶律
           A ∪ B ‾ = B ‾ ∩ A ‾ \overline{A \cup B} = \overline{B} \cap \overline{A} AB=BA A ∩ B ‾ = B ‾ ∪ A ‾ \overline{A \cap B} = \overline{B} \cup \overline{A} AB=BA

2.2 概率与频率

2.2.1 频率

定义 2.2.1    如果随机事件 A A A N N N 次随机试验中发生了 n n n 次,称
f ( A ) = n N f(A) = \frac{n}{N} f(A)=Nn A A A 的频率。

2.2.2 概率

定义 2.2.2    随机事件 A A A 发生可能性的的度量,称为 A A A 发生的概率,记为 P ( A ) P(A) P(A)

2.2.3 频率与概率的关系

        设随机事件 A A A N N N 次重复试验中发生了 n n n次。若 N N N 很大时, f ( A ) f(A) f(A) 总在某个值附近来回摆动,且随试验次数的增加,其摆幅越来越小,则这个数值称为频率的稳定值。因此,可以通过频率来度量概率的一个近似值(详见2.4 大数定理)。

2.3 贝叶斯定理

2.3.1 条件概率

定义 2.3.1   设 A A A B B B 是样本空间 Ω \Omega Ω 中的两个事件,若 P ( B ) > 0 P(B)>0 P(B)>0 ,则称
P ( A ∣ B ) = P ( A B ) P ( B ) P(A | B) = \frac{P(AB)}{P(B)} P(AB)=P(B)P(AB)
B B B 发生下 A A A 的条件的概率

定义 2.3.2   由条件概率 P ( A ∣ B ) = P ( A B ) P ( B ) P(A | B) = \frac{P(AB)}{P(B)} P(AB)=P(B)P(AB) P ( B ) > 0 P(B)>0 P(B)>0 ,得
P ( A B ) = P ( A ∣ B ) P ( B ) P(AB)= P(A | B) P(B) P(AB)=P(AB)P(B)
以上公式称为乘法公式

乘法公式推广
        设 A 1 , A 2 , … , A n A_1, A_2, \dots , A_n A1,A2,,An ,并且 P ( A 1 A 2 … A n − 1 ) > 0 P(A_1A_2\dots A_{n-1}) > 0 P(A1A2An1)>0,则
P ( A 1 A 2 … A n ) = P ( A 1 ) P ( A 2 ∣ A 1 ) P ( A 3 ∣ A 1 A 2 ) … P ( A n ∣ A 1 … A n − 1 ) P(A_1A_2\dots A_n) = P(A_1)P(A_2|A_1)P(A_3|A_1A_2)\dots P(A_n|A_1\dots A_{n-1}) P(A1A2An)=P(A1)P(A2A1)P(A3A1A2)P(AnA1An1)

2.3.2 全概率

定义 2.3.3   设有一事件组 B 1 , B 2 , … , B n B_1, B_2, \dots , B_n B1,B2,,Bn ,若满足:
        (1)    ∪ i = 1 n B i = Ω \cup_{i=1}^{n}B_i = \Omega i=1nBi=Ω
        (2)    B i B j = ∅ , i ≠ j , i , j = 1 , 2 , … , n B_iB_j = \empty , i \neq j, i, j = 1, 2, \dots , n BiBj=,i=j,i,j=1,2,,n
称该事件组为完备事件组

定理 2.3.1   设有一事件组 B 1 , B 2 , … , B n B_1, B_2, \dots , B_n B1,B2,,Bn 为完备事件组,则对任意事件 A A A ,有
P ( A ) = ∑ i = 1 n P ( B i ) P ( A ∣ B i ) P(A) = \sum_{i=1}^{n}P(B_i)P(A|B_i) P(A)=i=1nP(Bi)P(ABi)
以上定理称为全概率公式。

2.3.3 贝叶斯公式

定理 2.3.2   设有一事件组 B 1 , B 2 , … , B n B_1, B_2, \dots , B_n B1,B2,,Bn 为完备事件组,则对任意事件 A A A ,若 P ( A ) > 0 P(A) > 0 P(A)>0,有
P ( B i ∣ A ) = P ( B i ) P ( A ∣ B i ) P ( A ) = P ( B i ) P ( A ∣ B i ) ∑ j = 1 n P ( B j ) P ( A ∣ B j ) P(B_i|A) = \frac{P(B_i)P(A|B_i)}{P(A)} = \frac{P(B_i)P(A|B_i)}{\sum_{j=1}^{n}P(B_j)P(A|B_j)} P(BiA)=P(A)P(Bi)P(ABi)=j=1nP(Bj)P(ABj)P(Bi)P(ABi)
以上定理称为贝叶斯公式。其中, P ( B i ) P(B_i) P(Bi) 为先验概率; P ( A ∣ B i ) P(A|B_i) P(ABi) 为似然或贝叶斯参数; P ( A ) P(A) P(A) 为证据; P ( B i ∣ A ) P(B_i|A) P(BiA) 为后验概率。

见解 1   贝叶斯定理的特点是它使用了顺序事件,其中后来获得的附加信息会影响初始概率。先验概率是事件在特定条件下被情景化之前的的初始概率或边际概率。后验概率是观察一段数据之后事件发生的概率。

2.3.4 随机事件的独立性

定义 2.3.4   对任意两个事件 A , B A, B A,B ,若满足:
P ( A B ) = P ( A ) P ( B ) P(AB) = P(A)P(B) P(AB)=P(A)P(B)
则称事件 A A A 与事件 B B B 相互独立。

2.4 大数定律

        数学中由这样一个现象:有时候一个有限的和很难求,但是从有限过渡到无限时,问题反而好办了。例如,对某一有限范围的 x x x 计算和
a n ( x ) = 1 + x + x 2 2 ! + x 3 3 ! + ⋯ + x n n ! a_n(x) = 1 + x + \frac{x^2}{2!} + \frac{x^3}{3!} + \dots + \frac{x^n}{n!} an(x)=1+x+2!x2+3!x3++n!xn
通过上式可以看出,当 n n n 固定的时候,很难求。但是对其求极限,则有了简单的结果:
lim ⁡ n → ∞ a n ( x ) = e x \lim_{n → \infty} a_n(x) = e^x nliman(x)=ex
n n n 很大的时候,我们可以把 e x e^x ex 作为 a n ( x ) a_n(x) an(x) 的近似值。
        在概率中也存在上述问题。如果 X 1 , X 2 , … , X n X_1, X_2, \dots,X_n X1,X2,Xn 是一些随机变量,则 X 1 + X 2 + ⋯ + X n X_1 + X_2 + \dots + X_n X1+X2++Xn 的分布很难计算,因此自然地会提出:利用极限的方法近似计算。事实证明这种想法是可能的。
        在概率论中有两类极限:一种是大数定理,另外一种是中心极限定理。在这里我们只讲大数定理。大数定理由概率统计定义"频率收敛于概率"引伸而来。为描述这一点,我们把频率通过一些随机变量的和表示出来。
        设 X X X n n n 次独立试验中某事件 A A A 发生的次数,且在每次试验中 A A A 发生的概率为 p p p,故引入随机变量 X 1 , X 2 , … , X n X_1, X_2, \dots,X_n X1,X2,Xn,其中
X i = { 1 , 若在第 i 次试验时事件 A 发生 0 , 若在第 i 次试验时事件 A 不发生 X_i= \begin{cases} 1, & 若在第 i 次试验时事件 A 发生 \\ 0, & 若在第 i 次试验时事件 A 不发生 \end{cases} Xi={1,0,若在第i次试验时事件A发生若在第i次试验时事件A不发生
由于 X 1 , X 2 , … , X n X_1, X_2, \dots,X_n X1,X2,Xn独立,则在 n n n 次试验中事件 A A A 一共出现了
X = X 1 + X 2 + ⋯ + X n X = X_1 + X_2 + \dots + X_n X=X1+X2++Xn,而频率为
p n = X 1 + ⋯ + X n n = X ^ n p_n = \frac{X_1 + \dots + X_n}{n} = \hat{X}_n pn=nX1++Xn=X^n
P ( A ) = p P(A) = p P(A)=p,则可以说,在某种意义下,当 n n n 很大时, p n p_n pn 接近 p p p p p p X i X_i Xi 的期望,故也可以写成:当 n n n 很大时, X ^ n \hat{X}_n X^n 接近 X i X_i Xi 的期望。大数定理时对这一点从理论的高度给予概括和论证。
定理 2.4.1   设 X 1 , X 2 , … , X n X_1,X_2,\dots,X_n X1X2Xn 是独立同分布的随机变量,记它们的均值为 a a a,又设它们的方差存在,并记为 σ \sigma σ,则对任意给定的 ξ > 0 \xi > 0 ξ>0
lim ⁡ n → ∞ P ( ∣ X ^ n − a ∣ ≥ ξ ) = 0 \lim_{n→\infty} P(|\hat{X} _n - a | \geq \xi) = 0 nlimP(X^naξ)=0

第三章 朴素贝叶斯分类器

        朴素贝叶斯分类器利用贝叶斯公式判断样本的类别,其计算公式如下:
P ( Y ∣ X ) = P ( Y ) P ( X ∣ Y ) P ( X ) (2-1) P(Y | X) = \frac{P(Y)P(X|Y)}{P(X)} \tag{2-1} P(YX)=P(X)P(Y)P(XY)(2-1)
其中, P ( Y ) P(Y) P(Y) 称为先验概率, P ( X ∣ Y ) P(X|Y) P(XY) 为条件概率, P ( Y ∣ X ) P(Y | X) P(YX)为后验概率。朴素贝叶斯分类器的推理工具是概率理论中的联合概率公式
P ( Y , X ) = P ( Y ) P ( X ∣ Y ) P(Y, X) = P(Y)P(X|Y) P(Y,X)=P(Y)P(XY)
        将贝叶斯公式引入机器学习,就需要把 X X X 当作样本特征, Y Y Y 当作样本的类别。先验概率 P ( Y ) P(Y) P(Y) 表示某个样本属于某个类别的概率,条件概率 P ( X ∣ Y ) P(X|Y) P(XY) 表示属于某个类别的样本具有某些特征值的概率,而后验概率 P ( Y ∣ X ) P(Y|X) P(YX) 表示具有某些特征值的样本属于某个类别的概率。

3.1 算法原理

        假设 X X X 是输入空间上的随机变量表示为 X = x 1 , x 2 , … , x n X = {x_1, x_2, \dots, x_n} X=x1,x2,,xn Y Y Y 是输出空间上的随机变量 Y = c 1 , c 2 , … , c k Y={c_1, c_2, \dots, c_k} Y=c1,c2,,ck。当进行朴素贝叶斯分类时,对给定的输入样本 x i ( i = 1 , 2 , … , n ) x_i (i=1, 2, \dots, n) xi(i=1,2,,n) ,通过学习到的模型计算后验概率 P ( Y = c j ∣ X = x i ) ( j = 1 , 2 , … , k ) P(Y=c_j | X=x_i) (j = 1, 2, \dots, k) P(Y=cjX=xi)(j=1,2,,k),取后验概率最大时相应的类别 c j c_j cj 作为样本 x i x_i xi 的输出。根据公式(2-1)可知后验概率计算方式如下:
P ( Y = c j ∣ X = x i ) = P ( Y = c j ) P ( X = x i ∣ Y = c j ) P ( X = x i ) (2-2) P(Y=c_j | X=x_i) = \frac{P(Y=c_j)P(X=x_i|Y=c_j)}{P(X=x_i)} \tag{2-2} P(Y=cjX=xi)=P(X=xi)P(Y=cj)P(X=xiY=cj)(2-2)
        在具体计算条件概率 P ( X = x i ∣ Y = c j ) P(X=x_i|Y=c_j) P(X=xiY=cj) 时,假设特征之间相互独立,则计算公式如下:
P ( X = x i ∣ Y = c j ) = P ( X ( 1 ) = x i ( 1 ) , … , X ( m ) = x i ( m ) ∣ Y = c j ) = ∏ s = 1 m P ( X ( s ) = x i ( s ) ∣ Y = c j ) (2-3) \begin{align} P(X=x_i | Y=c_j) &= P(X^{(1)}=x_i^{(1)}, \dots,X^{(m)}=x_i^{(m)}|Y=c_j) \notag \\ &= \prod_{s=1}^{m}P(X^{(s)}=x_i^{(s)}|Y=c_j) \notag \end{align} \tag{2-3} P(X=xiY=cj)=P(X(1)=xi(1),,X(m)=xi(m)Y=cj)=s=1mP(X(s)=xi(s)Y=cj)(2-3)
其中, x i ( s ) x_i^{(s)} xi(s)表示输入样本 x i x_i xi 的第 s s s 个特征的取值。
        将式 (2-3) 代入 (2-2) 中有
P ( Y = c j ∣ X = x i ) = ∏ s = 1 m P ( X ( s ) = x i ( s ) ∣ Y = c j ) P ( Y = c j ) P ( X = x i ) ( j = 1 , 2 , … , k ) P(Y=c_j | X=x_i) = \frac{\prod_{s=1}^{m}P(X^{(s)}=x_i^{(s)}|Y=c_j)P(Y=c_j)}{P(X=x_i)}(j=1,2,\dots, k) P(Y=cjX=xi)=P(X=xi)s=1mP(X(s)=xi(s)Y=cj)P(Y=cj)(j=1,2,,k)
        取概率最大的类别 c j c_j cj 为样本 x i x_i xi 的输出,则分类器可表示为:
y = f ( x i ) = arg max ⁡ c j ∏ s = 1 m P ( X ( s ) = x i ( s ) ∣ Y = c j ) P ( Y = c j ) P ( X = x i ) (2-4) y=f(x_i)=\argmax_{c_j}\frac{\prod_{s=1}^{m}P(X^{(s)}=x_i^{(s)}|Y=c_j)P(Y=c_j)}{P(X=x_i)} \tag{2-4} y=f(xi)=cjargmaxP(X=xi)s=1mP(X(s)=xi(s)Y=cj)P(Y=cj)(2-4)
        对所有类别 c j c_j cj,式 (2-4) 中分母都是相同的,所以可简化为:

y = f ( x i ) = arg max ⁡ c j ∏ s = 1 m P ( X ( s ) = x i ( s ) ∣ Y = c j ) P ( Y = c j ) y=f(x_i)=\argmax_{c_j} \prod_{s=1}^{m}P(X^{(s)}=x_i^{(s)}|Y=c_j)P(Y=c_j) y=f(xi)=cjargmaxs=1mP(X(s)=xi(s)Y=cj)P(Y=cj)

为了防止计算时,数值下溢。因此,从该函数两边取对数,将乘积变为求和,由于对数是递增函数,所以不影响分类。

y ^ = ln ⁡ f ( x i ) = arg max ⁡ c j ln ⁡ P ( Y = c j ) + ∑ s = 1 m ln ⁡ P ( X ( s ) = x i ( s ) ∣ Y = c j ) \hat{y}=\ln f(x_i)=\argmax_{c_j} \ln{P(Y=c_j)} + \sum_{s=1}^{m} \ln P(X^{(s)}=x_i^{(s)}|Y=c_j) y^=lnf(xi)=cjargmaxlnP(Y=cj)+s=1mlnP(X(s)=xi(s)Y=cj)

        由此可知,朴素贝叶斯算法最终需要通过训练集获取参数 P ( X ( s ) = x i ( s ) ∣ Y = c j ) P(X^{(s)}=x_i^{(s)}|Y=c_j) P(X(s)=xi(s)Y=cj) P ( Y = c j ) P(Y=c_j) P(Y=cj),这里使用极大似然估计法来估计参数的概率。
        令 D j D_j Dj 表示训练集中 c j c_j cj 类样本的集合,则条件概率如下计算:
P ( X ( s ) = x i ( s ) ∣ Y = c j ) = N j , x i ( s ) ∣ D j ∣ P(X^{(s)}=x^{(s)}_i|Y=c_j) = \frac{N_{j,x_i^{(s)}}}{|D_j|} P(X(s)=xi(s)Y=cj)=DjNj,xi(s)
        这里 N j , x i ( s ) N_{j,x_i^{(s)}} Nj,xi(s) 表示 D j D_j Dj 中第 s s s 个特征值为 x i ( s ) x_i^{(s)} xi(s) 的样本数量,这里称为特征变量, N j N_j Nj 表示 D j D_j Dj 中元素的个数,这里称为样本变量。
        先验概率计算方法如下:
P ( Y = c j ) = ∣ D j ∣ ∑ j = 1 k ∣ D j ∣ P(Y=c_j) = \frac{|D_j|}{\sum_{j=1}^{k}|D_j|} P(Y=cj)=j=1kDjDj
k k k 表示训练集中样本的类别个数。
        在类条件概率公式中,特征分量的某个取值在训练样本中一次都不出现,则会导致如果预测样本的特征分量取到这个值时,整个预测值为0。为了弥补,可以使用拉普拉斯平滑,具体做法给分子和分母同时加一个正数。如果特征分量的取值有k种情况,在分母加上k,每一类分子加1,这样就可以保证所有类条件概率的和为1。
P ( X ( s ) = x i ( s ) ∣ Y = c j ) = N j , x i ( s ) + 1 ∣ D j ∣ + k P(X^{(s)}=x^{(s)}_i|Y=c_j) = \frac{N_{j,x_i^{(s)}}+1}{|D_j|+k} P(X(s)=xi(s)Y=cj)=Dj+kNj,xi(s)+1

3.2 算法伪代码

        朴素贝叶斯算法分为训练和测试部分,训练包括计算训练集中每个特征值的条件概率和类别的先验概率,测试部分则是用训练好的参数对预测样本进行分类预测。这个定义集合 D j D_j Dj 中的元素的数量变量为 N j N_j Nj

3.3 算法实例

      例3.1 下表是训练数据学习的一个朴素贝叶斯分类器并确定,并确定 x = ( 2 , S ) T x=(2,S)^T x=(2,S)T的类标记为 y y y。表中 X ( 1 ) X^{(1)} X(1) X ( 2 ) X^{(2)} X(2)为特征,取值的集合分别为 A 1 = { 1 , 2 , 3 } A_1=\{1, 2, 3\} A1={1,2,3} A 2 = { S , M , L } A_2=\{S, M, L\} A2={S,M,L} Y Y Y为类标记, Y ∈ C = { 1 , − 1 } Y \in C=\{1, -1\} YC={1,1}

123456789101112131415
X(1) 111112222233333
X(2) SMMSSSMMLLLMMLL
Y-1-111-1-1-11111111-1

    根据素朴贝叶斯算法,计算下列概率:
P ( Y = 1 ) = 10 17 , P ( Y = − 1 ) = 7 17 P(Y=1)=\frac{10}{17},P(Y=-1)=\frac{7}{17} P(Y=1)=1710P(Y=1)=177
P ( X ( 1 ) = 1 ∣ Y = 1 ) = 3 12 , P ( X ( 1 ) = 2 ∣ Y = 1 ) = 4 12 , P ( X ( 1 ) = 3 ∣ Y = 1 ) = 5 12 P(X^{(1)}=1|Y=1)=\frac{3}{12},P(X^{(1)}=2|Y=1)=\frac{4}{12},P(X^{(1)}=3|Y=1)=\frac{5}{12} P(X(1)=1∣Y=1)=123P(X(1)=2∣Y=1)=124P(X(1)=3∣Y=1)=125
P ( X ( 2 ) = S ∣ Y = 1 ) = 2 12 , P ( X ( 2 ) = M ∣ Y = 1 ) = 5 12 , P ( X ( 2 ) = L ∣ Y = 1 ) = 5 12 P(X^{(2)}=S|Y=1)=\frac{2}{12},P(X^{(2)}=M|Y=1)=\frac{5}{12},P(X^{(2)}=L|Y=1)=\frac{5}{12} P(X(2)=SY=1)=122P(X(2)=MY=1)=125P(X(2)=LY=1)=125
P ( X ( 1 ) = 1 ∣ Y = − 1 ) = 4 9 , P ( X ( 1 ) = 2 ∣ Y = − 1 ) = 3 9 , P ( X ( 1 ) = 3 ∣ Y = − 1 ) = 2 9 P(X^{(1)}=1|Y=-1)=\frac{4}{9},P(X^{(1)}=2|Y=-1)=\frac{3}{9},P(X^{(1)}=3|Y=-1)=\frac{2}{9} P(X(1)=1∣Y=1)=94P(X(1)=2∣Y=1)=93P(X(1)=3∣Y=1)=92
P ( X ( 2 ) = S ∣ Y = − 1 ) = 4 9 , P ( X ( 2 ) = M ∣ Y = − 1 ) = 3 9 , P ( X ( 2 ) = L ∣ Y = − 1 ) = 2 9 P(X^{(2)}=S|Y=-1)=\frac{4}{9},P(X^{(2)}=M|Y=-1)=\frac{3}{9},P(X^{(2)}=L|Y=-1)=\frac{2}{9} P(X(2)=SY=1)=94P(X(2)=MY=1)=93P(X(2)=LY=1)=92
对于给定 x = ( 2 , S ) T x=(2,S)^T x=(2,S)T,计算
P ( Y = 1 ) P ( X ( 1 ) = 2 ∣ Y = 1 ) P ( X ( 2 ) = S ∣ Y = 1 ) = 0.0327 P ( Y = − 1 ) P ( X ( 1 ) = 2 ∣ Y = − 1 ) P ( X ( 2 ) = S ∣ Y = − 1 ) = 0.0610 P(Y=1)P(X^{(1)}=2|Y=1)P(X^{(2)}=S|Y=1)=0.0327 \\ P(Y=-1)P(X^{(1)}=2|Y=-1)P(X^{(2)}=S|Y=-1)=0.0610 P(Y=1)P(X(1)=2∣Y=1)P(X(2)=SY=1)=0.0327P(Y=1)P(X(1)=2∣Y=1)P(X(2)=SY=1)=0.0610
由于 P ( Y = − 1 ) P ( X ( 1 ) = 2 ∣ Y = − 1 ) P ( X ( 2 ) = S ∣ Y = − 1 ) P(Y=-1)P(X^{(1)}=2|Y=-1)P(X^{(2)}=S|Y=-1) P(Y=1)P(X(1)=2∣Y=1)P(X(2)=SY=1)值最大,所以给定 x x x的类别属于 − 1 -1 1类。

第四章 实践与应用

4.1 数据准备

https://archive.ics.uci.edu/static/public/73/mushroom.zip

4.2 核心代码

import numpy as np
from abc import abstractmethod, ABCMeta
from utils.common import label_binarize


class BaseDiscreteNB(metaclass=ABCMeta):
    @abstractmethod
    def _count(self, X, Y):
        """ 更新计数并计算概率.

        统计输入数据, 更新类别计数和特征计数.

        Parameters
        ----------
        X : {ndarray, sparse matrix} of shape (n_samples, n_features)
            输入样本.
        Y : ndarray of shape (n_samples, n_classes)
            二值化类别标签.
        """

    @abstractmethod
    def _update_feature_log_prob(self, alpha):
        """ 更新特征的对数概率.

        Parameters
        ----------
        alpha: float
            拉普拉斯光滑系数.
        """

    @abstractmethod
    def _joint_log_likelihood(self, X):
        """ 联合对数似然

        基于计数器预测输入样本的后验概率.

        Parameters
        ----------
        X: ndarray
            测试集
        """


class MyDiscreteNB(BaseDiscreteNB):
    def __init__(self) -> None:
        self.n_features = None
        self.classes_ = None

    def _init_counter(self, n_classes, n_features):
        self.n_features = n_features
        self.class_count_ = np.zeros(n_classes, dtype=np.float64)
        self.feature_count_ = [np.zeros((n_classes, 0)) for _ in range(n_features)]

    def _count(self, X, Y):
        """ 更新计数器

        Parameters
        ----------
        X: ndarray
            特征
        Y: ndarray
            独热编码类别
        """

        def _update_cat_count_dim(cat_count, highest_feature):
            """ 更新特征计数器的维度.

            Parameters
            ----------
            cat_count: ndarray
                每个特征的计数器.
            highest_feature: float
                每个特征的最大类别数目.
            """
            diff = highest_feature - cat_count.shape[1]
            if diff > 0:
                return np.pad(cat_count, [(0, 0), (0, diff)], 'constant')
            return cat_count

        def _update_cat_count(X_feature, Y, cat_count, n_classes):
            """ 更新特征计数器.

            Parameters
            ----------
            X_feature: ndarray
                特征.
            Y: ndarray
                独热编码类别.
            cat_count: ndarray
                特征计数器.
            n_classes: int
                类别数目
            """
            for j in range(n_classes):
                mask = Y[:, j].astype(bool)  # 同类掩码
                counts = np.bincount(X_feature[mask])  # 统计类别
                indices = np.nonzero(counts)[0]
                cat_count[j, indices] += counts[indices]

        self.class_count_ += Y.sum(axis=0)  # 更新类类别数目

        # 更新特征类别数目
        self.n_categories = X.max(axis=0) + 1  # 特征的类别数目
        for i in range(self.n_features):
            X_feature = X[:, i]
            self.feature_count_[i] = _update_cat_count_dim(self.feature_count_[i], self.n_categories[i])
            _update_cat_count(
                X_feature, Y, self.feature_count_[i], self.class_count_.shape[0]
            )
        pass

    def _update_feature_log_prob(self, alpha):
        feature_log_proba = []
        for i in range(self.n_features):
            smooth_feature_count = self.feature_count_[i] + alpha
            smooth_class_count = smooth_feature_count.sum(axis=1)
            feature_log_proba.append(np.log(smooth_class_count) - np.log(smooth_class_count.reshape(-1, 1)))
        return feature_log_proba

    def _joint_log_likelihood(self, X):   # todo: 这段代码有问题
        jll = np.zeros((X.shape[0], self.class_count_.shape[0]))
        for i in range(self.n_features):
            indices = X[:, i]
            jll += self.feature_count_[i][:, indices].T
        total_jll = jll + np.log(self.class_count_)
        return total_jll

    def fit(self, X, y):
        """ 根据X, y拟合贝叶斯分类器

        Parameters
        ----------
        X: array-like of shape (n_samples, n_features)
            训练数据集.
        y: array-like of shape (n_samples,)
            训练标签.
        """
        _, n_features = X.shape
        self.classes_ = np.unique(y)
        Y = label_binarize(y, classes=self.classes_)
        n_classes = Y.shape[1]
        self._init_counter(n_classes, n_features)
        self._count(X, Y)
        self._update_feature_log_prob(alpha=1)
        self._joint_log_likelihood(X)
        return self

    def predict(self, X):
        """预测"""
        jll = self._joint_log_likelihood(X)
        return self.classes_[np.argmax(jll, axis=1)]


if __name__ == "__main__":
    pass

4.3 测试代码

import numpy as np
import pandas as pd
from my_naive_byes import MyDiscreteNB


def _map_to_integer(values, uniques):
    """Map values based on its position in uniques."""
    table = {val: i for i, val in enumerate(uniques)}
    return np.array([table[v] for v in values])


# 准备数据
f_path = r"../../datasets/mushroom/raw_data/agaricus-lepiota.data"
data = pd.read_csv(f_path, header=None)

# 数据预处理
data = np.asarray(data)
data_copy = np.zeros_like(data).astype(int)  # todo: 细节
for i in range(data.shape[1]):
    temp = data[:, i]
    classes = np.unique(temp)
    data_copy[:, i] = _map_to_integer(temp, classes)

# 拆分数据
X = data_copy[:, 1:]
y = data_copy[:, 0]


# 训练数据
mdnb = MyDiscreteNB()
mdnb.fit(X, y)
y = mdnb.predict(data_copy[0: 2, 1:])
print(y)

# sklearn 测试
from sklearn.naive_bayes import CategoricalNB

CN = CategoricalNB()
CN.fit(X, y)
y_pred = CN.predict(data_copy[0: 2, 1:])
print(y_pred)

4.4 对比分析

D:\anaconda3\envs\machinelearn\python.exe E:\my_ml\models\naive_bayes\test.py 
[0 0]
[0 0]

      以上代码与sklearn运算结果符合。

第五章 参考文献

[1] 茆诗松,程依明,濮晓龙. 概率论与数理统计教程[M]. 北京: 高等教育出版社, 2010:61-65.
[2] 李航. 统计学习方法[M]. 北京: 清华大学出版社, 2019:41-51.
[3] 雷明. 机器学习原理、算法与应用[M]. 北京: 清华大学出版社, 2019:55-61.

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值