因果发现评测指标 (Evaluation Metrics for Causal Discovery)
定位: 因果发现评测指标用于量化因果发现算法的输出与真实因果结构之间的差异,是算法比较和方法选择的关键依据。
前置知识: 因果图结构(DAG/CPDAG)、图论基础(邻接矩阵、路径)、因果发现算法(PC/GES/NOTEARS)
核心直觉
核心直觉: 因果结构是离散的图结构,评测需要捕捉两种误差:(1)边的错误(添加、删除、方向反转);(2)干预效果的误差。CPDAG的存在要求评测必须考虑马尔可夫等价类,而非仅比较单个DAG。
评测指标设计需要在计算效率和统计意义之间权衡。SHD简单直观但对边方向敏感;SID更符合因果推断的实际需求但计算复杂。
数学推导
1. 结构汉明距离 (SHD)
SHD是最常用的评测指标,定义为将估计图
其中:
: 需要添加的边数 : 需要删除的边数 : 需要反转方向的边数
定义:
其中
2. 加权SHD
对不同类型的错误赋予不同权重:
典型设置:
3. SHD-CPDAG
当真实结构是DAG而估计是CPDAG时:
即在真实DAG的等价类中选择最优匹配。
4. 结构干预距离 (SID)
SID衡量干预下预测误差:
其中:
: 干预目标变量 : 干预值 : 在DAG 中, 对所有其他变量的干预效应向量
性质:
- SID = 0 当且仅当两个图干预等价
- SID 对边方向比SHD更敏感
- 考虑了马尔可夫等价类的干预效果
5. SID的计算
对于干预
计算时需要对每个变量进行do演算,复杂度为
6. 边精度与召回率
边精度:
其中
边召回率:
其中
7. 骨架精度与召回率
忽略边方向,仅比较骨架(无向图):
其中
8. 临界真值 (Critical True Value)
对于CPDAG估计,边被正确识别的条件:
- 若真实边是单向的: 估计为相同方向 → 正确
- 若真实边是双向的(CPDAG中): 估计为任一方向 → 正确
- 若真实边是单向的: 估计为双向 → 错误(过度定向)
9. 时间阈值敏感性
大多数指标对算法阈值(如CI检验的
通常
训练与估计
评测流程
def evaluate_causal_discovery(G_true, G_est, metric='shd'):
"""
评测因果发现算法输出
参数:
- G_true: 真实DAG或CPDAG
- G_est: 估计的DAG或CPDAG
- metric: 'shd', 'sid', 'sid_cpdag', 'precision', 'recall'
"""
if metric == 'shd':
return structural_hamming_distance(G_true, G_est)
elif metric == 'sid':
return structural_interventional_distance(G_true, G_est)
elif metric == 'sid_cpdag':
return sid_cpdag(G_true, G_est)
elif metric == 'precision':
return edge_precision(G_true, G_est)
elif metric == 'recall':
return edge_recall(G_true, G_est)计算复杂度
| 指标 | 时间复杂度 | 说明 |
|---|---|---|
| SHD | 边比较 | |
| SID | 对每个干预进行do演算 | |
| SHD-CPDAG | 需要遍历等价类(实际用近似) |
推理/干预/反事实
指标与干预效果的关系
- SHD: 衡量结构差异,但边的改变不一定影响干预效果
- SID: 直接衡量干预效果差异,更适合实际应用
- 骨架精度: 衡量因果发现的核心能力(发现连接性)
选择指南
| 应用场景 | 推荐指标 | 原因 |
|---|---|---|
| 算法原型开发 | SHD | 快速、易计算 |
| 干预决策系统 | SID | 与实际效用相关 |
| 高维问题 | 骨架精度/召回 | 关注核心因果发现能力 |
| 马尔可夫等价类研究 | SHD-CPDAG | 处理等价类模糊性 |
优点与局限
SHD优点
- 直观: 对应编辑图的操作数
- 高效:
计算 - 标准化: 被广泛采用
SHD局限
- 等权重假设: 添加边和删除边可能不等价
- 方向敏感: 轻微的方向错误可能导致大SHD
- 不反映干预效果: 结构差异不一定影响实际应用
SID优点
- 因果意义: 直接衡量干预效果差异
- 完整性: 考虑所有单变量干预
SID局限
- 计算复杂:
- 假设离散/连续: 实现依赖于数据分布假设
与其他笔记的连接
- 应用: 所有因果发现算法(PC, GES, NOTEARS, PCMCI)都使用这些指标
- 数据: 合成数据与基准使用这些指标评估算法
- 理论: 指标设计反映了因果结构识别的核心挑战
可复现性说明
实现细节
import numpy as np
def structural_hamming_distance(G1, G2):
"""计算两个DAG之间的SHD"""
n = G1.shape[0]
diff = 0
for i in range(n):
for j in range(n):
if G1[i, j] != G2[i, j]:
diff += 1
return diff
def edge_precision_recall(G_true, G_est):
"""计算边的精度和召回率"""
true_edges = set(zip(*np.where(G_true)))
est_edges = set(zip(*np.where(G_est)))
tp = len(true_edges & est_edges)
fp = len(est_edges - true_edges)
fn = len(true_edges - est_edges)
precision = tp / (tp + fp) if (tp + fp) > 0 else 0
recall = tp / (tp + fn) if (tp + fn) > 0 else 0
return precision, recall
def sid(G_true, G_est):
"""
计算SID (Structural Interventional Distance)
简化版本,假设线性高斯模型
"""
n = G_true.shape[0]
sid_total = 0
# 遍历每个干预目标
for i in range(n):
# 计算真实图的干预效应
effects_true = compute_intervention_effect(G_true, i)
# 计算估计图的干预效应
effects_est = compute_intervention_effect(G_est, i)
# 累加差异
sid_total += np.sum(np.abs(effects_true - effects_est))
return sid_total
def compute_intervention_effect(G, target):
"""计算DAG中单一干预的效应向量"""
n = G.shape[0]
effects = np.zeros(n - 1)
# 使用do演算计算干预效应
# 简化实现:假设线性模型
return effects阈值敏感性分析
def threshold_sensitivity(algorithm, data, alpha_range):
"""
分析算法对阈值的敏感性
alpha_range: 显著性水平范围
"""
results = []
for alpha in alpha_range:
G_est = algorithm(data, alpha=alpha)
shd = structural_hamming_distance(G_true, G_est)
sid = sid(G_true, G_est)
results.append({'alpha': alpha, 'shd': shd, 'sid': sid})
return results章节总结
- SHD(结构汉明距离)定义为将估计图变为真实图的最小边操作数(添加/删除/反转)
- SHD计算复杂度
,是因果发现评测的标准指标 - SID(结构干预距离)直接衡量干预效应的差异,更符合因果推断的实际需求
- SHD-CPDAG处理真实图为DAG、估计为CPDAG的情况,在等价类中选择最优匹配
- 边精度和召回率从不同角度衡量因果发现的能力
- 骨架精度/召回率忽略方向,关注核心的因果连接发现能力
- SHD对边方向敏感,相同结构但不同方向的边仍计为错误
- SID计算复杂度
,但直接反映干预下的预测误差 - 阈值敏感性是评测的重要方面:
增大通常导致更稀疏的图 - 指标选择应根据应用场景:原型开发用SHD,干预系统用SID,高维问题用骨架指标
关键词: SHD, SID, 结构汉明距离, 结构干预距离, CPDAG评测, 边精度, 边召回率, 阈值敏感性