因果公平性理论基础

1. 引言

因果公平性(Causal Fairness)使用因果推断工具来建模和解决算法歧视问题。与传统统计公平性方法不同,因果方法可以区分”可接受的差异”(由真实因果关系导致)和”不可接受的歧视”(由偏见路径导致)。1

1.1 为什么需要因果公平性

传统公平性方法存在以下局限:

方法局限
Fairness Through Unawareness忽略敏感属性,但可能包含歧视信息的代理变量
Demographic Parity可能拒绝有用的预测信息
Equalized Odds无法解释差异的来源

因果公平性可以:

  • 回答”为什么”产生差异
  • 区分直接歧视和间接歧视
  • 指导具体的干预行动

1.2 因果公平性框架

因果公平性问题:

敏感属性 A (种族、性别等)
       ↓
   ┌───┴───┐
   ↓       ↓
  公平路径   不公平路径
  (X→Y)    (A→X→Y)
   ↓       ↓
   Y       Y
   ↓       ↓
结果差异 = 可接受差异 + 歧视性差异

2. 反事实公平性

2.1 基础定义

反事实公平性(Counterfactual Fairness,Kusner et al., 2017)2

定义:当且仅当对于每个个体 ,预测值在反事实世界(敏感属性改变)和现实世界中相同,则预测器是反事实公平的。

形式化表达:

其中:

  • 是敏感属性
  • 是原始值
  • 是反事实值
  • 表示在将 干预为 的反事实世界中的预测

2.2 三步推理框架

反事实公平性的计算遵循 Pearl 的因果推理框架:

反事实推理三步:

1. 溯因(Abduction)
   P(U | W=w)  ← 根据观测数据推断背景变量
   
2. 行动(Action)
   P(Y_{A←a} | W=w)  ← 用干预替换敏感属性
   
3. 预测(Prediction)
   E[Y_{A←a} | W=w]  ← 计算反事实结果期望

数学形式化

给定因果模型 和观测数据

2.3 反事实公平性的因果图表示

反事实公平性因果图:

           A (敏感属性)
          ↙    ↓    ↘
         ↓     ↓     ↓
         X₁   X₂    X₃ (中介变量)
          ↘    ↓    ↙
            Y (结果)
             ↓
             U (未观测混杂)

反事实公平性条件

对于任何反事实 ,满足:

这意味着 不能依赖于通过任何从 的路径传递的信息。


3. 路径特定反事实公平性

3.1 问题的提出

敏感属性可能同时通过”公平”和”不公平”路径影响决策:

多路径因果图:

              A (敏感属性)
            ↙    ↓    ↘
           ↓     ↓     ↓
        公平   中介   历史
        路径   路径   路径
           ↓     ↓     ↓
            ↘    ↓    ↙
                 Y

问题:如果完全阻断所有路径,可能损失有用的预测信息。

3.2 路径特定公平性

路径特定反事实公平性(Chiappa, 2019)3

核心思想:忽略沿”不公平”路径的影响,保留沿”公平”路径的信息。

定义:对于给定的路径集 ,如果:

则预测器满足路径 上的反事实公平性。

3.3 公平路径的定义

路径类型示例是否公平
直接路径通常不公平
历史歧视不公平
真实能力差异是真实能力)可能公平
中介歧视是历史偏见的结果)不公平

3.4 应用示例:信贷决策

信贷决策因果图:

        种族/性别 (A)
            ↓
    ┌───────┼───────┐
    ↓       ↓       ↓
历史歧视  教育   真实信用
  (X₁)    (X₂)    (X₃)
    ↓       ↓       ↓
    └───┬───┴───────┘
            ↓
        信用评分 (Y)

公平性分析

  • 路径 不公平(历史歧视)
  • 路径 可能公平(真实信用差异)
  • 路径 视情况而定

4. PC-Fairness统一框架

4.1 框架概述

PC-Fairness(Wu et al., NeurIPS 2019)4

目标:统一各种因果公平性度量,解决可识别性问题。

核心贡献

  • 形式化定义各种因果公平性度量
  • 分析其可识别性条件
  • 提供统一的计算框架

4.2 公平性度量的因果形式化

度量因果定义可识别性
反事实公平性需完全因果模型
路径特定公平性部分可识别
平均因果效应公平性$E[Y_{A\leftarrow 1}] - E[Y_{A\leftarrow 0}]

4.3 可识别性条件

可识别性定理

因果公平性度量 在以下条件下可识别:

  1. 后门路径阻塞:存在足够的调整集
  2. 前门路径:使用前门准则
  3. 工具变量:使用工具变量法
class PCFairnessFramework:
    def __init__(self, causal_graph):
        self.graph = causal_graph
        
    def check_identifiability(self, fairness_metric, path_set=None):
        """检查公平性度量的可识别性"""
        if fairness_metric == 'counterfactual':
            return self._identify_counterfactual_fairness()
        elif fairness_metric == 'path_specific':
            return self._identify_path_specific(path_set)
        elif fairness_metric == 'ace_fairness':
            return self._identify_ace_fairness()
    
    def _identify_counterfactual_fairness(self):
        """反事实公平性的可识别性"""
        # 需要完整的因果模型
        return self.graph.has_no_unobserved_confounders()
    
    def _identify_path_specific(self, path_set):
        """路径特定公平性的可识别性"""
        # 需要满足特定的可识别性条件
        return self._check_genealogy_condition(path_set)

5. 因果公平性的统计度量

5.1 条件平均因果效应(CACE)

定义:在特定条件下处理组的平均因果效应

5.2 公平性差异度量

度量公式含义
总体差异$E[YA=1] - E[Y
因果差异因果效应差异
间接歧视沿不公平路径的因果效应历史偏见
直接歧视沿直接路径的因果效应即时偏见

5.3 分解分析

class CausalFairnessDecomposition:
    def decompose(self, graph, treatment, outcome, covariates):
        """
        将观测差异分解为因果和非因果成分
        
        Total Disparity = Direct Effect + Indirect Effect + Confounding
        """
        # 总差异
        total = self._total_disparity(outcome, treatment)
        
        # 直接因果效应(总直接效应)
        direct_effect = self._direct_effect(
            graph, treatment, outcome
        )
        
        # 间接效应(通过中介)
        indirect_effect = self._indirect_effect(
            graph, treatment, outcome, covariates
        )
        
        # 混杂效应
        confounding = total - direct_effect - indirect_effect
        
        return {
            'total': total,
            'direct': direct_effect,
            'indirect': indirect_effect,
            'confounding': confounding
        }

6. 因果公平性的因果图建模

6.1 公平性因果图的构建

class FairnessCausalGraph:
    """
    构建公平性分析的因果图
    
    节点类型:
    - A: 敏感属性(种族、性别等)
    - C: 合法的协变量
    - M: 中介变量
    - U: 未观测混杂
    - Y: 决策/结果
    """
    
    def build_graph(self, scenario='employment'):
        if scenario == 'employment':
            # 就业决策场景
            nodes = {
                'A': 'race/gender',  # 敏感属性
                'C': 'education',     # 合法因素
                'M': 'job_history',  # 中介(历史偏见)
                'U': 'unobserved',   # 未观测混杂
                'Y': 'hired'        # 决策
            }
            
            edges = [
                ('A', 'M'),   # 历史偏见
                ('A', 'C'),   # 教育机会不平等
                ('C', 'M'),   # 经验影响历史
                ('C', 'Y'),   # 合法因素
                ('M', 'Y'),   # 历史影响决策
                ('U', 'C'),   # 混杂
                ('U', 'Y')    # 混杂
            ]
        elif scenario == 'lending':
            # 信贷决策场景
            # ...
        
        return nodes, edges

6.2 混杂控制策略

策略方法适用场景
后门调整$P(Ydo(A), X) = \sum_x P(Y
前门调整估计直接因果效应无法观测混杂
工具变量两阶段最小二乘存在工具变量

6.3 反事实计算

class CounterfactualFairnessCalculator:
    def compute_fairness(self, model, individual_data, sensitive_attr, 
                         counterfactual_value):
        """
        计算单个个体的反事实公平性
        
        Steps:
        1. Abduction: P(U | W=w)
        2. Action: do(A = a')
        3. Prediction: E[Y_{A←a'}]
        """
        # Step 1: 溯因
        posterior = self._compute_posterior(individual_data)
        
        # Step 2: 行动(干预)
        intervened_data = individual_data.copy()
        intervened_data[sensitive_attr] = counterfactual_value
        
        # Step 3: 预测
        factual_pred = model.predict([individual_data])
        counterfactual_pred = model.predict([intervened_data])
        
        return {
            'factual': factual_pred,
            'counterfactual': counterfactual_pred,
            'fairness_violation': abs(factual_pred - counterfactual_pred)
        }

7. 因果公平性算法

7.1 FairWalk算法

FairWalk(Rahman et al., 2019):

思想:在图嵌入中引入公平性约束

class FairWalk:
    def fit(self, graph, sensitive_attr, embedding_dim=64):
        """
        FairWalk: 公平的图嵌入
        """
        # Step 1: 修改随机游走概率
        def fair_walk_probability(node, neighbor, sensitive_attr):
            base_prob = 1 / graph.degree(node)
            
            # 公平性调整:减少组间差异
            if graph.node[neighbor][sensitive_attr] != \
               graph.node[node][sensitive_attr]:
                return base_prob * fairness_penalty
            
            return base_prob
        
        # Step 2: 生成公平随机游走
        walks = self._generate_fair_walks(
            graph, 
            walk_prob=fair_walk_probability
        )
        
        # Step 3: Skip-gram训练
        embeddings = self._train_embeddings(walks, embedding_dim)
        
        return embeddings

7.2 对抗去偏见

class AdversarialFairness:
    """
    对抗学习实现因果公平性
    """
    def __init__(self, predictor, adversary, lambda_fair=1.0):
        self.predictor = predictor
        self.adversary = adversary
        self.lambda_fair = lambda_fair
    
    def fit(self, X, Y, A):
        """
        训练目标:
        min_θ max_φ L_pred(Y, Ŷ) - λ L_adversary(A, Â) + λ_fair L_fair
        """
        for epoch in range(n_epochs):
            # 更新预测器
            Y_pred = self.predictor(X)
            adv_pred = self.adversary(Y_pred.detach())
            
            pred_loss = self.criterion(Y, Y_pred)
            adv_loss = self.adversary.criterion(A, adv_pred)
            fair_loss = self._causal_fairness_loss(X, Y_pred, A)
            
            pred_loss_total = pred_loss + \
                             self.lambda_adv * adv_loss + \
                             self.lambda_fair * fair_loss
            
            pred_loss_total.backward()
            
            # 更新对抗器
            self.adversary.zero_grad()
            adv_pred = self.adversary(Y_pred.detach())
            adv_loss = self.adversary.criterion(A, adv_pred)
            (-adv_loss).backward()
    
    def _causal_fairness_loss(self, X, Y_pred, A):
        """
        因果公平性损失
        鼓励预测器不依赖于敏感属性
        """
        # 使用因果干预近似
        Y_pred_0 = self.predictor(self._intervene(X, A, value=0))
        Y_pred_1 = self.predictor(self._intervene(X, A, value=1))
        
        # 反事实公平性损失
        return torch.mean((Y_pred_0 - Y_pred_1) ** 2)

7.3 因果感知正则化

class CausalFairnessRegularizer:
    """
    因果公平性正则化器
    """
    def __init__(self, causal_graph, path_set):
        self.graph = causal_graph
        self.path_set = path_set  # 不公平路径集
    
    def fairness_loss(self, X, Y_pred, A):
        """
        计算因果公平性正则化损失
        
        L_fair = ||Y - E[Y_A]||²
        其中 E[Y_A] 是沿公平路径的期望预测
        """
        # 估计反事实结果
        Y_counterfactual = self._estimate_counterfactual(X, A)
        
        # 只考虑沿公平路径的影响
        Y_fair = self._project_to_fair_paths(Y_counterfactual)
        
        return torch.mean((Y_pred - Y_fair) ** 2)
    
    def _estimate_counterfactual(self, X, A):
        """使用因果模型估计反事实"""
        # ...
        pass
    
    def _project_to_fair_paths(self, Y_cf):
        """投影到公平路径"""
        # ...
        pass

8. 因果公平性与传统公平性的联系

8.1 与统计公平性的关系

统计公平性因果对应联系
Demographic Parity反事实版本的DP
Equalized Odds$P(Y=1A=0, Y^*=1) = P(Y=1
** Predictive Parity**$P(Y^*=1A=0, Y=1) = P(Y^*=1

8.2 理论联系

定理(Anthis & Veitch, 2024)5

满足反事实公平性的预测器自动满足Demographic Parity(在一定条件下)。

证明思路

(反事实公平),则


9. 工具与实现

9.1 CausalFairness库

Amazon Science CausalFairnessInAction6

# 安装
# pip install causal-fairness-in-action
 
from causal_fairness import CounterfactualFairness, PathSpecificFairness
from causal_fairness.datasets import load_adult
 
# 加载数据
data = load_adult()
 
# 创建因果图
graph = CounterfactualFairness.create_default_graph()
 
# 计算反事实公平性
cf_fairness = CounterfactualFairness(graph)
fairness_score = cf_fairness.evaluate(data, treatment='sex', outcome='income')
 
print(f"Counterfactual Fairness Score: {fairness_score}")
 
# 路径特定公平性
ps_fairness = PathSpecificFairness(
    graph, 
    unfair_paths=['sex -> education -> occupation -> income']
)
ps_score = ps_fairness.evaluate(data)
 
print(f"Path-Specific Fairness Score: {ps_score}")

9.2 DoWhy集成

import dowhy
from dowhy.causal_identifier import auto_identify_effect
 
# 定义因果图
model = dowhy.CausalModel(
    data=data,
    treatment='sex',
    outcome='income',
    common_causes=['education', 'occupation', 'hours_per_week'],
    graph="""
    digraph {
        sex -> education;
        sex -> income;
        education -> occupation;
        education -> income;
        occupation -> income;
    }
    """
)
 
# 识别因果效应
identified_estimand = model.identify_effect()
 
# 估计因果效应(公平性调整后)
estimate = model.estimate_effect(
    identified_estimand,
    method_name="backdoor.linear_regression"
)
 
print(f"Causal Effect (Sex -> Income): {estimate.value}")

9.3 Fairlearn集成

from fairlearn.datasets import fetch_adult
from fairlearn.reductions import ExponentiatedGradient, DemographicParity
 
# 获取数据
data = fetch_adult()
 
# 定义公平性约束
constraint = DemographicParity()
mitigator = ExponentiatedGradient(
    estimator=model,
    constraints=constraint
)
 
# 训练公平模型
mitigator.fit(X_train, y_train, sensitive_features=A_train)
 
# 评估
fair_predictions = mitigator.predict(X_test)

10. 实践指南

10.1 实施检查清单

fairness_implementation_checklist = """
因果公平性实施检查清单:
 
□ 因果图构建
  □ 识别敏感属性 A
  □ 识别相关变量 X
  □ 定义结果 Y
  □ 假设未观测混杂 U
  □ 标注公平/不公平路径
 
□ 可识别性分析
  □ 检查后门路径
  □ 评估可识别性条件
  □ 选择适当的估计方法
 
□ 公平性评估
  □ 计算反事实公平性得分
  □ 计算路径特定公平性
  □ 对比不同方法的结果
 
□ 公平性优化
  □ 选择公平性-准确性权衡点
  □ 实施公平性干预
  □ 验证干预效果

10.2 注意事项

  1. 因果假设的重要性:因果公平性的有效性依赖于因果图假设的正确性
  2. 可识别性限制:某些公平性度量可能从观测数据中无法识别
  3. 公平-准确权衡:更强的公平性约束可能导致准确率下降
  4. 组内公平性:关注组内差异而非仅关注组间差异

11. 参考文献


相关主题

Footnotes

  1. Kilbertus, N., et al. (2020). Avoiding Discrimination through Causal Reasoning. JMLR.

  2. Kusner, M., et al. (2017). Counterfactual Fairness. NeurIPS.

  3. Chiappa, S. (2019). Path-Specific Counterfactual Fairing. AAAI.

  4. Wu, Y., et al. (2019). PC-Fairness: A Unified Framework. NeurIPS.

  5. Anthis, J. R., & Veitch, V. (2024). Causal Context Connects Counterfactual Fairness to Robust Prediction and Group Fairness.

  6. Amazon Science. (2025). CausalFairnessInAction. NeurIPS 2025.