概述
概率图模型(Probabilistic Graphical Models, PGMs) 是用图结构表示随机变量之间条件独立关系的概率模型家族。这一统一框架将贝叶斯网络的有向表示和马尔可夫随机场的无向表示纳入同一个数学体系,为不确定性推理和结构化预测提供了强大工具。1
┌─────────────────────────────────────────────────────────────────┐
│ 概率图模型分类 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ 概率图模型 │
│ │ │
│ ┌───────────┴───────────┐ │
│ │ │ │
│ 有向图模型 无向图模型 │
│ │ │ │
│ ┌──────┴──────┐ ┌─────┴─────┐ │
│ │ │ │ │ │
│ 贝叶斯 动态 马尔可夫 条件随机场 │
│ 网络 模型 随机场 (CRF) │
│ │
└─────────────────────────────────────────────────────────────────┘
1. 概率图模型基础
1.1 图表示的基本要素
概率图模型通过图 表示变量之间的依赖关系:
| 要素 | 符号 | 含义 |
|---|---|---|
| 节点 | 随机变量集合 | |
| 边 | 变量间的直接依赖关系 | |
| 邻域 | 节点 的父节点集合 | |
| 邻居 | 与节点 相邻的节点集合 |
1.2 条件独立性
概率图模型的核心价值在于用图结构编码条件独立性:
这意味着给定父节点后,节点的条件分布仅依赖其直接前驱。
2. 贝叶斯网络(Bayesian Networks)
2.1 定义与表示
贝叶斯网络使用**有向无环图(DAG)**表示因果或条件依赖关系。1
联合概率分布分解:
每个变量的概率只依赖于其父节点,这种分解极大地减少了参数量。
2.2 条件概率分布
连续变量的条件分布通常假设为高斯分布:
2.3 朴素贝叶斯分类器
朴素贝叶斯是贝叶斯网络的特例,假设所有特征条件独立于类别:
# 朴素贝叶斯分类器实现
import numpy as np
class NaiveBayes:
def __init__(self):
self.classes = None
self.mean = {} # 每个类别的特征均值
self.var = {} # 每个类别的特征方差
self.priors = {} # 先验概率
def fit(self, X, y):
"""训练朴素贝叶斯分类器"""
n_samples, n_features = X.shape
self.classes = np.unique(y)
for c in self.classes:
X_c = X[c == y]
self.mean[c] = X_c.mean(axis=0)
self.var[c] = X_c.var(axis=0) + 1e-9 # 防止除零
self.priors[c] = X_c.shape[0] / n_samples
return self
def _gaussian_pdf(self, x, mean, var):
"""高斯概率密度函数"""
return np.exp(-0.5 * ((x - mean) ** 2) / var) / np.sqrt(2 * np.pi * var)
def _log_likelihood(self, X, c):
"""计算对数似然"""
mean = self.mean[c]
var = self.var[c]
# log P(X|Y=c) = Σ log P(x_i|Y=c)
log_likelihood = np.sum(np.log(self._gaussian_pdf(X, mean, var)), axis=1)
return log_likelihood + np.log(self.priors[c])
def predict(self, X):
"""预测"""
predictions = []
for x in X:
posteriors = [self._log_likelihood(x.reshape(1, -1), c) for c in self.classes]
predictions.append(self.classes[np.argmax(posteriors)])
return np.array(predictions)2.4 贝叶斯网络的推理
给定部分观测变量,推断其他变量的后验分布:
3. 马尔可夫随机场(Markov Random Fields)
3.1 定义与表示
马尔可夫随机场(MRF)使用无向图表示变量之间的对称依赖关系。2
联合概率分布(吉布斯分布形式):
其中:
- 是团的集合
- 是团势函数(clique potential)
- 是配分函数
3.2 能量函数表示
势函数通常用能量函数的指数形式表示:
这使得联合分布变为:
3.3 条件独立性
MRF的条件独立性由Hammersley-Clifford定理保证:
4. 条件随机场(Conditional Random Fields)
4.1 定义
条件随机场是对结构化数据进行条件概率建模的无向图模型,特别适合序列标注任务。3
条件概率定义:
其中 是归一化因子。
4.2 线性链CRF
对于序列标注任务,使用线性链CRF:
X: X₁ ─ X₂ ─ X₃ ─ ... ─ Xₙ
│ │ │ │
Y: Y₁ ─ Y₂ ─ Y₃ ─ ... ─ Yₙ
特征函数定义:
# 线性链CRF特征函数定义
class CRF:
def __init__(self, states, features):
self.states = states # 标签状态集合
self.features = features # 特征函数列表
def state_feature(self, y_i, y_im1, X, i):
"""状态特征:当前标签与观测的关系"""
return features.get((y_i, X[i]), 0)
def transition_feature(self, y_i, y_im1, X, i):
"""转移特征:相邻标签的关系"""
return features.get((y_i, y_im1), 0)
def score(self, Y, X):
"""计算特征得分"""
score = 0
for i in range(len(Y)):
score += self.state_feature(Y[i], Y[i-1] if i > 0 else '<START>', X, i)
if i > 0:
score += self.transition_feature(Y[i], Y[i-1], X, i)
return score
def partition_function(self, X):
"""计算配分函数 Z(X)"""
# 使用前向算法高效计算
alpha = np.zeros((len(X), len(self.states)))
# 初始化
for s in range(len(self.states)):
alpha[0, s] = np.exp(self.state_feature(self.states[s], '<START>', X, 0))
# 递推
for t in range(1, len(X)):
for s in range(len(self.states)):
alpha[t, s] = np.sum(alpha[t-1] * np.exp([
self.transition_feature(self.states[s], self.states[sp], X, t)
for sp in range(len(self.states))
]))
return np.sum(alpha[-1])4.3 CRF vs 朴素贝叶斯
| 特性 | CRF | 朴素贝叶斯 |
|---|---|---|
| 建模方式 | 条件分布 | 联合分布 |
| 特征依赖 | 任意特征函数 | 假设条件独立 |
| 标签依赖 | 建模标签转移 | 忽略标签依赖 |
| 计算复杂度 | 较高 | 低 |
| 适用场景 | 序列标注、结构预测 | 简单分类 |
5. 推断问题
5.1 推断任务分类
| 任务 | 描述 | 示例 |
|---|---|---|
| 边缘推断 | 计算单个变量的边缘分布 | 诊断推理 |
| 条件推断 | 计算条件分布 | 贝叶斯推断 |
| MAP推断 | 找到最可能的配置 | 图像分割 |
| 配分函数 | 计算归一化常数 | 模型评估 |
5.2 精确推断方法
变量消除算法(Variable Elimination)
利用条件独立性避免冗余计算:
def variable_elimination(factors, query_var, evidence):
"""
变量消除算法
factors: 因子列表
query_var: 查询变量
evidence: 观测变量及其值
"""
# 消除非查询、非证据变量
remaining_factors = factors.copy()
for var in get_elimination_order(remaining_factors, query_var):
# 收集涉及该变量的所有因子
related = [f for f in remaining_factors if var in f.scope]
remaining_factors = [f for f in remaining_factors if var not in f.scope]
# 乘积
product = multiply_factors(related)
# 求和(边缘化)
if var not in evidence:
product = sum_out(product, var)
remaining_factors.append(product)
# 最终归一化
result = multiply_factors(remaining_factors)
return result / np.sum(result)信念传播(Belief Propagation)
利用图结构进行消息传递:
def belief_propagation(graph, node, message_type='sum-product'):
"""
信念传播算法
graph: 图结构
node: 当前节点
message_type: 'sum-product' 或 'max-product'
"""
if is_leaf(node):
return compute_local_message(node)
messages = []
for neighbor in node.neighbors:
if not neighbor.visited:
neighbor.visited = True
messages.append(belief_propagation(graph, neighbor, message_type))
if message_type == 'sum-product':
# 和-积消息传递
combined = product_messages(messages)
return sum_out(combined, exclude=neighbor)
else:
# 最大-积消息传递(用于MAP推断)
combined = product_messages(messages)
return max_out(combined, exclude=neighbor)5.3 近似推断方法
6. 学习问题
6.1 参数学习
极大似然估计(MLE)
对于贝叶斯网络,参数学习相对简单:
def bayesian_network_mle(data, graph):
"""
贝叶斯网络参数学习
data: 观测数据 (N x n)
graph: 图结构
"""
parameters = {}
for node in graph.nodes:
parents = graph.get_parents(node)
if len(parents) == 0:
# 无父节点:计算边缘分布
parameters[node] = compute_empirical_distribution(data[:, node])
else:
# 有父节点:计算条件分布表
parameters[node] = compute_conditional_distribution(data, node, parents)
return parameters6.2 结构学习
从数据中学习图结构:
| 方法 | 原理 | 复杂度 |
|---|---|---|
| PC算法 | 条件独立性检验 | 检验 |
| GES | 贪婪等价搜索 | 局部最优 |
| NOTEARS | 连续优化 | 可扩展 |
7. 与深度学习的联系
7.1 神经网络作为图模型
深度学习的许多模型可以解释为图模型的特殊形式:
7.2 变分自编码器(VAE)
VAE将变分推断与神经网络结合:
# VAE的图模型视角
class VAEFromPGMPerspective:
"""
从概率图模型角度理解VAE
"""
def __init__(self, input_dim, latent_dim):
# 编码器 q(z|x) - 近似后验
self.encoder = NeuralNetwork(input_dim, latent_dim * 2) # 均值+方差
# 解码器 p(x|z) - 生成模型
self.decoder = NeuralNetwork(latent_dim, input_dim)
def forward(self, x):
# 近似后验 q(z|x)
q_params = self.encoder(x)
mu, log_var = q_params[:, :latent_dim], q_params[:, latent_dim:]
# 重参数化技巧
epsilon = torch.randn_like(mu)
z = mu + epsilon * torch.exp(0.5 * log_var)
# 生成 p(x|z)
x_recon = torch.sigmoid(self.decoder(z))
return x_recon, mu, log_var
def elbo(self, x):
"""ELBO = log p(x|z) - KL(q(z|x) || p(z))"""
x_recon, mu, log_var = self.forward(x)
# 重构损失
recon_loss = F.binary_cross_entropy(x_recon, x, reduction='sum')
# KL散度
kl_loss = -0.5 * torch.sum(1 + log_var - mu.pow(2) - log_var.exp())
return recon_loss + kl_loss7.3 GNN的概率解释
GNN的消息传递可以视为MRF上的概率推断:
这等价于在图的邻域上进行置信传播。
8. 实践应用
8.1 医学诊断
贝叶斯网络用于疾病诊断:
症状 → 疾病 → 检查结果
8.2 自然语言处理
CRF广泛用于序列标注:
- 命名实体识别(NER)
- 词性标注(POS tagging)
- 句法分析
8.3 计算机视觉
MRF/CRF用于图像分割:
# 图像CRF后处理示例
class DenseCRF:
def __init__(self, unary_cost, pairwise_cost, image):
self.unary = unary_cost # 像素属于某类的初始概率
self.pairwise = pairwise_cost # 成对势函数
self.image = image # 原始图像
def inference(self, max_iter=10):
"""Dense CRF推断"""
Q = self.unary.copy() # 初始分布
for _ in range(max_iter):
# 消息传递(高斯核)
Q = self.message_pass(Q)
# 兼容约束
Q = self.compatibility_transform(Q)
# 加回一元势能
Q = self.add_unary(Q)
# 归一化
Q = Q / Q.sum(axis=-1, keepdims=True)
return Q9. 总结与展望
9.1 三种模型的对比
| 特性 | 贝叶斯网络 | 马尔可夫随机场 | 条件随机场 |
|---|---|---|---|
| 边类型 | 有向 | 无向 | 无向 |
| 分解形式 | |||
| 适用场景 | 因果建模 | 无向依赖 | 结构化预测 |
| 参数解释 | 因果强度 | 相互作用强度 | 条件关系 |
| 推断难度 | 中等 | 较难 | 较难 |
9.2 发展趋势
参考资料
相关链接
Footnotes
-
Koller, D., & Friedman, N. (2009). Probabilistic Graphical Models: Principles and Techniques. MIT Press. ↩ ↩2
-
Kindermann, R., & Snell, J. L. (1980). Markov Random Fields and Their Applications. American Mathematical Society. ↩
-
Lafferty, J., McCallum, A., & Pereira, F. (2001). Conditional Random Fields: Probabilistic Models for Segmenting and Labeling Sequence Data. ICML 2001. ↩