1. 研究背景

1.1 因果发现的任务

因果发现旨在从观测数据中推断变量间的因果关系1

# 从数据中发现因果结构
data = load_observational_data()
graph = causal_discovery(data)  # 推断因果图

1.2 现有方法的局限

方法优势局限
PC算法理论基础强计算复杂度高
NOTEARS可微分需要领域知识
DAG-GNN端到端需要重训练

1.3 Arrow的愿景

构建一个零样本因果发现的基础模型,无需重训练即可应用于新数据集。

2. 技术框架

2.1 核心思想

Arrow基于以下洞察1

  1. 因果结构的普遍性:高质量因果图共享通用模式
  2. 表示学习:学习跨领域的通用因果表示
  3. 适配器设计:少量参数即可适应新领域

2.2 架构设计

┌─────────────────────────────────────────────────────────────────────────┐
│                           Arrow 架构                                     │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                          │
│  预训练阶段:                                                           │
│    ┌─────────────────────────────────────────────────────────────┐    │
│    │         多源因果数据集预训练                                 │    │
│    │                                                                 │    │
│    │   Dataset1: 生物数据 ──► 因果图                             │    │
│    │   Dataset2: 经济数据 ──► 因果图                             │    │
│    │   Dataset3: 医疗数据 ──► 因果图                             │    │
│    │                                                                 │    │
│    │   ↓ 共享因果表示学习                                         │    │
│    └─────────────────────────────────────────────────────────────┘    │
│                                                                          │
│  推理阶段(零样本):                                                   │
│    ┌─────────────────────────────────────────────────────────────┐    │
│    │         新数据集 → 因果发现                                  │    │
│    │                                                                 │    │
│    │   新数据 ──► Arrow编码器 ──► 因果图                        │    │
│    │              ↑                                               │    │
│    │         无需参数更新!                                        │    │
│    │                                                                 │    │
│    └─────────────────────────────────────────────────────────────┘    │
│                                                                          │
└─────────────────────────────────────────────────────────────────────────┘

3. 核心算法

3.1 因果图表示

class CausalGraphEncoder(nn.Module):
    """
    因果图编码器
    学习通用的因果结构表示
    """
    def __init__(self, num_vars, hidden_dim):
        super().__init__()
        
        # 变量表示
        self.var_embedding = nn.Embedding(num_vars, hidden_dim)
        
        # 边表示(可学习的邻接矩阵)
        self.adj_logits = nn.Parameter(torch.zeros(num_vars, num_vars))
        
        # 因果强度编码
        self.strength_encoder = nn.Sequential(
            nn.Linear(hidden_dim * 2, hidden_dim),
            nn.ReLU(),
            nn.Linear(hidden_dim, 1)
        )
        
    def forward(self, var_indices):
        """
        Args:
            var_indices: 变量索引 [B, N]
        Returns:
            adj_matrix: 因果邻接矩阵 [B, N, N]
        """
        # 变量嵌入
        var_emb = self.var_embedding(var_indices)  # [B, N, hidden]
        
        # 计算边强度
        adj_logits = self.adj_logits.unsqueeze(0)  # [1, N, N]
        
        # 注意力计算
        src = var_emb.unsqueeze(2)  # [B, N, 1, hidden]
        dst = var_emb.unsqueeze(1)  # [B, 1, N, hidden]
        
        strength = self.strength_encoder(torch.cat([src, dst], dim=-1))
        strength = strength.squeeze(-1)  # [B, N, N]
        
        # 融合
        adj = torch.sigmoid(strength + adj_logits)
        
        return adj

3.2 零样本推理

class ArrowZeroShotCausalDiscovery:
    """
    Arrow零样本因果发现
    """
    def __init__(self, model, device='cuda'):
        self.model = model
        self.model.eval()
        self.device = device
        
    @torch.no_grad()
    def discover(self, data, var_names=None):
        """
        零样本因果发现
        Args:
            data: 观测数据 [N, D]
            var_names: 变量名列表
        Returns:
            adj_matrix: 因果邻接矩阵
        """
        # 标准化数据
        data_norm = (data - data.mean(0)) / (data.std(0) + 1e-8)
        
        # 构建变量索引
        num_vars = data.shape[1]
        var_indices = torch.arange(num_vars, device=self.device).unsqueeze(0)
        
        # 编码
        adj = self.model(var_indices)  # [1, N, N]
        adj = adj.squeeze(0).cpu().numpy()
        
        # 移除自环
        np.fill_diagonal(adj, 0)
        
        # 阈值化
        threshold = 0.3
        adj_binary = (adj > threshold).astype(int)
        
        return adj_binary, adj

4. 理论分析

4.1 表示学习理论

假设(因果结构普遍性):高质量因果图在语义空间中形成低维流形。

定理(跨域泛化):设源域和目标域共享隐因果流形 ,则Arrow学到的表示 满足:

4.2 零样本保证

引理(分布无关性):Arrow的因果发现能力与具体数据集分布无关,仅依赖于因果结构的普遍模式。

5. 实验结果

5.1 标准基准

Sachs数据集

方法SHD↓SID↓运行时
PC1542120s
GES123845s
NOTEARS10358s
Arrow8280.5s

5.2 零样本泛化

跨数据集评估

源 → 目标同分布Arrow零样本微调后
Bio → Econ0.850.720.83
Med → Social0.880.680.81
Tech → Finance0.820.650.78

5.3 计算效率

方法时间内存
PCO(n²)
GESO(n³)
ArrowO(1)

6. 总结

6.1 主要贡献

  1. 零样本因果发现:无需重训练
  2. 跨域泛化:利用因果结构的普遍性
  3. 高效推理:预训练+推理模式

6.2 局限性

  1. 精度限制:复杂因果结构可能不准确
  2. 领域依赖:部分领域缺乏预训练数据
  3. 时序数据:主要针对表格数据

参考文献

Footnotes

  1. Arrow: A Foundation Model for Causal Discovery, arXiv:2605.07204 2