第4章 朴素贝叶斯

引言

在众多机器学习分类算法中,本篇我们提到的朴素贝叶斯模型,和其他绝大多数分类算法都不同,也是很重要的模型之一。

在众多机器学习的分类算法中,朴素贝叶斯模型以其独特的方法和重要性,与其他算法显著不同。相对于KNN、逻辑回归、决策树等判别方法,这些算法直接学习输入特征X与输出Y之间的直接关系(决策函数 Y=f(x)Y=f(x) 或者条件分布 P(YX)P(Y \mid X)​ ),朴素贝叶斯模型则采用了生成方法。它直接找出特征输出Y和特征 X的联合分布 P(X,Y)P(X, Y) ,进而通过

P(YX)=P(X,Y)P(X)P(Y \mid X)=\frac{P(X, Y)}{P(X)}

计算得出结果判定。

朴素贝叶斯算法原理

贝叶斯定理

贝叶斯理论是以18世纪的一位神学家托马斯.贝叶斯(Thomas Bayes)命名。通常,事件A在事件B (发生) 的条件下的概率,与事件B在事件A (发生) 的条件下的概率是不一样的。然而,这两者是有确定的关系的,贝叶斯定理就是这种关系的陈述。

P(AB)=P(BA)P(A)P(B)P(A \mid B)=\frac{P(B \mid A) P(A)}{P(B)}

  • 条件概率:就是事件 AA 在另外一个事件 BB 已经发生条件下的发生概率。条件概率表示为 P(AB)P(A \mid B) ,即在 BB 发生的条件下 AA 发生的概率。
  • 联合概率:表示两个事件共同发生(数学概念上的交集)的概率。 AABB 的联合概率表示为联合概率。联合概率表示为 P(AB)P(A B)

P(AB)=P(AB)P(B)=P(BA)P(A), 若 AB 相互独立, 则P(AB)=P(A)P(B)P(A B)=P(A \mid B) P(B)=P(B \mid A) P(A) \text {, 若 } A B \text { 相互独立, 则} P(A B)=P(A) P(B)

  • 全概率公式: P(X)=kP(XY=Yk)P(Yk)\displaystyle P(X)=\sum_k P\left(X \mid Y=Y_k\right) P\left(Y_k\right), 其中 kP(Yk)=1\displaystyle \sum_k P\left(Y_k\right)=1

朴素贝叶斯

朴素贝叶斯方法是基于贝叶斯定理和特征条件独立假设的分类方法

这是一个较强的假设。由于这一假设,模型包含的条件概率的数量大为减少,朴素贝叶斯法的学习与预测大为简化。因而朴素贝叶斯法高效,且易于实现。其缺点是分类的性能不一定很高。

对于给定的训练数据集:

  1. 首先基于特征条件独立假设学习输入 / 输出的联合概率分布
  2. 然后基于此模型,对给定的输入 xx ,利用贝叶斯定理求出后验概率最大的输出 yy :

P(X=xY=ck)=P(X(1)=x(1),,X(n)=x(n)Y=ck)=j=1nP(X(j)=x(j)Y=ck)(1)\begin{aligned} P\left(X=x \mid Y=c_k\right) & =P\left(X^{(1)}=x^{(1)}, \cdots, X^{(n)}=x^{(n)} \mid Y=c_k\right) \\ & =\prod_{j=1}^n P\left(X^{(j)}=x^{(j)} \mid Y=c_k\right) \end{aligned}\tag{1}

原理

朴素贝叶斯方法属于生成模型的范畴。在给定输入 xx 的情况下,这种方法通过已学习的模型计算后验概率分布 P(Y=ckX=x)P(Y=c_k \mid X=x) 。它选择后验概率最高的类别 $c_k $ 作为输入 $x $ 的预测分类。其中后验概率的计算基于贝叶斯定理进行

P(Y=ckX=x)=P(X=xY=ck)P(Y=ck)kP(X=xY=ck)P(Y=ck)(2)\begin{aligned} P\left(Y=c_k \mid X=x\right) &= \frac{P\left(X=x \mid Y=c_k\right) P\left(Y=c_k\right)}{\displaystyle \sum_k P\left(X=x \mid Y=c_k\right) P\left(Y=c_k\right)} \end{aligned}\tag{2}

将式(1)(1)代入式(2)(2),有

P(Y=ckX=x)=P(Y=ck)jP(X(j)=x(j)Y=ck)kP(Y=ck)jP(X(j)=x(j)Y=ck),k=1,2,,K(3)P\left(Y=c_k \mid X=x\right)=\frac{\displaystyle P\left(Y=c_k\right) \prod_j P\left(X^{(j)}=x^{(j)} \mid Y=c_k\right)}{\displaystyle \sum_{k} P\left(Y=c_k\right) \prod_{j} P\left(X^{(j)}=x^{(j)} \mid Y=c_k\right)},k=1,2, \cdots, K\tag{3}

这是朴素贝叶斯法分类的基本公式。于是, 朴素贝叶斯分类器可表示为

y=f(x)=argmaxckP(Y=ck)jP(X(j)=x(j)Y=ck)kP(Y=ck)jP(X(j)=x(j)Y=ck)(4)y=f(x)=\arg \max _{c_k} \frac{\displaystyle P\left(Y=c_k\right) \prod_j P\left(X^{(j)}=x^{(j)} \mid Y=c_k\right)}{\displaystyle \sum_k P\left(Y=c_k\right) \prod_j P\left(X^{(j)}=x^{(j)} \mid Y=c_k\right)}\tag{4}

注意到, 在式 (4)(4) 中分母对所有 ckc_k 都是相同的,所以

y=argmaxckP(Y=ck)jP(X(j)=x(j)Y=ck)(5)y=\arg \max _{c_k} P\left(Y=c_k\right) \prod_j P\left(X^{(j)}=x^{(j)} \mid Y=c_k\right)\tag{5}

后验概率最大化的含义

朴素贝叶斯法将实例分到后验概率最大的类中, 这等价于期望风险最小化。假设选择 0-1 损失函数:

L(Y,f(X))={1,Yf(X)0,Y=f(X)(6)L(Y, f(X))=\left\{\begin{array}{rr} 1, & Y \neq f(X) \\ 0, & Y=f(X) \end{array}\right.\tag{6}

式中 f(X)f(X) 是分类决策函数。这时,期望风险函数为

Rexp(f)=E[L(Y,f(X))](7)R_{\exp }(f)=E[L(Y, f(X))]\tag{7}

期望是对联合分布 P(X,Y)P(X, Y) 取的。由此取条件期望

Rexp(f)=EXk=1K[L(ck,f(X))]P(ckX)(8)R_{\exp }(f)=E_X \sum_{k=1}^K\left[L\left(c_k, f(X)\right)\right] P\left(c_k \mid X\right)\tag{8}

为了使期望风险最小化, 只需对 X=xX=x 逐个极小化, 由此得到:

f(x)=argminyYk=1KL(ck,y)P(ckX=x)=argminyYk=1KP(yckX=x)=argminyY(1P(y=ckX=x))=argmaxyYP(y=ckX=x)(9)\begin{aligned} f(x) & =\arg \min _{y \in \mathcal{Y}} \sum_{k=1}^K L\left(c_k, y\right) P\left(c_k \mid X=x\right) \\ & =\arg \min _{y \in \mathcal{Y}} \sum_{k=1}^K P\left(y \neq c_k \mid X=x\right) \\\\ & =\arg \min _{y \in \mathcal{Y}}\left(1-P\left(y=c_k \mid X=x\right)\right) \\\\ & =\arg \max _{y \in \mathcal{Y}} P\left(y=c_k \mid X=x\right) \end{aligned}\tag{9}

这样一来, 根据期望风险最小化准则就得到了后验概率最大化准则:

f(x)=argmaxckP(ckX=x)(10)f(x)=\arg \max _{c_k} P\left(c_k \mid X=x\right)\tag{10}

即朴素贝叶斯法所采用的原理。

极大似然估计

在朴素贝叶斯法中,学习意味着估计 P(Y=ck)P\left(Y=c_k\right)P(X(j)=x(j)Y=ck)P\left(X^{(j)}=x^{(j)} \mid Y=c_k\right) 。可以应用极大似然估计法估计相应的概率。先验概率 P(Y=ck)P\left(Y=c_k\right) 的极大似然估计是

P(Y=ck)=i=1NI(yi=ck)N,k=1,2,,K(11)P\left(Y=c_k\right)=\frac{\displaystyle \sum_{i=1}^N I\left(y_i=c_k\right)}{N}, \quad k=1,2, \cdots, K \tag{11}

设第 jj 个特征 x(j)x^{(j)} 可能取值的集合为 {aj1,aj2,,ajSj}\left\{a_{j 1}, a_{j 2}, \cdots, a_{j S_j}\right\},条件概率 P(X(j)=ajlY=ck)P\left(X^{(j)}=a_{j l} \mid Y=c_k\right)的极大似然估计是

P(X(j)=ajlY=ck)=i=1NI(xi(j)=ajl,yi=ck)i=1NI(yi=ck),j=1,2,,n,l=1,2,,Sj,k=1,2,,K(12)\begin{aligned} & P\left(X^{(j)}=a_{j l} \mid Y=c_k\right)=\frac{\displaystyle \sum_{i=1}^N I\left(x_i^{(j)}=a_{j l}, y_i=c_k\right)}{\displaystyle \sum_{i=1}^N I\left(y_i=c_k\right)}, \\ & j=1,2, \cdots, n, \quad l=1,2, \cdots, S_j, \quad k=1,2, \cdots, K \end{aligned}\tag{12}

式中, xi(j)x_i^{(j)} 是第 ii 个样本的第 jj 个特征; ajla_{j l} 是第 jj 个特征可能取的第 ll 个值; II 为指示函数。

创建训练集和测试集

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline

from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split

from collections import Counter
import math
# data
def create_data():
iris = load_iris()
df = pd.DataFrame(iris.data, columns=iris.feature_names)
df['label'] = iris.target
df.columns = [
'sepal length', 'sepal width', 'petal length', 'petal width', 'label'
]
data = np.array(df.iloc[:100, :])
# print(data)
return data[:, :-1], data[:, -1]
X, y = create_data()
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3)
X_test[0], y_test[0]

Output[ ]

(array([6.6, 2.9, 4.6, 1.3]), 1.0)
  • 高斯模型

    GaussianNB 高斯朴素贝叶斯
    特征的可能性被假设为高斯概率密度函数:

    P(xiyk)=12πσyk2exp((xiμyk)22σyk2)(13)P\left(x_i \mid y_k\right)=\frac{1}{\sqrt{2 \pi \sigma_{y k}^2}} \exp \left(-\frac{\left(x_i-\mu_{y k}\right)^2}{2 \sigma_{y k}^2}\right)\tag{13}

    数学期望: μ\mu
    方差: σ2=(Xμ)2N\sigma^2=\frac{\sum(X-\mu)^2}{N}

实现一个朴素贝叶斯分类器

class NaiveBayes:
def __init__(self):
self.model = None

# 数学期望
@staticmethod
def mean(X):
return sum(X) / float(len(X))

# 标准差(方差)
def stdev(self, X):
avg = self.mean(X)
return math.sqrt(sum([pow(x - avg, 2) for x in X]) / float(len(X)))

# 概率密度函数
def gaussian_probability(self, x, mean, stdev):
exponent = math.exp(-(math.pow(x - mean, 2) /
(2 * math.pow(stdev, 2))))
return (1 / (math.sqrt(2 * math.pi) * stdev)) * exponent

# 处理X_train
def summarize(self, train_data):
summaries = [(self.mean(i), self.stdev(i)) for i in zip(*train_data)]
return summaries

# 分类别求出数学期望和标准差
def fit(self, X, y):
labels = list(set(y))
data = {label: [] for label in labels}
for f, label in zip(X, y):
data[label].append(f)
self.model = {
label: self.summarize(value)
for label, value in data.items()
}
return 'gaussianNB train done!'

# 计算概率
def calculate_probabilities(self, input_data):
# summaries:{0.0: [(5.0, 0.37),(3.42, 0.40)], 1.0: [(5.8, 0.449),(2.7, 0.27)]}
# input_data:[1.1, 2.2]
probabilities = {}
for label, value in self.model.items():
probabilities[label] = 1
for i in range(len(value)):
mean, stdev = value[i]
probabilities[label] *= self.gaussian_probability(
input_data[i], mean, stdev)
return probabilities

# 类别
def predict(self, X_test):
# {0.0: 2.9680340789325763e-27, 1.0: 3.5749783019849535e-26}
label = sorted(
self.calculate_probabilities(X_test).items(),
key=lambda x: x[-1])[-1][0]
return label

def score(self, X_test, y_test):
right = 0
for X, y in zip(X_test, y_test):
label = self.predict(X)
if label == y:
right += 1

return right / float(len(X_test))
model = NaiveBayes()
model.fit(X_train, y_train)

Output[ ]

'gaussianNB train done!'
print(model.predict([4.4,  3.2,  1.3,  0.2]))

Output[ ]

0.0
model.score(X_test, y_test)

Output[ ]

1.0

scikit-learn实例

from sklearn.naive_bayes import GaussianNB
clf = GaussianNB()
clf.fit(X_train, y_train)
clf.score(X_test, y_test)

Output[ ]

1.0
clf.predict([[4.4,  3.2,  1.3,  0.2]])

Output[ ]

array([0.])

而scikit-learn中的伯努利模型和多项式模型

from sklearn.naive_bayes import BernoulliNB, MultinomialNB # 伯努利模型和多项式模型

第4章朴素贝叶斯法-习题

1.用极大似然估计法推出朴素贝叶斯法中的概率估计公式(11)(11)及公式 (12)(12)

解答:
**第1步:**证明公式(11)(11)P(Y=ck)=i=1NI(yi=ck)N\displaystyle P(Y=c_k) = \frac{\displaystyle \sum_{i=1}^N I(y_i=c_k)}{N}

由于朴素贝叶斯法假设YY是定义在输出空间Y\mathcal{Y}上的随机变量,因此可以定义P(Y=ck)P(Y=c_k)概率为pp

m=i=1NI(yi=ck)\displaystyle m=\sum_{i=1}^NI(y_i=c_k),得出似然函数:

L(p)=fD(y1,y2,,ynθ)=(Nm)pm(1p)(Nm)L(p)=f_D(y_1,y_2,\cdots,y_n|\theta)=\binom{N}{m}p^m(1-p)^{(N-m)}

使用微分求极值,两边同时对pp求微分:

0=(Nm)[mp(m1)(1p)(Nm)(Nm)pm(1p)(Nm1)]=(Nm)[p(m1)(1p)(Nm1)(mNp)]\begin{aligned} 0 &= \binom{N}{m}\left[mp^{(m-1)}(1-p)^{(N-m)}-(N-m)p^m(1-p)^{(N-m-1)}\right] \\ & = \binom{N}{m}\left[p^{(m-1)}(1-p)^{(N-m-1)}(m-Np)\right] \end{aligned}

可求解得到:

p=0,p=1,p=mN\displaystyle p=0,p=1,p=\frac{m}{N}

显然

P(Y=ck)=p=mN=i=1NI(yi=ck)N\begin{aligned} \displaystyle P(Y=c_k)&=p =\frac{m}{N} =\frac{\displaystyle \sum_{i=1}^N I(y_i=c_k)}{N} \end{aligned}

公式(11)(11)得证。


**第2步:**证明公式(11)(11)

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

P(X(j)=ajlY=ck)=pP(X^{(j)}=a_{jl}|Y=c_k)=p

m=i=1NI(yi=ck),q=i=1NI(xi(j)=ajl,yi=ck)\displaystyle m=\sum_{i=1}^N I(y_i=c_k), q=\sum_{i=1}^N I(x_i^{(j)}=a_{jl},y_i=c_k)

得出似然函数:

L(p)=(mq)pq(ip)mqL(p)=\binom{m}{q}p^q(i-p)^{m-q}

使用微分求极值,两边同时对pp求微分:

0=(mq)[qp(q1)(1p)(mq)(mq)pq(1p)(mq1)]=(mq)[p(q1)(1p)(mq1)(qmp)]\begin{aligned} 0 &= \binom{m}{q}\left[qp^{(q-1)}(1-p)^{(m-q)}-(m-q)p^q(1-p)^{(m-q-1)}\right] \\ & = \binom{m}{q}\left[p^{(q-1)}(1-p)^{(m-q-1)}(q-mp)\right] \end{aligned}

可求解得到

p=0,p=1,p=qm\displaystyle p=0,p=1,p=\frac{q}{m}

显然

P(X(j)=ajlY=ck)=p=qm=i=1NI(xi(j)=ajl,yi=ck)i=1NI(yi=ck)\displaystyle P(X^{(j)}=a_{jl}|Y=c_k)=p=\frac{q}{m}=\frac{\displaystyle \sum_{i=1}^N I(x_i^{(j)}=a_{jl},y_i=c_k)}{\displaystyle \sum_{i=1}^N I(y_i=c_k)}

公式(12)(12)得证。