贝叶斯公式

AABB是随机事件,且P(B)0P(B) \neq 0P(AB)P(A|B)是指在事件BB发生的情况下事件AA发生的概率。

P(AB)=P(A)P(BA)P(B)\begin{align} P(A | B) = \frac{P(A)P(B|A)}{P(B)} \end{align}

其中,P(AB)P(A \mid B) 是后验概率,P(BA)P(B \mid A) 是似然概率,P(A)P(A) 是先验概率,P(B)P(B) 是边缘概率。

贝叶斯决策论

假设有NN种可能的类别标记,即Y={c1,c2,,cN}\mathcal{Y} = \{c_{1},c_{2},\cdots,c_{N} \}λij\lambda_{ij}是将一个真实标记为cjc_{j}的样本误分类为cic_{i}所产生的犯错成本。基于后验概率P(cix)P(c_{i}|\boldsymbol{x})可获得将样本x\boldsymbol{x}分类为cic_{i}所产生的期望损失,即在样本x\boldsymbol{x}上的”条件风险“。

R(cix)=j=1NλijP(cjx)λij={0,if i=j;1,otherwise.\begin{align} R(c_{i}|\boldsymbol{x}) = \sum_{j = 1}^N \lambda_{ij} P(c_{j}|\boldsymbol{x}) \\ \lambda_{ij} = \left \{ \begin{array}{c} 0,if \ i = j; \\ 1,otherwise. \end{array} \right . \end{align}

我们的任务是去寻找一个判定准则h:XYh : \mathcal{X} \mapsto \mathcal{Y}以最小化总体风险

R(h)=Ex[R(h(x)x)]\begin{align} R(h) = \mathbb{E}_{x}[R(h(\boldsymbol{x} )| \boldsymbol{x})] \end{align}

显然,对每个样本x\boldsymbol{x},若hh能最小化条件风险R(h(x)x)R(h(\boldsymbol{x} )| \boldsymbol{x}),则总体风险R(h)R(h)也将最小化。这就产生了贝叶斯判定准则:为最小化总体风险,只需在每个样本上选择那个能使条件风险R(cx)R(c | \boldsymbol{x})最小的类别标记,即

h(x)=argmincYR(cx)\begin{align} h^* (\boldsymbol{x}) = \arg{\min}_{c \in \mathcal{Y}} R(c| \boldsymbol{x}) \end{align}

此时,hh^*称为贝叶斯最优分类器,与之对应的总体风险R(h)R(h^*)称为贝叶斯风险。1R(h)1-R(h^*)反映了分类器所能达到的最好性能,即通过机器学习所能产生的模型精度的理论上限。

以上都是不说人话环节。其实这些东西说白了就是告诉一件事情:贝叶斯最优分类器定义了最高准确率。如果训练的模型准确率高过贝叶斯最优分类器的准确率,那就要考虑是否有过拟合的问题了。

朴素贝叶斯分类器

Algorithm 1 朴素贝叶斯算法(Naive Bayes algorithm)

输入:训练数据集 T={(x1,y1),(x2,y2),,(xN,yN)}T = \{(x_1, y_1), (x_2, y_2), \dots, (x_N, y_N)\},其中 xi=(x1(i),x2(i),,xn(i))x_i = (x_1^{(i)}, x_2^{(i)}, \dots, x_n^{(i)}), yi{c1,c2,,cK}y_i \in \{c_1, c_2, \dots, c_K\}, xix_i 是第 ii 个样本的第 jj 个特征, xj(i){aj1,aj2,,ajsj}x_j^{(i)} \in \{a_{j1}, a_{j2}, \dots, a_{js_j}\}, sjs_j 是第 jj 个特征可能取的值的个数, j=1,2,,nj = 1, 2, \dots, n, yi{c1,c2,,cK}y_i \in \{c_1, c_2, \dots, c_K\}: 实例 xx 的类别。

输出:实例 xx 的分类。

(1) 计算先验概率及条件概率
计算类别 kk 的先验概率:

P(Y=ck)=i=1NI(yi=ck)N,k=1,2,,K\begin{array}{c} P(Y = c_k) = \frac{\sum_{i=1}^{N} I(y_i = c_k)}{N}, \quad k = 1, 2, \dots, K \end{array}

计算条件概率:

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\begin{array}{c} P(X^{(j)} = a_{jl} | Y = c_k) = \frac{\sum_{i=1}^{N} I(x_i^{(j)} = a_{jl}, y_i = c_k)}{\sum_{i=1}^{N} I(y_i = c_k)}, \quad j = 1, 2, \dots, n, \quad l = 1, 2, \dots, S_j, \quad k = 1, 2, \dots, K \end{array}

(2) 对于给定的实例 x=(x(1),x(2),,x(n))Tx = (x^{(1)}, x^{(2)}, \dots, x^{(n)})^T,计算

P(Y=ck)j=1nP(X(j)=x(j)Y=ck),k=1,2,,K\begin{array}{c} P(Y = c_k) \prod_{j=1}^{n} P(X^{(j)} = x^{(j)} | Y = c_k), \quad k = 1, 2, \dots, K \end{array}

(3) 确定实例 xx 的类

y=argmaxckP(Y=ck)j=1nP(X(j)=x(j)Y=ck),k=1,2,,K\begin{array}{c} y = \arg \max_{c_k} P(Y = c_k) \prod_{j=1}^{n} P(X^{(j)} = x^{(j)} | Y = c_k), \quad k = 1, 2, \dots, K \end{array}

实现代码——鸢尾花数据集

本代码由DeepSeek R1生成。

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
from sklearn.datasets import load_iris
from sklearn.naive_bayes import GaussianNB
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
from sklearn import tree
from collections import Counter
import numpy as np
import pandas as pd

class GaussianNaiveBayes:
"""
高斯朴素贝叶斯分类器实现
基于特征独立假设和正态分布概率计算
"""

def __init__(self):
"""初始化分类器
属性:
classes : 存储所有唯一类别标签的数组
class_priors : 存储类别先验概率的字典 {类别: 概率}
feature_params : 存储特征参数的字典 {类别: {mean: 均值数组, var: 方差数组}}
"""
self.classes = None
self.class_priors = {}
self.feature_params = {}

def fit(self, X, y):
"""
训练模型方法
参数:
X : 特征矩阵,形状 (n_samples, n_features)
y : 目标向量,形状 (n_samples,)
"""
# 转换数据为numpy数组
X = np.array(X)
y = np.array(y)

# 获取唯一类别及其样本数量
self.classes, counts = np.unique(y, return_counts=True)
total_samples = len(y)

# 计算每个类别的统计量
for cls, count in zip(self.classes, counts):
# 筛选当前类别的样本
X_cls = X[y == cls]

# 计算并存储先验概率
self.class_priors[cls] = count / total_samples

# 计算特征均值和方差(添加平滑项避免零方差)
self.feature_params[cls] = {
'mean': X_cls.mean(axis=0),
'var': X_cls.var(axis=0) + 1e-9
}

def _gaussian_log_prob(self, X, mean, var):
"""
计算高斯分布的对数概率
参数:
X : 输入数据,形状 (n_samples, n_features)
mean : 均值数组
var : 方差数组
返回:
对数概率数组,形状 (n_samples,)
"""
# 概率计算分解为指数项和对数项
exponent = -0.5 * np.sum((X - mean)**2 / var, axis=1)
log_term = -0.5 * np.log(2 * np.pi * var).sum()
return exponent + log_term

def predict(self, X):
"""
执行预测
参数:
X : 输入数据,形状 (n_samples, n_features)
返回:
预测类别数组,形状 (n_samples,)
"""
X = np.array(X)
log_probs = []

# 遍历所有类别计算后验概率
for cls in self.classes:
# 对数先验概率
log_prior = np.log(self.class_priors[cls])

# 对数似然概率(特征条件概率的对数和)
log_likelihood = self._gaussian_log_prob(
X,
self.feature_params[cls]['mean'],
self.feature_params[cls]['var']
)

# 存储总对数概率
log_probs.append(log_prior + log_likelihood)

# 选择最大概率对应的类别
return self.classes[np.argmax(log_probs, axis=0)]

# 数据加载与预处理
iris = load_iris()
X_train, X_test, y_train, y_test = train_test_split(
iris.data,
iris.target,
test_size=0.2,
random_state=42
)

# 模型训练与预测
model = GaussianNaiveBayes()
model.fit(X_train, y_train)
predictions = model.predict(X_test)

# 结果评估与展示
accuracy = accuracy_score(y_test, predictions)
print(f"模型准确率: {accuracy:.2f}")
print("预测结果对比表:")
print(Counter(zip(y_test, predictions)))

# scikit-learn 的 GaussianNB 模组验证
model_sklearn = GaussianNB()
model_sklearn.fit(X_train, y_train)
y_pred = model_sklearn.predict(X_test)
print(f"sk-learn的高斯朴素贝叶斯算法准确率:{accuracy_score(y_test, y_pred)}")

半朴素贝叶斯分类器

朴素贝叶斯分类器采用了属性条件独立性假设,但是现实中这个假设往往很难成立。于是乎,人门尝试对属性条件独立性假设进行一定程度的放松,由此产生一类为“半朴素贝叶斯分类器”。

One-Dependent Estimator(ODE)

独依赖估计(One-Dependent Estimator,ODE)是半朴素贝叶斯分类器最常用的一种策略。所谓“独依赖”,就是假设每个属性在类别之外最多只能依赖一个其他属性。

Super-Parent ODE(SPODE)

超父独依赖估计(Super-Parent ODE,SPODE)是假设所有属性都依赖于同一个属性,这个属性被称作“超父”。

Averaged ODE(AODE)

AODE是一种基于集成学习机制,更为强大的独依赖分类器,它尝试将每个属性作为超父来构建SPODE,然后取结果平均。

Tree Augumented Naive Bayes(TAN)

TAN则是在最大有权生成树算法的基础上,通过以下步骤将属性之间的依赖关系约简成一个树形结构:

  1. 计算任意两个属性之间的条件互信息:

I(xi,xjy)=xi,xj;cYP(xi,xjc)logP(xi,xjc)P(xic)P(xjc);\begin{align} I(x_{i},x_{j}|y) = \sum_{x_{i},x_{j};c \in \mathcal{Y}}P(x_{i},x_{j}|c) \log \frac{P(x_{i},x_{j}|c)}{P(x_{i}|c)P(x_{j}|c)}; \end{align}

  1. 以属性为节点构建完全图,任意两个结点之间的边权重设为I(xi,xjy)I(x_{i},x_{j}|y);
  2. 构建此完全图的最大有权生成树,挑选根变量,将边置为有向;
  3. 加入类别结点yy,增加yy到每个属性的有向边。

应用于朴素贝叶斯的EM算法

这篇文章是不错的EM算法的学习资料:【机器学习】EM——期望最大(非常详细) - 知乎,感觉这篇文章里面的例子比机器学习算法 李航著里面的例子好理解多了。

期望极大算法(Expectation Maximization Algorithm,EM Algorithm)是含有隐变量的概率模型极大似然估计或极大后验概率估计的迭代算法。EM算法的最大优点是简单性和普适性,它通过迭代求解观测数据的对数似然函数L(θ)=logP(Yθ)L(\theta) = \log P(Y|\theta)的最大化,实现极大似然估计。

Algorithm 2 EM算法

输入:观测变量数据YY,隐变量数据XX,联合分布P(Y,Zθ)P(Y,Z|\theta),条件分布P(ZY,θ)P(Z|Y,\theta)

输出:模型参数θ\theta

(1) 计算参数的初始值θ(0)\theta^{(0)},开始迭代。

(2) E步:记θi\theta^{i}为第ii次迭代参数θ\theta的估计值,在第i+1i+1次迭代的E步,计算

Q(θ,θ(i))=EZ[logP(Y,Zθ)Y,θ(i)]=ZlogP(Y,Zθ)P(ZY,θ(i)) \begin{align} Q(\theta,\theta^{(i)}) & = E_{Z}[\log P(Y,Z|\theta)|Y,\theta^{(i)}] \nonumber \\ & =\sum_{Z} \log P(Y,Z|\theta)P(Z|Y,\theta^{(i)}) \end{align}

这里,P(ZY,θ(i))P(Z|Y,\theta^{(i)})是在给定观测数据YY和当前的参数估计θ(i)\theta^{(i)}下的隐变量数据ZZ的条件概率分布。

(3) M步:求使Q(θ,θ(i))Q(\theta,\theta^{(i)})极大化的θ\theta,确定第i+1i+1次迭代的参数的估计值θ(i+1)\theta^{(i+1)}

θ(i+1)=argmaxθQ(θ,θ(i))\begin{align} \theta^{(i+1)} = \arg \max_{\theta} Q(\theta,\theta^{(i)}) \end{align}

(4) 重复第2步和第3步,直到收敛(见下文的EM算法的几点说明第四条)。

式(7)的函数Q(θ,θ(i))Q(\theta,\theta^{(i)})是EM算法的核心,称为Q函数(Q function)。

EM算法的几点说明

  • 步骤(1)中参数的初值可以任意选择,但需要注意EM算法对初值是敏感的
  • 步骤(2)中E步求Q函数中,ZZ是未观测数据,YY是观测数据。注意,Q(θ,θ(i))Q(\theta,\theta^{(i)})的第1个变元表示要极大化的参数,第2个变元表示参数的当前估计值。每次迭代实际在求Q函数及其极大。
  • 步骤(3)中M步求Q(θ,θ(i))Q(\theta,\theta^{(i)})的极大化,得到Q(i+1)Q^{(i+1)},完成一次迭代θ(i)θ(i+1)\theta^{(i)} \to \theta^{(i+1)}
  • 步骤(4)给出停止迭代的条件,一般是对于较小的正数ε1,ε2\varepsilon_{1},\varepsilon_{2},若满足

θ(i)θ(i+1)<ε1 or Q(θ(i+1),θ(i))Q(θ(i),θ(i))<ε2\begin{array}{c} \Vert \theta^{(i)} - \theta^{(i+1)} \Vert < \varepsilon_{1} \ or \ \Vert Q(\theta^{(i+1)} , \theta^{(i)}) - Q(\theta^{(i)} , \theta^{(i)}) \Vert < \varepsilon_{2} \end{array}

则停止迭代