机器学习 第七章 贝叶斯分类器
1. 贝叶斯决策论
1.1 核心理论框架
贝叶斯决策论是统计决策理论的基石,其核心公式为:
R
(
C
i
∣
x
)
=
∑
j
=
1
N
λ
i
j
P
(
C
j
∣
x
)
R(C_i|x) = \sum_{j=1}^N \lambda_{ij}P(C_j|x)
R(Ci∣x)=j=1∑NλijP(Cj∣x)
其中:
- R ( C i ∣ x ) R(C_i|x) R(Ci∣x):将样本x分类为 C i C_i Ci的条件风险
- λ i j \lambda_{ij} λij:误分类损失矩阵
- P ( C j ∣ x ) P(C_j|x) P(Cj∣x):后验概率
1.2 损失函数矩阵示例
真实\预测 | 正类 | 负类 |
---|---|---|
正类 | 0 | 1 |
负类 | 5 | 0 |
注:此矩阵表示将正类误判为负类的损失是1,负类误判为正类的损失是5
1.3 贝叶斯最优分类器推导
当
λ
i
j
=
{
0
i
=
j
1
i
≠
j
\lambda_{ij} = \begin{cases}0 & i=j \\ 1 & i \ne j\end{cases}
λij={01i=ji=j时:
h
∗
(
x
)
=
arg
max
C
i
P
(
C
i
∣
x
)
h^*(x) = \arg\max_{C_i} P(C_i|x)
h∗(x)=argCimaxP(Ci∣x)
1.4 完整实现代码
from sklearn.naive_bayes import GaussianNB
import numpy as np
class BayesianClassifier:
def __init__(self, loss_matrix):
self.loss_matrix = loss_matrix
def fit(self, X, y):
self.classes_ = np.unique(y)
self.priors_ = np.bincount(y) / len(y)
self.gnb = GaussianNB().fit(X, y)
def predict(self, X):
posterior = self.gnb.predict_proba(X)
risk = posterior @ self.loss_matrix.T
return self.classes_[np.argmin(risk, axis=1)]
# 示例使用
loss_matrix = np.array([[0,1],[5,0]]) # 自定义损失矩阵
X = np.array([[1,2], [2,3], [3,3], [2,1], [3,2], [4,3]])
y = np.array([0, 0, 0, 1, 1, 1])
clf = BayesianClassifier(loss_matrix)
clf.fit(X, y)
print(clf.predict([[2.5, 2]])) # 输出:[0]
2. 极大似然估计(MLE)
2.1 参数估计方法对比
方法 | 优点 | 局限性 |
---|---|---|
极大似然估计 | 计算简单,一致性 | 需要大样本 |
贝叶斯估计 | 整合先验知识 | 计算复杂度高 |
矩估计 | 无需分布假设 | 效率较低 |
2.2 高斯分布参数估计
对于
X
∼
N
(
μ
,
σ
2
)
X \sim \mathcal{N}(\mu, \sigma^2)
X∼N(μ,σ2):
μ
^
=
1
m
∑
i
=
1
m
x
i
σ
^
2
=
1
m
∑
i
=
1
m
(
x
i
−
μ
^
)
2
\hat{\mu} = \frac{1}{m}\sum_{i=1}^m x_i \\ \hat{\sigma}^2 = \frac{1}{m}\sum_{i=1}^m (x_i - \hat{\mu})^2
μ^=m1i=1∑mxiσ^2=m1i=1∑m(xi−μ^)2
2.3 多变量高斯MLE实现
def mle_multivariate_gaussian(X):
mu = np.mean(X, axis=0)
sigma = (X - mu).T @ (X - mu) / len(X)
return mu, sigma
# 示例使用
X = np.random.multivariate_normal(
mean=[0,0],
cov=[[1,0.5],[0.5,1]],
size=1000
)
print(mle_multivariate_gaussian(X)) # 输出接近真实参数
3. 朴素贝叶斯分类器
3.1 算法流程
graph TD
A[计算先验概率 P(C_i)] --> B[计算条件概率 P(x_j|C_i)]
B --> C[计算后验概率 P(C_i|x)]
C --> D[选择最大后验概率类别]
3.2 三种变体对比
类型 | 适用场景 | 概率计算公式 |
---|---|---|
高斯朴素贝叶斯 | 连续特征 | P ( x j ∣ C i ) = N ( x j ; μ i j , σ i j 2 ) P(x_j|C_i) = \mathcal{N}(x_j;\mu_{ij},\sigma_{ij}^2) P(xj∣Ci)=N(xj;μij,σij2) |
多项式朴素贝叶斯 | 文本分类 | P ( x j ∣ C i ) = N i j + α N i + α n P(x_j|C_i) = \frac{N_{ij}+\alpha}{N_i+\alpha n} P(xj∣Ci)=Ni+αnNij+α |
伯努利朴素贝叶斯 | 二元特征 | P ( x j ∣ C i ) = p i j x j ( 1 − p i j ) 1 − x j P(x_j|C_i) = p_{ij}^{x_j}(1-p_{ij})^{1-x_j} P(xj∣Ci)=pijxj(1−pij)1−xj |
3.3 文本分类实战
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.naive_bayes import MultinomialNB
# 构建示例语料库
corpus = [
'this is positive review',
'negative feedback here',
'very good experience',
'terrible service'
]
y = [1, 0, 1, 0]
# 特征提取
vectorizer = CountVectorizer()
X = vectorizer.fit_transform(corpus)
# 训练分类器
clf = MultinomialNB().fit(X, y)
# 预测新样本
new_text = ['excellent service']
print(clf.predict(vectorizer.transform(new_text))) # 输出:[1]
4. 半朴素贝叶斯分类器
4.1 依赖关系建模
方法 | 依赖结构 | 计算公式 |
---|---|---|
ODE | 单父节点 | P ( x 1 , . . . , x d ∣ C ) = ∏ P ( x j ∣ x p a ( j ) , C ) P(x_1,...,x_d|C) = \prod P(x_j|x_{pa(j)}, C) P(x1,...,xd∣C)=∏P(xj∣xpa(j),C) |
TAN | 树结构 | 通过最大互信息构建依赖树 |
AODE | 平均ODE | 集成多个超父模型 |
4.2 TAN算法实现步骤
- 计算特征间条件互信息
- 构建最大生成树
- 选择根节点并确定方向
- 构建带树结构的概率图
4.3 代码实现
from sklearn.naive_bayes import GaussianNB
from sklearn.base import BaseEstimator
class TANClassifier(BaseEstimator):
def __init__(self):
self.dependency_graph = None
def fit(self, X, y):
# 实现特征依赖关系学习(此处简化)
self.sub_models = {
(0,1): GaussianNB().fit(X[:,[0,1]], y),
(1,2): GaussianNB().fit(X[:,[1,2]], y)
}
return self
def predict_proba(self, X):
# 集成多个依赖模型的预测结果
probas = [model.predict_proba(X[:,[i,j]])
for (i,j), model in self.sub_models.items()]
return np.mean(probas, axis=0)
# 示例使用
X = np.random.randn(100,3)
y = np.random.randint(0,2,100)
clf = TANClassifier().fit(X,y)
print(clf.predict_proba(X[:5])) # 输出概率矩阵
5. 贝叶斯网络
5.1 网络结构学习
5.2 精确推理算法对比
算法 | 时间复杂度 | 适用场景 |
---|---|---|
变量消除法 | O(n^w) | 小规模网络 |
联结树算法 | O(n exp(w)) | 中等规模网络 |
近似推理 | O(n) | 大规模网络 |
5.3 医疗诊断应用
from pgmpy.models import BayesianModel
from pgmpy.factors.discrete import TabularCPD
# 构建网络结构
model = BayesianModel([
('Smoking', 'LungCancer'),
('AirPollution', 'LungCancer'),
('LungCancer', 'Cough'),
('AirPollution', 'RespiratoryDisease'),
('Cough', 'HospitalVisit'),
('RespiratoryDisease', 'HospitalVisit')
])
# 定义条件概率表
cpd_s = TabularCPD('Smoking', 2, [[0.3], [0.7]])
cpd_a = TabularCPD('AirPollution', 2, [[0.4], [0.6]])
cpd_l = TabularCPD(
'LungCancer', 2,
[[0.99,0.9,0.85,0.3],
[0.01,0.1,0.15,0.7]],
evidence=['Smoking','AirPollution'],
evidence_card=[2,2]
)
# 添加所有CPD并验证模型
model.add_cpds(cpd_s, cpd_a, cpd_l)
model.check_model()
# 概率推理
from pgmpy.inference import VariableElimination
infer = VariableElimination(model)
print(infer.query(['HospitalVisit'], evidence={'Smoking':1}))
6. EM算法深度剖析
6.1 算法收敛性证明
设:
- θ ( t ) \theta^{(t)} θ(t)为第t次迭代参数估计值
- ℓ ( θ ) \ell(\theta) ℓ(θ)为对数似然函数
则有:
ℓ
(
θ
(
t
+
1
)
)
≥
ℓ
(
θ
(
t
)
)
\ell(\theta^{(t+1)}) \geq \ell(\theta^{(t)})
ℓ(θ(t+1))≥ℓ(θ(t))
即每次迭代保证似然函数不减少
6.2 GMM参数估计
高斯混合模型参数更新公式:
γ
(
z
i
k
)
=
π
k
N
(
x
i
∣
μ
k
,
Σ
k
)
∑
j
=
1
K
π
j
N
(
x
i
∣
μ
j
,
Σ
j
)
μ
k
=
∑
i
=
1
N
γ
(
z
i
k
)
x
i
∑
i
=
1
N
γ
(
z
i
k
)
Σ
k
=
∑
i
=
1
N
γ
(
z
i
k
)
(
x
i
−
μ
k
)
(
x
i
−
μ
k
)
T
∑
i
=
1
N
γ
(
z
i
k
)
\gamma(z_{ik}) = \frac{\pi_k \mathcal{N}(x_i|\mu_k,\Sigma_k)}{\sum_{j=1}^K \pi_j \mathcal{N}(x_i|\mu_j,\Sigma_j)} \\ \mu_k = \frac{\sum_{i=1}^N \gamma(z_{ik})x_i}{\sum_{i=1}^N \gamma(z_{ik})} \\ \Sigma_k = \frac{\sum_{i=1}^N \gamma(z_{ik})(x_i-\mu_k)(x_i-\mu_k)^T}{\sum_{i=1}^N \gamma(z_{ik})}
γ(zik)=∑j=1KπjN(xi∣μj,Σj)πkN(xi∣μk,Σk)μk=∑i=1Nγ(zik)∑i=1Nγ(zik)xiΣk=∑i=1Nγ(zik)∑i=1Nγ(zik)(xi−μk)(xi−μk)T
6.3 完整EM实现
import numpy as np
from scipy.stats import multivariate_normal
class GMM:
def __init__(self, n_components, max_iter=100):
self.K = n_components
self.max_iter = max_iter
def fit(self, X):
# 初始化参数
n, d = X.shape
self.pi = np.ones(self.K)/self.K
self.mu = X[np.random.choice(n, self.K, False)]
self.sigma = [np.eye(d)]*self.K
for _ in range(self.max_iter):
# E步
gamma = np.zeros((n, self.K))
for k in range(self.K):
gamma[:,k] = self.pi[k] * multivariate_normal.pdf(X, self.mu[k], self.sigma[k])
gamma /= gamma.sum(1, keepdims=True)
# M步
Nk = gamma.sum(0)
self.pi = Nk / n
self.mu = gamma.T @ X / Nk[:,None]
for k in range(self.K):
diff = X - self.mu[k]
self.sigma[k] = (gamma[:,k,None,None] * diff[:,:,None] @ diff[:,None,:]).sum(0) / Nk[k]
return self
# 示例使用
X = np.concatenate([
np.random.normal(0,1,(100,2)),
np.random.normal(5,1,(100,2))
])
gmm = GMM(2).fit(X)
print("均值:\n", gmm.mu)
7. 进阶话题
7.1 贝叶斯深度学习
- 贝叶斯神经网络
- 变分推断在深度模型中的应用
- MCMC采样与深度生成模型
7.2 概率编程语言
语言 | 特点 | 应用场景 |
---|---|---|
Stan | 哈密顿蒙特卡洛采样 | 统计建模 |
Pyro | 基于PyTorch | 深度学习集成 |
Edward2 | TensorFlow概率框架 | 大规模推理 |
8. 学习总结
关键知识点图谱
实际应用建议
- 文本分类:优先选择多项式朴素贝叶斯
- 医疗诊断:使用贝叶斯网络建模疾病关系
- 异常检测:采用高斯混合模型(GMM)
- 小样本学习:结合贝叶斯推断与深度学习