动态贝叶斯网络

概述

动态贝叶斯网络(Dynamic Bayesian Networks, DBN)是贝叶斯网络在时序数据上的扩展,用于建模随时间演化的随机系统。与隐马尔可夫模型(HMM)等专门的时序模型相比,DBN提供了一个统一的框架,可以灵活地表示各种时序依赖关系12

DBN的核心思想:将时间维度显式地纳入图结构,通过在相邻时间片之间添加边来建模时间依赖性。


1. DBN基础定义

1.1 形式化定义

DBN由以下要素组成:

  • 时间片数量 :序列长度
  • 节点集合 :时刻 的随机变量集合
  • 时间片内结构 :片内条件独立性(相当于贝叶斯网络结构)
  • 时间片间结构 :片间条件依赖(过渡模型)
  • 初始分布 时的先验分布

DBN的关键假设是马尔可夫假设:给定当前状态,过去状态与未来状态条件独立。

1.2 展开表示

DBN可以通过”展开”(Unrolling)转换为有限或无限的静态贝叶斯网络:

时间片1:    X1₁ ──► X1₂
             │
             ▼
时间片2:    X2₁ ──► X2₂
             │
             ▼
时间片3:    X3₁ ──► X3₂

展开后的网络包含所有时间片的节点和片间边,每条边代表条件概率关系。

1.3 DBN与HMM的关系

HMM可以视为DBN的特例:

HMM结构:
  Y₁   Y₂   Y₃   ...   Yₙ      (观测)
  │    │    │          │
  ▼    ▼    ▼          ▼
  X₁──►X₂──►X₃──►...──►Xₙ      (隐状态)
特性HMMDBN
隐状态单一离散变量可以是多个变量
观测变量单一变量可以是多个变量
观测依赖仅依赖当前隐状态可依赖多个时间片
结构固定可自定义

2. DBN结构设计

2.1 马尔可夫阶数

DBN的阶数定义了过去对未来的影响范围:

阶数定义示例
0阶仅依赖当前状态$P(X_{t+1}
1阶依赖最近1个状态$P(X_{t+1}
k阶依赖最近k个状态$P(X_{t+1}

2.2 过渡模型

时间片间条件概率表(CPT) 定义了状态转移:

例如,一阶马尔可夫链的过渡模型:

2.3 发射模型

观测变量与隐状态的条件概率分布:

常见发射模型:

  • 高斯发射
  • 多项发射
  • 混合发射:高斯混合模型(GMM)

3. DBN推断算法

3.1 前向-后向算法

DBN的核心推断任务是计算边缘概率和后验概率。

前向算法

计算前向变量

def forward_algorithm(observations, init_prob, trans_mat, emit_mat):
    """
    前向算法计算 P(X_t | Y_{1:t})
    
    参数:
        observations: 观测序列 [Y_1, ..., Y_T]
        init_prob: 初始概率 [P(X_1=i)]
        trans_mat: 转移矩阵 [P(X_{t+1}=j|X_t=i)]
        emit_mat: 发射矩阵 [P(Y_t|X_t=i)]
    返回:
        alphas: 前向变量 [α_1, ..., α_T]
    """
    T = len(observations)
    num_states = len(init_prob)
    alphas = []
    
    # 初始化: α_1(i) = P(X_1=i) * P(Y_1|X_1=i)
    alpha = init_prob * emit_mat[:, observations[0]]
    alphas.append(alpha)
    
    # 递归: α_{t+1}(j) = [Σ_i α_t(i) * A_{ij}] * B_j(Y_{t+1})
    for t in range(1, T):
        # 过渡
        alpha = np.dot(alpha, trans_mat)
        # 发射
        alpha = alpha * emit_mat[:, observations[t]]
        # 归一化(数值稳定性)
        alpha = alpha / np.sum(alpha)
        alphas.append(alpha)
    
    return alphas

后向算法

计算后向变量

def backward_algorithm(observations, trans_mat, emit_mat):
    """
    后向算法计算 P(Y_{t+1:T} | X_t)
    
    返回:
        betas: 后向变量 [β_1, ..., β_T]
    """
    T = len(observations)
    num_states = trans_mat.shape[0]
    betas = [np.ones(num_states)]
    
    # 初始化: β_T(i) = 1
    for t in range(T-2, -1, -1):
        # 发射和转移
        beta_next = betas[0] * emit_mat[:, observations[t+1]]
        # 反向过渡
        beta = np.dot(trans_mat, beta_next)
        betas.insert(0, beta)
    
    return betas

3.2 滤波与平滑

任务定义方法
滤波$P(X_tY_{1:t})$
预测$P(X_{t+k}Y_{1:t})$
平滑$P(X_tY_{1:T})$

平滑公式(Rauch-Tung-Striebel RTS算法):

平滑增益(smoother gain):

3.3 粒子滤波

当状态空间连续或高维时,使用序贯蒙特卡洛方法。

def particle_filter(observations, num_particles, state_prior, transition_fn, emission_fn, obs_likelihood):
    """
    粒子滤波算法
    
    参数:
        observations: 观测序列
        num_particles: 粒子数量
        state_prior: 初始状态采样函数
        transition_fn: 状态转移函数 p(x'|x)
        emission_fn: 观测采样函数 p(y|x)
        obs_likelihood: 观测似然函数 p(y|x)
    """
    T = len(observations)
    particles = [state_prior(num_particles)]  # 初始粒子
    weights = [np.ones(num_particles) / num_particles]
    
    for t in range(T):
        # 1. 预测:采样新的粒子
        new_particles = transition_fn(particles[-1])
        
        # 2. 更新:计算重要性权重
        likelihoods = obs_likelihood(observations[t], new_particles)
        new_weights = weights[-1] * likelihoods
        new_weights = new_weights / np.sum(new_weights)
        
        # 3. 重采样(如果ESS过低)
        ess = 1 / np.sum(new_weights ** 2)
        if ess < num_particles / 2:
            indices = np.random.choice(num_particles, size=num_particles, p=new_weights)
            new_particles = new_particles[indices]
            new_weights = np.ones(num_particles) / num_particles
        
        particles.append(new_particles)
        weights.append(new_weights)
    
    return particles, weights

4. DBN参数学习

4.1 完全数据情况

当状态序列 完全可观测时,使用计数法

4.2 不完全数据:EM算法

当状态不可观测时,使用Baum-Welch算法(DBN的EM版本):

E步:计算每个时间点每个状态的后验概率

M步:更新参数

4.3 变分推断

当EM难以计算时,使用变分方法近似后验:

变分自由能:


5. 应用实例

5.1 语音识别:GMM-HMM的DBN视角

传统GMM-HMM可以表示为DBN:

      GMM发射           转移
   ┌──────────┐    ┌──────────┐
   │  c₁,μ₁,Σ₁│    │   A₁₁    │
◄─►│  c₂,μ₂,Σ₂│◄──►│   A₁₂    │
   │    ...    │    │   ...    │
   └──────────┘    └──────────┘
       观测Y          隐状态S

5.2 机器人定位:Kalman滤波的DBN表示

线性高斯系统的状态空间模型:

对应的DBN结构:

X_t ──► X_{t+1}    (线性转移)
  │
  ▼
Y_t              (线性发射)

5.3 金融时序:随机波动率模型

DBN可以建模隐波动率 的时序演化。


6. DBN与其他时序模型的关系

6.1 DBN vs HMM

特性HMMDBN
状态维度单一离散变量多维,可连续
观测维度单一变量多变量
转移结构固定一阶马尔可夫可自定义
推断复杂度取决于网络结构

6.2 DBN vs RNN/LSTM

特性DBNRNN/LSTM
表示方式概率图模型神经网络
不确定性原生支持需额外建模
可解释性因果结构透明黑盒
推断精确/近似近似
扩展性随状态空间指数增长可处理大状态空间

6.3 DBN vs SSM

状态空间模型(State Space Model)与DBN在形式上等价:

  • 连续SSM
  • 离散SSM
  • DBN:图结构化的状态空间模型

7. 代码实现:完整DBN框架

import numpy as np
from typing import List, Tuple, Callable, Optional
 
class DynamicBayesianNetwork:
    """动态贝叶斯网络实现"""
    
    def __init__(self, init_prob: np.ndarray, trans_mat: np.ndarray, emit_mat: np.ndarray):
        """
        初始化DBN
        
        参数:
            init_prob: 初始概率分布 [N_states]
            trans_mat: 转移矩阵 [N_states, N_states]
            emit_mat: 发射矩阵 [N_states, N_obs] 或 [N_states] 对于连续
        """
        self.init_prob = init_prob
        self.trans_mat = trans_mat
        self.emit_mat = emit_mat
        self.num_states = len(init_prob)
    
    def forward(self, observations: List[int]) -> Tuple[np.ndarray, float]:
        """前向算法"""
        T = len(observations)
        alphas = np.zeros((T, self.num_states))
        
        # 初始化
        alphas[0] = self.init_prob * self.emit_mat[:, observations[0]]
        alphas[0] = alphas[0] / np.sum(alphas[0])
        
        # 递归
        for t in range(1, T):
            alphas[t] = np.dot(alphas[t-1], self.trans_mat)
            alphas[t] = alphas[t] * self.emit_mat[:, observations[t]]
            alphas[t] = alphas[t] / np.sum(alphas[t])
        
        log_likelihood = np.sum(np.log(np.dot(alphas[-1], np.ones(self.num_states))))
        return alphas, log_likelihood
    
    def backward(self, observations: List[int]) -> np.ndarray:
        """后向算法"""
        T = len(observations)
        betas = np.ones((T, self.num_states))
        
        for t in range(T-2, -1, -1):
            betas[t] = np.dot(self.trans_mat, 
                            self.emit_mat[:, observations[t+1]] * betas[t+1])
            betas[t] = betas[t] / np.sum(betas[t])
        
        return betas
    
    def forward_backward(self, observations: List[int]) -> Tuple[np.ndarray, np.ndarray]:
        """前向后向算法"""
        alphas, _ = self.forward(observations)
        betas = self.backward(observations)
        
        # 平滑
        gammas = alphas * betas
        gammas = gammas / gammas.sum(axis=1, keepdims=True)
        
        # 平滑转移
       xis = np.zeros((len(observations)-1, self.num_states, self.num_states))
        for t in range(len(observations)-1):
            for i in range(self.num_states):
                for j in range(self.num_states):
                    xis[t,i,j] = alphas[t,i] * self.trans_mat[i,j] * \
                                  self.emit_mat[j, observations[t+1]] * betas[t+1,j]
            xis[t] = xis[t] / xis[t].sum()
        
        return gammas, xis
    
    def viterbi(self, observations: List[int]) -> Tuple[List[int], float]:
        """Viterbi解码"""
        T = len(observations)
        delta = np.zeros((T, self.num_states))
        psi = np.zeros((T, self.num_states), dtype=int)
        
        # 初始化
        delta[0] = self.init_prob * self.emit_mat[:, observations[0]]
        
        # 递归
        for t in range(1, T):
            for j in range(self.num_states):
                trans_probs = delta[t-1] * self.trans_mat[:, j]
                delta[t, j] = np.max(trans_probs) * self.emit_mat[j, observations[t]]
                psi[t, j] = np.argmax(trans_probs)
        
        # 回溯
        path = [np.argmax(delta[-1])]
        for t in range(T-1, 0, -1):
            path.insert(0, psi[t, path[0]])
        
        log_prob = np.log(np.max(delta[-1]))
        return path, log_prob

8. 总结与展望

核心要点

  1. DBN提供统一框架:将各种时序概率模型纳入统一的图结构框架
  2. 灵活性与可解释性:可以自定义状态维度和依赖关系
  3. 推断算法成熟:前向-后向、粒子滤波等成熟方法可用
  4. 学习挑战:参数学习在高维情况下面临计算复杂度问题

未来方向

  • 变分DBN:处理高维连续状态
  • 深度DBN:与神经网络结合的混合模型
  • 因果DBN:加入因果推断能力
  • 在线DBN:实时学习和推断

参考资料


相关主题

Footnotes

  1. Murphy, K. (2002). “Dynamic Bayesian Networks: Representation, Inference and Learning.” PhD Thesis, UC Berkeley.

  2. Koller, D., & Friedman, N. (2009). “Probabilistic Graphical Models: Principles and Techniques.” MIT Press.