使用 GCM 估计平均因果效应#

最常见的因果问题之一是,在两种不同的干预/处理下,某个目标量的差异有多大。这也被称为平均处理效应 (ATE) 或更广泛地称为平均因果效应 (ACE)。最简单的形式是比较两种处理,即在处理 A 下与处理 B 下,我的目标量平均差异是多少。例如,接受某种药物治疗的患者 (\(T:=1\)) 是否比完全未接受治疗的患者 (\(T:=0\)) 恢复得更快。ACE API 允许估计目标节点中的此类差异,即它估计数量 \(\mathbb{E}[Y | \text{do}(T:=A)] - \mathbb{E}[Y | \text{do}(T:=B)]\)

如何使用#

让我们生成一些处理影响明显的数据。

>>> import networkx as nx, numpy as np, pandas as pd
>>> import dowhy.gcm as gcm
>>> X0 = np.random.normal(0, 0.2, 1000)
>>> T = (X0 > 0).astype(float)
>>> X1 = np.random.normal(0, 0.2, 1000) + 1.5 * T
>>> Y = X1 + np.random.normal(0, 0.1, 1000)
>>> data = pd.DataFrame(dict(T=T, X0=X0, X1=X1, Y=Y))

这里,我们看到 \(T\) 是二元的,如果 \(T\) 是 1,则给 \(Y\) 增加 1.5,否则增加 0。像往常一样,让我们对因果关系进行建模并将其拟合到数据上

>>> causal_model = gcm.ProbabilisticCausalModel(nx.DiGraph([('X0', 'T'), ('T', 'X1'), ('X1', 'Y')]))
>>> gcm.auto.assign_causal_mechanisms(causal_model, data)
>>> gcm.fit(causal_model, data)

现在我们准备回答这个问题:“将 \(T\) 设置为 1 与设置为 0 的因果效应是什么?”

>>> gcm.average_causal_effect(causal_model,
>>>                          'Y',
>>>                          interventions_alternative={'T': lambda x: 1},
>>>                          interventions_reference={'T': lambda x: 0},
>>>                          num_samples_to_draw=1000)
1.5025054682995396

平均效应约为 1.5,这与我们的数据生成过程一致。由于该方法期望一个包含干预措施的字典,我们也可以干预多个节点和/或指定更复杂的干预措施。

注意,虽然在实践中正确指定因果图似乎很困难,但通常只需指定具有正确因果顺序的图即可。也就是说,只要没有反向因果关系,从上游节点向一个下游节点添加太多边在估计因果效应时仍然会得到合理的结果。在上面的示例中,如果我们添加边 \(X0 \rightarrow Y\)\(T \rightarrow Y\),我们将得到相同的结果。

>>> causal_model.graph.add_edge('X0', 'Y')
>>> causal_model.graph.add_edge('T', 'Y')
>>> gcm.auto.assign_causal_mechanisms(causal_model, data, override_models=True)
>>> gcm.fit(causal_model, data)
>>> gcm.average_causal_effect(causal_model,
>>>                          'Y',
>>>                          interventions_alternative={'T': lambda x: 1},
>>>                          interventions_reference={'T': lambda x: 0},
>>>                          num_samples_to_draw=1000)
1.509062353057525

为了进一步考虑未建模的根节点之间的潜在相互作用,我们也可以传入观察数据而不是生成新数据

>>> gcm.average_causal_effect(causal_model,
>>>                          'Y',
>>>                          interventions_alternative={'T': lambda x: 1},
>>>                          interventions_reference={'T': lambda x: 0},
>>>                          observed_data=data)
1.4990885925844586

理解该方法#

估计平均因果效应很简单,因为这只需要根据目标节点在各自干预分布下的样本来比较它们的两个期望。也就是说,我们可以将 ACE 估计归结为以下步骤

  1. 从处理 A 下 \(Y\) 的干预分布中抽取样本。

  2. 从处理 B 下 \(Y\) 的干预分布中抽取样本。

  3. 计算它们各自的均值。

  4. 计算均值之差。即,\(\mathbb{E}[Y | \text{do}(T:=A)] - \mathbb{E}[Y | \text{do}(T:=B)]\),其中我们不需要限制干预的类型或我们要干预的变量。