CRL与动力系统结合 (CRL Combined with Dynamical Systems)
一句话定位
因果表示学习与动力系统的结合将因果结构扩展到连续时间领域,通过状态空间模型和神经微分方程建模时序数据中的因果关系。
前置知识
- 因果表示学习基础:编码器、解码器、因果结构
- 动力系统基础:微分方程、相空间、稳定性
- 状态空间模型:隐马尔可夫模型、卡尔曼滤波
- 神经网络:NNodes、ResNet、编码器-解码器
核心直觉
在许多现实应用中,数据本质上是时序的:股票价格、心电图、视频帧、机器人传感器读数等。在这些场景中,数据的生成过程通常涉及潜在的因果动力系统,这个系统随时间演变并产生观测数据。
关键洞察:时间序列中的相关性可能来自两个来源:
- 因果关系:一个变量直接导致另一个变量的变化
- 虚假相关:两个变量都受某个共同原因的影响,或者由于时序依赖而产生相关
例如,在心电图中,心跳(R波)和血压可能高度相关,但这种相关可能是因为两者都由神经系统的共同控制所导致,而不是直接因果关系。
将因果表示学习扩展到动力系统需要:
- 时间维度的因果结构:不仅考虑变量之间的因果关系,还考虑时间上的因果传播
- 连续时间模型:使用微分方程描述连续时间演变
- 状态空间表示:将系统状态建模为低维因果变量
问题形式化
状态空间模型
设
其中:
是状态转移函数(因果机制) 是观测函数(解码器) 是输入/控制
连续时间因果模型
假设隐状态
其中
因果发现的目标
从观测数据
- 隐状态维度
- 因果结构
(哪个 影响哪个 ) - 动态函数
时间序列中的因果 vs 虚假相关
因果相关:
数学框架
神经微分方程 (NODE)
神经微分方程使用神经网络参数化连续时间动态:
给定初始状态
因果 NODE
将因果结构融入 NODE:
其中
这强制因果结构在动态中保持:只有父节点可以影响
状态空间模型的因果解释
考虑线性高斯状态空间模型:
其中
从因果角度看:
意味着 是 的因 - 稀疏结构可以通过稀疏化
来实现
时序因果结构的可辨识性
定理:在时序设置下,如果满足以下条件,因果结构是可辨识的:
- 充分激励:系统有足够的输入变化来激发所有因果路径
- 稀疏性:每个变量只受少数其他变量影响
- 非奇异性:动态函数是可逆的
证明思路:在时序数据中,我们可以观察变量的时间演变,通过干预和时间依赖性来区分因果方向和虚假相关。
训练与估计
变分推断扩展
对于状态空间模型,变分推断需要:
- 识别后验:
- 动态先验:
由因果结构决定
ELBO:
编码器-解码器架构
class CausalSSM(nn.Module):
def __init__(self, dim_x, dim_z, causal_graph):
self.encoder = Encoder(dim_x, dim_z) # 观测 -> 隐状态
self.decoder = Decoder(dim_z, dim_x) # 隐状态 -> 观测
self.dynamics = CausalDynamics(dim_z, causal_graph) # 因果动态
def forward(self, x_sequence):
# 编码整个序列
z_0 = self.encoder(x_sequence[:, 0])
# 通过因果动态传播
z_hidden = [z_0]
for t in range(1, len(x_sequence)):
z_t = self.dynamics(z_hidden[-1])
z_hidden.append(z_t)
# 解码
x_recon = [self.decoder(z) for z in z_hidden]
return x_recon, z_hidden
class CausalDynamics(nn.Module):
def __init__(self, dim_z, causal_graph):
super().__init__()
self.causal_graph = causal_graph
# 每个变量有自己的动态网络
self.dynamics_nets = nn.ModuleDict({
f'z_{i}': MLP(dim_z, dim_z)
for i in range(dim_z)
})
def forward(self, z):
dz_dt = torch.zeros_like(z)
for i in range(dim_z):
# 只使用父节点的表示来计算变化率
parents = self.causal_graph.get_parents(i)
z_parents = z[:, parents]
dz_dt[:, i] = self.dynamics_nets[f'z_{i}'](z_parents).squeeze()
# 积分获得新状态
z_new = z + dz_dt * dt
return z_new时序因果发现
从数据中发现时序因果结构:
- 基于约束的方法:利用条件独立性测试
- 基于得分的方法:优化某种准则(如 BIC)
- 连续方法:使用神经网络端到端学习
推理与干预
状态估计
给定观测序列
可以使用卡尔曼滤波或粒子滤波。
时序 do 操作
在时序设置下,do 操作作用在隐状态的动态上:
这强制
预测与干预
给定干预
反事实时序
反事实推理在时序设置下更加复杂:
- 观察实际轨迹
- 应用干预
- 模拟替代轨迹
优点与局限
优点
- 自然建模:连续时间模型更接近物理世界的本质
- 因果解释:时序因果结构提供更强的解释性
- 预测能力:因果动态模型可以更好地预测干预效果
- 处理缺失数据:连续模型可以自然地处理不规则采样
局限
- 计算复杂度:连续模型通常计算成本高
- 可辨识性困难:时序因果结构的可辨识性比静态更复杂
- 模型假设:需要假设动态函数的形式
- 噪声处理:过程噪声和观测噪声的建模困难
与其他笔记的联系
- 因果生成模型:状态空间模型是因果生成模型在时序上的扩展
- 可解释隐变量动力学:关注从数据中发现稀疏因果结构
- 稀疏性原则:稀疏性在时序因果发现中很重要
- Multi-View CRL:多模态时序数据
可重现性笔记
常用数据集
- PhysioNet:生理时间序列(心电图、血压等)
- MIMIC:重症监护数据
- 机器人操作:Sawyer机械臂数据
- 交通数据:传感器时序数据
评估指标
- MSE:预测误差
- 因果结构准确性:恢复的因果图与真实图的比较
- 反事实一致性:反事实预测与实际干预结果的一致性
代码框架
# 时序因果表示学习
class TemporalCRL(nn.Module):
def __init__(self, dim_x, dim_z):
self.encoder = TemporalEncoder(dim_x, dim_z)
self.decoder = TemporalDecoder(dim_z, dim_x)
self.causal_dynamics = NeuralODE(dim_z, causal=True)
def forward(self, x_seq):
z0 = self.encoder(x_seq[:, 0])
z_seq = [z0]
for t in range(1, len(x_seq)):
# 因果动态
z_next = self.causal_dynamics(z_seq[-1])
z_seq.append(z_next)
# 解码
x_recon_seq = [self.decoder(z) for z in z_seq]
return x_recon_seq, z_seq章节总结
- 动力系统中的因果结构体现在连续时间上的因果动力学
- 状态空间模型结合因果表示和时序动力学
- 隐 ODE 将因果变量建模为连续时间动态系统
- 时间序列中的因果相关和虚假相关需要区分
- NODE 和因果 NODE 结合神经网络和因果结构
- 时序 CRL 需要处理时序依赖和因果结构的联合学习
- 在动力系统中因果发现更困难但更有价值
- 连续时间模型比离散时间模型更自然
- 稀疏性在时序因果发现中也很重要
- 应用:生理监控、机器人控制、经济预测
关键词
causal representation learning, dynamical systems, state-space model, latent ODE, causal discovery, neural ODE, time series, continuous-time dynamics, causal dynamics, intervention