概述
反事实推理(Counterfactual Reasoning)是因果推断的最高层级,回答”如果…会怎样”的问题。反事实不仅考虑”发生了什么”,更追问”如果没有发生A,B还会发生吗”。这在医学诊断、法律推理、科学发现等领域具有核心重要性。1
深度学习与反事实推理的结合开辟了新的研究方向:从反事实图像生成到可执行的代码级反事实推理,本专题系统梳理这一领域的理论基础与技术进展。
反事实推理基础理论
因果三层级回顾
Judea Pearl提出的因果层级揭示了认知难度:
| 层级 | 问题形式 | 示例 | 可回答性 |
|---|---|---|---|
| L1 | 关联 | 闪电后预计雷声? | 观测数据直接回答 |
| L2 | 干预 | 强制降雨后产量? | 需要实验或因果假设 |
| L3 | 反事实 | 如果我没吸烟… | 需要反事实推理 |
反事实的形式化定义
给定结构因果模型(SCM) ,反事实查询 定义为:
关键步骤(Abduction-Computation-Derivation, ABC):
-
Abduction(推断):基于观测数据推断外生变量
-
Action(行动):执行干预
-
Derivation(推导):计算反事实结果
# 反事实推理的简化实现
class CounterfactualReasoner:
"""
基于SCM的反事实推理器
"""
def __init__(self, scm):
"""
scm: dict, 结构因果模型的函数定义
例如: {'X': lambda eps: eps['x'],
'Y': lambda x, eps: 2*x + eps['y']}
"""
self.scm = scm
def abduce(self, observations):
"""
基于观测推断外生变量
"""
epsilon = {}
for var, obs_val in observations.items():
# 使用观测值反推外生变量
parents = self.get_parents(var)
parent_vals = {p: observations.get(p, None) for p in parents}
epsilon[var] = self.scm[var](**parent_vals) - obs_val
return epsilon
def compute_counterfactual(self, intervention, target, epsilon, fixed_observations):
"""
计算反事实:Y_x(u)
参数:
intervention: dict, 例如 {'X': 1} 表示 do(X=1)
target: str, 目标变量名
epsilon: dict, 推断的外生变量
"""
# 1. 修正(Act):应用干预
modified_scm = self.scm.copy()
for var, val in intervention.items():
modified_scm[var] = lambda v=val: v
# 2. 拓扑排序计算
computed = fixed_observations.copy()
for var in self.topological_order():
if var in intervention:
computed[var] = intervention[var]
elif var in fixed_observations:
continue
else:
# 从干预后的SCM计算
parents = self.get_parents(var)
parent_vals = {p: computed[p] for p in parents}
computed[var] = modified_scm[var](**parent_vals)
return computed[target]反事实与条件期望的区别
反事实推理与条件期望有本质区别:
示例:在混杂存在时,
- (条件概率)
- (因果效应,因为部分康复患者是因为病情轻才吃药)
深度学习反事实生成
Countenance模型:分离变异因素
Countenance框架2提出通过反事实图像学习解耦表示:
核心思想:图像的变异来自多个因素——物体身份、姿态、光照、背景等。好的表示应该能独立控制这些因素。
架构设计:
┌─────────────────────────────────────────────────────────────┐
│ Countenance 模型 │
│ │
│ 输入图像 ──→ 编码器 E ──→ 潜在因素 z = (z_id, z_pose, ...) │
│ │ │
│ ┌─────────────┼─────────────┐ │
│ ▼ ▼ ▼ │
│ 身份因素 姿态因素 光照因素 │
│ │ │ │ │
│ └─────────────┼─────────────┘ │
│ ▼ │
│ 解码器 D ──→ 重构图像 │
│ │
│ 关键约束:改变 z_pose 而固定 z_id,应生成同物体不同姿态 │
└─────────────────────────────────────────────────────────────┘
损失函数设计:
其中:
- :重构损失
- :因素分离损失(鼓励因素独立)
- :反事实一致性损失
CausalGAN与因果驱动的生成
CausalGAN3将因果结构融入GAN框架:
因果生成模型:
其中因果结构定义因素间的依赖关系:
Z_semantic
(语义因素)
↓
┌───────┴───────┐
↓ ↓
Z_shape Z_color
(形状) (颜色)
↓ ↓
└───────┬───────┘
↓
生成图像 Canvas
反事实图像评估指标
| 指标 | 定义 | 理想值 |
|---|---|---|
| Validity | 生成图像满足目标反事实的程度 | 越高越好 |
| Actionability | 修改是可操作/有意义的 | 越高越好 |
| Sparsity | 修改最小化(仅改变必要因素) | 越高越好 |
| Identity Preservation | 保持原始图像身份 | 越高越好 |
可执行反事实(Executable Counterfactuals)
问题背景
传统反事实解释生成的是自然语言描述,难以验证和执行。可执行反事实4提出生成可执行的代码级反事实:
定义:给定输入x和目标预测y’,生成扰动 使得:
且 可以被解释为语义上有意义的操作序列。
ICML 2025: 可执行反事实框架
核心架构:
┌──────────────────────────────────────────────────────────────┐
│ 可执行反事实生成流程 │
│ │
│ 输入: (x, y_current) ─→ 目标: y_target │
│ │ │
│ ▼ │
│ ┌─────────────────┐ │
│ │ 操作提议器 │ 生成候选操作序列 │
│ │ Operation │ [操作1, 操作2, 操作3, ...] │
│ │ Proposer │ │
│ └────────┬────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────┐ │
│ │ 有效性验证器 │ 检查约束满足 │
│ │ Constraint │ • 语义有效性 │
│ │ Verifier │ • 因果有效性 │
│ └────────┬────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────┐ │
│ │ 执行引擎 │ 编译执行为可执行代码 │
│ │ Execution │ 返回反事实 │
│ │ Engine │ x_cf = execute(operations) │
│ └─────────────────┘ │
└──────────────────────────────────────────────────────────────┘
数学框架:
定义操作空间 ,反事实问题形式化为:
其中 衡量操作的成本/复杂性。
约束满足条件
可执行反事实必须满足:
-
有效性约束:
-
因果有效性:
-
最小性约束:
LLM反事实推理
CounterFact数据集
CounterFact5是评估语言模型知识编辑的重要数据集:
数据集结构:
| 字段 | 描述 | 示例 |
|---|---|---|
prompt | 输入提示 | ”The capital of France is” |
ground_truth | 真实答案 | ”Paris” |
target_new | 编辑后答案 | ”Lyon” |
relation_id | 关系类型 | CAPITANL_OF |
neighborhood_prompts | 邻近反事实 | ”France’s capital is” |
评估维度:
class CounterFactEvaluator:
def evaluate(self, model, edit_data):
results = {}
# 1. 靶向准确性:编辑后能否正确回答
results['target_accuracy'] = self.check_target(
model,
edit_data['prompt'],
edit_data['target_new']
)
# 2. 邻近泛化:相关问题是否正确
results['neighborhood_acc'] = self.check_neighborhood(
model,
edit_data['neighborhood_prompts'],
edit_data['ground_truth'] # 应保持不变
)
# 3. 无关测试:无关知识是否保留
results['paraphrase_acc'] = self.check_irrelevant(
model,
edit_data['paraphrase_prompts'],
edit_data['ground_truth']
)
return resultsG2-Reasoner: 目标导向因果推理
G2-Reasoner6提出结合知识图谱与目标导向推理:
核心思想:
推理流程:
- 知识注入:将结构化知识(知识图谱)注入LLM
- 目标展开:从目标反向推理所需操作
- 行动验证:验证行动序列能否达到目标
class G2Reasoner:
def __init__(self, llm, knowledge_graph):
self.llm = llm
self.kg = knowledge_graph
def counterfactual_reasoning(self, query, target):
"""
目标导向反事实推理
"""
# 1. 知识检索
relevant_knowledge = self.kg.query(query)
# 2. 目标展开(从目标反向)
goal_chain = self.backward_chain(target)
# 3. 行动序列生成
actions = self.generate_actions(goal_chain, relevant_knowledge)
# 4. 验证与修正
validated_actions = self.validate(actions, query)
return validated_actions链式思维中的反事实推理
Chain-of-Thought提示可以增强LLM的反事实推理能力:
提示策略:
cot_prompt = """
问题:如果我没有吸烟,现在我会得肺癌吗?
步骤1:识别因果关系
- 吸烟 → 肺癌(直接因果路径)
步骤2:推断反事实条件
- 条件:do(吸烟=否)
步骤3:评估因果效应
- 吸烟对肺癌的直接效应 = P(肺癌|do(吸烟=是)) - P(肺癌|do(吸烟=否))
- 根据流行病学数据,吸烟者肺癌风险约20倍于非吸烟者
步骤4:反事实结论
- 如果没有吸烟,患肺癌的概率将大幅降低
"""因果反事实评估基准
CounterBench
CounterBench7是评估模型反事实推理能力的综合基准:
任务分类:
| 类别 | 描述 | 示例 |
|---|---|---|
| CF-Prediction | 预测反事实结果 | ”如果A变为X,Y会怎样变化?“ |
| CF-Generation | 生成反事实场景 | ”描述一个X导致Y的替代场景” |
| CF-Explanation | 解释因果机制 | ”为什么X导致Y?“ |
| CF-Intervention | 设计干预方案 | ”如何阻止X导致Y?“ |
CRE-Exec:可执行因果推理评估
CRE-Exec8评估模型的可执行因果推理能力:
核心任务:给定因果图和干预,生成可执行的Python代码计算因果效应。
# 示例任务
task = {
"causal_graph": {
"X": [], # 无父节点
"Z": ["X"], # Z受X影响
"Y": ["X", "Z"] # Y受X和Z影响
},
"intervention": {"do(X=1)"}, # 干预X=1
"query": "P(Y=1|do(X=1))", # 查询
"expected_output": """
# 计算后门调整
P(Y=1|do(X=1)) = sum_z P(Y=1|X=1, Z=z) * P(Z=z)
"""
}因果反事实质量指标
| 指标 | 公式/定义 | 说明 |
|---|---|---|
| 反事实F1 | 有效性度量 | |
| 因果保真度 | $1 - | P(Y_x){\text{pred}} - P(Y_x){\text{true}} |
| 解释连贯性 | LLM评估分数 | 解释质量 |
深度学习反事实推理方法
因果驱动的数据增强
反事实增强可以提升模型鲁棒性:
class CausalDataAugmentation:
def __init__(self, causal_graph):
self.causal_graph = causal_graph
def generate_counterfactual(self, x, target_var, target_val):
"""
基于因果图生成反事实样本
"""
# 1. 识别从target_var到x的因果路径
paths = find_causal_paths(self.causal_graph, target_var, x)
# 2. 对每条路径应用干预
cf_samples = []
for path in paths:
intervened_x = apply_intervention(x, target_var, target_val, path)
cf_samples.append(intervened_x)
# 3. 组合反事实
return combine_counterfactuals(cf_samples)对抗反事实训练
其中 是因果图, 鼓励模型对因果干预具有鲁棒性。
实践指南
实现步骤
- 构建因果图:明确变量间的因果关系
- 选择反事实类型:图像、语言、代码
- 设计干预机制:如何修改输入
- 验证有效性:确保反事实满足约束
- 评估质量:使用多维指标
注意事项
- 避免虚假反事实:确保干预通过真实因果机制
- 平衡有效性与最小性:过多样本修改可能失去解释价值
- 验证泛化性:测试集外反事实的有效性
相关内容
参考文献
Last updated: 2026-05-14
Footnotes
-
Pearl, J. “Causality: Models, Reasoning, and Inference” (2nd ed.). Cambridge University Press, 2009. ↩
-
Ilahi et al. “Countenance: Disentangling Fact from Artifact in Generative Models.” arXiv:2305.14712, 2023. ↩
-
Kocaoglu et al. “CausalGAN: Learning Causal Implicit Generative Models.” ICLR 2018. ↩
-
ICML 2025. “Executable Counterfactuals: Generating Interpretable and Executable Code.” OpenReview, 2025. ↩
-
Meng et al. “Locating and Editing Factual Associations in GPT.” NeurIPS 2022. ↩
-
arXiv:2506.21215. “G2-Reasoner: Goal-oriented Causal Reasoning with Large Language Models.” 2025. ↩
-
NeurIPS 2025. “CounterBench: A Comprehensive Benchmark for Counterfactual Reasoning.” 2025. ↩
-
arXiv:2511.04082. “CRE-Exec: Causal Reasoning Evaluation through Executable Programs.” 2024. ↩