公平性约束学习:在训练中嵌入公平指标

FreeGuideOnline 最新 2026-06-14

什么是公平性约束学习

公平性约束学习(Fairness-Constrained Learning)是在模型训练过程中直接引入公平性指标作为约束条件,使模型在追求预测精度的同时满足特定的公平性要求。与事后调整或预处理方法不同,这类方法将公平性目标嵌入优化问题,通过约束或正则化项引导模型在训练时就考虑群体间的均衡。

常见的做法是将公平性度量转化为可微分的约束,然后使用约束优化、拉格朗日松弛或对抗训练等技术进行求解。最终获得的模型不仅在整体性能上表现良好,还在指定敏感属性上具备可量化的公平性保障。

为什么需要训练时嵌入公平指标

事后修正方法(如阈值调整、重加权)往往只能在特定决策点上调整,难以保证全局公平性,且可能损害模型已学习到的特征表达。预处理方法虽能改变数据分布,却无法控制模型在训练过程中可能放大偏见。

在训练时嵌入公平性约束具有以下优势:

  • 端到端学习:公平目标与预测目标同步优化,得到的特征表示自身就具备更低的歧视性。
  • 灵活性强:可以无缝结合多种公平性准则(如 demographic parity、equalized odds)作为软约束或硬约束。
  • 理论保障:约束优化框架下可以获得可证明的公平性-精度权衡的近似最优解。

核心公平性约束指标

在构建约束前,需要将公平性概念量化为可计算的指标。以下是三种最常用的群体公平性定义,以二分类问题、二值敏感属性为例。

Demographic Parity(人口均等)

要求模型预测的正类概率在不同敏感属性组间相等。形式化为:

[ P(\hat{Y}=1 | A=a) = P(\hat{Y}=1 | A=b), \quad \forall a,b ]

差值形式可作为约束:(|P(\hat{Y}=1|A=1) - P(\hat{Y}=1|A=0)| \leq \epsilon)。

Equalized Odds(均等化几率)

要求模型的真阳性率和假阳性率在各组间分别相等:

[ P(\hat{Y}=1 | Y=y, A=a) = P(\hat{Y}=1 | Y=y, A=b), \quad y\in{0,1} ]

这确保了模型在不同群体中错误类型分布一致,是比人口均等更强的条件。

Equality of Opportunity(机会均等)

是 Equalized Odds 的放松版本,仅要求真阳性率(即正类被正确预测的比例)在组间相等:

[ P(\hat{Y}=1 | Y=1, A=a) = P(\hat{Y}=1 | Y=1, A=b) ]

构建公平性约束的损失函数

将公平指标集成到训练目标中,常见方式有两类:正则化方法和约束优化方法。

正则化方法

将公平性违反度作为惩罚项加入损失函数:

[ \mathcal{L}(\theta) = \mathcal{L}{\text{acc}}(\theta) + \lambda \cdot \mathcal{L}{\text{fair}}(\theta) ]

其中 (\mathcal{L}{\text{acc}}) 为标准任务损失(如交叉熵),(\mathcal{L}{\text{fair}}) 是对公平性违反的惩罚,(\lambda) 控制公平性权重。

设计 (\mathcal{L}_{\text{fair}}) 的关键在于将其表达为可微形式。以人口均等为例,可以利用模型输出的概率与敏感属性的相关性:

def demographic_parity_loss(y_pred, sensitive_attr):
    """y_pred: 模型预测概率, sensitive_attr: 二值敏感属性"""
    group0_prob = tf.reduce_mean(y_pred[sensitive_attr == 0])
    group1_prob = tf.reduce_mean(y_pred[sensitive_attr == 1])
    return tf.abs(group0_prob - group1_prob)

这种绝对值惩罚在训练过程中直接缩小两组平均预测概率的差距。

约束优化方法

更严格的做法是将公平性视为硬约束,求解带约束的经验风险最小化:

[ \begin{aligned} \min_{\theta} \quad & \frac{1}{N}\sum_{i=1}^{N} \ell(y_i, f_\theta(x_i)) \ \text{s.t.} \quad & g(\theta) \leq \epsilon \end{aligned} ]

其中 (g(\theta)) 是公平性违反度量。使用拉格朗日松弛可将问题转化为极小极大优化:

[ \min_{\theta} \max_{\lambda \geq 0} \frac{1}{N}\sum \ell(y_i, f_\theta(x_i)) + \lambda (g(\theta) - \epsilon) ]

通过交替更新模型参数 (\theta) 和拉格朗日乘子 (\lambda),动态调整对公平性的重视程度。TensorFlow Constrained Optimization (TFCO) 库提供了这类算法的实现。

实际实现:使用 TensorFlow Constrained Optimization

下面展示如何在二分类问题中,使用 TFCO 实现带有 Demographic Parity 约束的训练。

环境准备与数据加载

import tensorflow as tf
import tensorflow_constrained_optimization as tfco
import numpy as np

# 假设已有特征 X, 标签 y, 敏感属性 sensitive_attr
dataset = tf.data.Dataset.from_tensor_slices(
    (X, y, sensitive_attr)
).batch(128)

构建公平性约束

TFCO 通过 RateMinimizationProblem 定义约束。首先需定义上下文(context),包括预测和标签、敏感属性:

context = tfco.rate_context(
    predictions=lambda: logits,
    labels=lambda: y,
    sensitive_attr=lambda: sensitive_attr
)

# 整体错误率(目标)
overall_error = tfco.error_rate(context)

# 人口均等约束:组1与组0的正预测率差值不超过 epsilon
epsilon = 0.05
positive_rate_group0 = tfco.positive_prediction_rate(context, subset_index=0)
positive_rate_group1 = tfco.positive_prediction_rate(context, subset_index=1)

constraints = [
    tfco.leq(positive_rate_group1 - positive_rate_group0, epsilon),
    tfco.leq(-(positive_rate_group1 - positive_rate_group0), epsilon)
]

这相当于要求 (|P(\hat{Y}=1|A=1) - P(\hat{Y}=1|A=0)| \leq \epsilon)。

构建优化问题并训练

problem = tfco.RateMinimizationProblem(overall_error, constraints)

# 使用拉格朗日优化器
optimizer = tfco.ProxyLagrangianOptimizerV2(
    optimizer=tf.keras.optimizers.Adam(0.01)
)

# 自定义训练循环
@tf.function
def train_step(model, X_batch, y_batch, sensitive_batch):
    with tf.GradientTape() as tape:
        logits = model(X_batch, training=True)
        # 更新 context 中的数据
        context.update(labels=y_batch, predictions=logits, 
                       sensitive_attr=sensitive_batch)
        loss = problem.compose_loss()
    grads = tape.gradient(loss, model.trainable_variables)
    optimizer.apply_gradients(zip(grads, model.trainable_variables))
    return loss

训练过程中,优化器会自动调整拉格朗日乘子,使得约束逐渐被满足。

公平性约束与模型类型的适配

线性模型

对于逻辑回归等线性模型,公平性约束可直接作用于权重。例如,通过协方差约束实现人口均等:

[ \text{Cov}(\hat{Y}, A) \approx 0 \implies \frac{1}{N}\sum_{i}(a_i - \bar{a})\cdot \sigma(w^\top x_i) \approx 0 ]

线性模型下的约束优化通常具有闭合形式更新,适合高维稀疏特征场景。

深度神经网络

深度模型中,公平性损失需要反向传播。由于公平性指标往往是基于批统计量计算,需注意大批量以降低估计方差。一种技巧是使用代理损失(proxy loss),例如用敏感属性对模型预测的互信息作为惩罚项。

处理连续敏感属性

当敏感属性是连续变量(如年龄)时,可将公平性约束修改为独立性度量。例如,采用希尔伯特-施密特独立性准则(HSIC)作为正则化项:

[ \mathcal{L}{\text{fair}} = \text{HSIC}(f\theta(X), A) ]

该度量在再生核希尔伯特空间中计算,可微且能够捕捉非线性依赖。

多粒度公平性与约束组合

一个模型可能需要同时满足多个公平性准则,或在多个重叠群体上实现公平。这种情况下,可将多个约束线性叠加:

# example: 同时要求人口均等和均等化几率
dp_constraint = ...
tpr_constraint = ...  # 真阳性率等式
fpr_constraint = ...  # 假阳性率等式

constraints = [dp_constraint, tpr_constraint, fpr_constraint]

当群体存在交叠(如性别×种族)时,可对每个子群体分别定义约束。但约束数量过多会导致优化困难,此时可引入最大值约束:要求所有子群体间最大差异不超过阈值。

评估与验证

只依赖训练时的约束值不够,必须在独立验证集上评估公平性。关键步骤:

  1. 计算实际差距:如 Demographic Parity 差值、Equalized Odds 差值。
  2. 可视化权衡:绘制 Pareto 前沿,展示在不同约束强度下精度与公平性的关系。
  3. 统计显著性:使用自助法(bootstrap)评估公平性指标的置信区间。
  4. 交叉验证:确保公平性在不同数据划分上一致。

典型实验流程:

def evaluate_fairness(model, data_loader, sensitive_attr_index):
    all_preds = []
    all_sensitive = []
    for batch in data_loader:
        preds = model(batch.x)
        all_preds.extend(preds.numpy())
        all_sensitive.extend(batch.x[:, sensitive_attr_index].numpy())
    # 计算公平性指标
    dp_gap = abs(mean_pred(group0) - mean_pred(group1))
    return dp_gap

挑战与注意事项

  • 准确性-公平性权衡:过度强调公平会损害模型性能,需根据业务场景设定合理约束容限 (\epsilon)。
  • 代理损失与真实指标的鸿沟:在不可微的公平性指标上使用凸代理可能导致过于保守或无效的约束,应监控真实指标。
  • 批处理噪声:基于小批量估计的公平性约束方差大,可能收敛不稳定,可使用指数移动平均或历史统计量修正。
  • 概念漂移:部署后数据分布变化会破坏训练时达成的公平性,需构建持续监控和重训练机制。
  • 因果公平性:上述关联性约束无法捕捉真正因果关系带来的不公平,如欲消除因果路径上的歧视,需要借助结构因果模型和反事实公平性约束。

总结

公平性约束学习通过将公平指标直接注入训练目标,成为构建负责任的机器学习系统的重要手段。无论是简单的线性正则化还是拉格朗日约束优化,开发者均可根据具体场景选择合适的策略。实践中应关注指标选择、约束松弛度、优化稳定性以及部署后的持续验证,才能真正实现模型性能与公平性的有效平衡。