概述

因果推断(Causal Inference)是研究因果关系与因果效应的学科,是数据科学和人工智能的核心支柱之一。与传统的统计学关注相关性不同,因果推断致力于回答”如果我干预X,Y会怎样”这类反事实问题。1


相关性 ≠ 因果性

经典案例:冰淇淋与溺水

统计数据显示,冰淇淋销量与溺水死亡人数呈高度正相关。但这并不意味着”吃冰淇淋导致溺水”。

真正的原因: 两者都与第三个变量——气温——相关。夏天温度高 → 冰淇淋销量增加,同时游泳人数增加 → 溺水事故增多。

冰淇淋销量 ──┐
             ├──→ 表面相关性(虚假关联)
溺水人数 ───┘

     ↑
   气温(共同原因)

辛普森悖论(Simpson’s Paradox)

当数据被分组汇总与分层汇总得出相反结论时,就出现辛普森悖论。

示例:某药物治疗效果

性别药物治疗组(康复/总数)对照组(康复/总数)
男性80/100 (80%)70/100 (70%)
女性30/100 (30%)10/50 (20%)
合计110/200 (55%)80/150 (53.3%)
  • 分性别分析:药物对男性和女性都有正向效果
  • 合并分析:药物似乎略微有害

原因: 存在混杂变量(性别),影响治疗分配(可能女性更多被分配到治疗组)与结果。


Pearl 因果层级

Judea Pearl提出的因果层级(Causal Hierarchy)揭示了不同类型问题的认知难度:2

层级名称问题形式示例
L1关联(Association)看到闪电后,预计会听到雷声?
L2干预(Intervention)强制降雨后,农作物产量?
L3反事实(Counterfactual)如果我做了X,Y会是多少?

层级间的蕴含关系

L3 反事实 ⊃ L2 干预 ⊃ L1 关联
  • L1问题可以从观测数据直接回答
  • L2问题需要实验因果假设才能回答
  • L3问题需要反事实推理,最难回答

重要结论: 因果推断的核心挑战在于跨越层级——从观测数据推断干预效果。


因果图模型

定义

因果图(Causal Diagram)是一个有向无环图(DAG),其中:

  • 节点:变量
  • 有向边):X对Y有因果影响

结构因果模型(Structural Causal Model, SCM)

其中 是X的父节点集合, 是独立的外生噪声。

# 示例:简单SCM
# X := ε_X  (X无父节点)
# Y := 2X + ε_Y  (Y由X和噪声决定)
 
import numpy as np
 
def structural_causal_model(n_samples):
    eps_x = np.random.randn(n_samples)
    eps_y = np.random.randn(n_samples)
    
    X = eps_x  # X是外生的
    Y = 2 * X + eps_y  # Y受X影响
    
    return X, Y
 
X, Y = structural_causal_model(1000)
print(f"X与Y的相关性: {np.corrcoef(X, Y)[0,1]:.3f}")  # ≈ 0.9

基本结构

结构图形因果含义
链式X通过Z影响Y
叉式Z是X和Y的共同原因
对撞Z是X和Y的对撞节点

混杂因素与后门路径

混杂(Confounding)

混杂因素(Confounder)是同时影响处理变量X和结果变量Y的变量Z。混杂会引入虚假关联(Spurious Correlation),混淆X对Y的因果效应。

混杂结构:
    Z
   ↙ ↘
  X   Y

Z → X(混杂因素影响处理)
Z → Y(混杂因素影响结果)

后门路径(Backdoor Path)

从X到Y的路径中,如果存在以←结尾的箭头,则该路径是后门路径,会引入虚假关联。

阻断后门路径的条件:

  • 后门路径上存在非对撞节点的变量,且该变量被控制

后门调整公式

当后门路径被阻断时,因果效应可识别为:

这称为** Adjustment Formula**(调整公式)。

import numpy as np
 
def backdoor_adjustment(df, X, Y, Z):
    """
    使用后门调整估计P(Y|do(X))
    
    参数:
        df: DataFrame包含X, Y, Z
        X: 处理变量名
        Y: 结果变量名
        Z: 混杂变量名
    """
    effect = 0
    for z_val in df[Z].unique():
        # 分层加权
        p_z = (df[Z] == z_val).mean()
        p_y_given_xz = df[df[X]==1 & df[Z]==z_val][Y].mean()
        effect += p_y_given_xz * p_z
    return effect

潜在结果框架

Rubin因果模型

潜在结果框架(Potential Outcomes Framework)由Rubin提出,是因果推断的另一个核心框架。

核心概念:

符号含义
单位接受处理时的潜在结果
单位未接受处理时的潜在结果
观测到的结果

因果效应定义:

根本问题(Fundamental Problem of Causal Inference):

  • 每个单位只能观测到一个潜在结果
  • 另一个潜在结果永远是未知的

观测数据下的识别假设

假设公式含义
一致性处理与结果一一对应
** positivity**所有单位都有被处理的可能
可忽略性给定协变量后,处理分配与潜在结果独立

当可忽略性成立时:


因果效应估计方法

1. 分层分析(Stratification)

按混杂变量分层,控制层内比较:

2. 匹配(Matching)

为每个处理组单位找到特征相似的对照组单位:

from sklearn.neighbors import NearestNeighbors
import numpy as np
 
def propensity_score_matching(df, treatment, outcome, covariates):
    """
    基于倾向性评分的匹配估计
    
    倾向性评分 e(X) = P(T=1|X)
    """
    # 计算倾向性评分
    from sklearn.linear_model import LogisticRegression
    model = LogisticRegression()
    model.fit(df[covariates], df[treatment])
    ps = model.predict_proba(df[covariates])[:, 1]
    
    # 匹配
    treated_ps = ps[df[treatment] == 1]
    control_ps = ps[df[treatment] == 0]
    
    nn = NearestNeighbors(n_neighbors=1)
    nn.fit(control_ps.reshape(-1, 1))
    distances, indices = nn.kneighbors(treated_ps.reshape(-1, 1))
    
    # 计算ATT (Average Treatment effect on the Treated)
    treated_outcomes = df[df[treatment]==1][outcome].values
    matched_control_outcomes = df[df[treatment]==0][outcome].values[indices.flatten()]
    
    att = np.mean(treated_outcomes - matched_control_outcomes)
    return att

3. 工具变量(Instrumental Variable)

当存在无法控制的混杂时,使用工具变量Z:

工具变量三条件:

  1. (相关性)
  2. (排他性约束)
  3. 对Y的影响仅通过X(无直接路径)
   Z
   ↓
   X → Y
   ↑
  混杂

两阶段最小二乘法(2SLS):

def instrumental_variable(Y, T, Z, X_covariates=None):
    """
    工具变量估计
    
    第一阶段: X̂ = α + βZ
    第二阶段: Ŷ = γ + δX̂
    """
    from sklearn.linear_model import LinearRegression
    
    # 第一阶段
    lr1 = LinearRegression()
    if X_covariates is not None:
        Z_aug = np.column_stack([Z, X_covariates])
    else:
        Z_aug = Z.reshape(-1, 1)
    lr1.fit(Z_aug, T)
    T_hat = lr1.predict(Z_aug)
    
    # 第二阶段
    lr2 = LinearRegression()
    if X_covariates is not None:
        X_aug = np.column_stack([T_hat, X_covariates])
    else:
        X_aug = T_hat.reshape(-1, 1)
    lr2.fit(X_aug, Y)
    
    return lr2.coef_[0]  # 因果效应估计

与概率图模型的联系

因果图与贝叶斯网络有密切关系,但有关键区别:

方面贝叶斯网络因果图
表示条件概率关系表示因果关系
方向可任意指定具有语义含义
推断后验概率因果效应
可交换性有(干预后分布改变)

参见 贝叶斯网络马尔可夫网络与CRF


参考资料


相关词条:Do-Calculus与因果效应识别因果发现贝叶斯网络

Footnotes

  1. Pearl, J. “Causality: Models, Reasoning, and Inference” (2nd ed.). Cambridge University Press, 2009.

  2. Pearl, J. “Theoretical Impediments to Machine Learning with Seven Sparks from the Causal Revolution.” arXiv:1801.04016, 2018.