重新加权:通过调整样本权重实现公平性提升
重新加权减轻偏见:用样本权重实现公平机器学习
为什么需要关注模型偏见
机器学习模型从历史数据中学习,但数据往往反映了社会中的不平等与刻板印象。当模型不加甄别地学习这些模式时,可能会在放贷、招聘、司法等决策中系统性歧视某些群体。算法公平性的目标就是识别并缓解这类不公正结果。
最常见的公平性改进思路之一,就是重新加权(Reweighting)。它不改变模型结构,也不修改特征标签,仅通过调整每个训练样本的权重,让模型在优化时更关注弱势群体或被偏见影响的样本,从而在损失函数层面实现公平性提升。
重新加权的直观理解
想象一个二分类问题:预测贷款申请是否获批。数据中男性获批的比例远高于女性,这可能是历史偏见导致的。普通逻辑回归会最小化整体误差,导致决策边界向多数类别倾斜,女性更难被批准。
重新加权的方法相当于给每个样本一个“重要性分数”。我们可以:
- 提高女性少数样本的权重,让模型更“在乎”这些样本,不敢轻易预测错;
- 降低男性多数样本的权重,减少其对损失的主导影响。
这样,优化目标就从纯粹的最小化总误差,变为最小化加权误差,模型决策边界会被迫向更公平的方向调整。
用权重表达公平目标
基础设定
设有数据集 ( D = {(x_i, y_i, a_i)}_{i=1}^N ),其中 ( a_i ) 是敏感属性(如性别、种族),( y_i ) 是目标标签,( x_i ) 是特征。
传统经验风险最小化(ERM)的目标是: [ \min_{\theta} \frac{1}{N} \sum_{i=1}^{N} L(h_\theta(x_i), y_i) ] 其中 ( L ) 为损失函数。
重新加权则引入样本权重 ( w_i ),目标变为: [ \min_{\theta} \frac{1}{\sum w_i} \sum_{i=1}^{N} w_i \cdot L(h_\theta(x_i), y_i) ] 权重 ( w_i ) 的设计直接决定了模型追求的公平性方向。
常见权重设计方案
1. 基于群体的统计平等加权
若希望模型满足人口统计平等(Demographic Parity),即预测结果 ( \hat{Y} ) 与敏感属性 ( A ) 独立,一种简单方法是为每个 ( (A=a, Y=y) ) 组合设置权重,使其在加权分布中比例均匀。
具体公式(来自经典的 Equalized Odds 或预处理方法): [ w_i = \frac{P(Y=y) \cdot P(A=a)}{P(Y=y, A=a)} ] 这里 ( P(\cdot) ) 根据训练集统计。该权重会放大稀少组合的样本,缩小常见组合的样本,使得加权后 ( Y ) 与 ( A ) 近似独立。
2. 为均衡错误率而设计的权重
如果目标是均等化几率(Equalized Odds),即各群体的假阳性率(FPR)和假阴性率(FNR)相等,可以在训练中迭代调整权重,加大对当前错误率较高群体的惩罚。一种启发式方法是:
- 每训练固定轮次,评估每个 ( (a, y) ) 分组的错误率;
- 提高错误率较高的分组的权重,降低错误率较低的分组的权重;
- 用更新后的权重继续训练。
这种方法不要求权重有封闭形式,而是通过动态调整引导模型减少群组间错误率差异。
3. 反事实公平的权重
在某些场景中,我们希望模型对于仅敏感属性不同的样本输出相同预测。可以构建成对的正反事实样本(例如通过属性翻转),并对这类成对样本施加一致性损失,权重则控制公平性约束的强度。
实操方法:重新加权减轻偏见的步骤
步骤一:探索数据中的偏见
在应用权重之前,先计算敏感属性各子群体在标签分布上的差异。例如:
- 群体
A=0的正例比例:0.30 - 群体
A=1的正例比例:0.15
这种差异可能反映历史偏见,后续重新加权将尝试缓解它。
步骤二:计算样本权重
选择公平性目标,例如要求 ( \hat{Y} ) 与 ( A ) 的关联降低。一种常用预处理权重计算方法:
import pandas as pd
def compute_weights(df, sensitive_attr, target):
# 计算联合概率与边缘概率
joint = df.groupby([sensitive_attr, target]).size() / len(df)
margin_y = df[target].value_counts(normalize=True)
margin_a = df[sensitive_attr].value_counts(normalize=True)
weights = {}
for (a, y), p_joint in joint.items():
p_margin = margin_y[y] * margin_a[a]
weights[(a, y)] = p_margin / p_joint
# 映射回每一行
df['weight'] = df.apply(lambda row: weights[(row[sensitive_attr], row[target])], axis=1)
return df
这个代码片段实现了使 ( Y ) 与 ( A ) 独立化的权重:在加权分布中,( P(A=a, Y=y) = P(A=a)P(Y=y) )。
步骤三:用加权损失训练模型
多数机器学习框架支持样本权重。以 scikit-learn 为例:
from sklearn.linear_model import LogisticRegression
model = LogisticRegression()
model.fit(X_train, y_train, sample_weight=train_weights)
以 PyTorch 为例:
loss_fn = torch.nn.BCEWithLogitsLoss(reduction='none')
def weighted_loss(outputs, targets, weights):
loss = loss_fn(outputs, targets)
weighted_loss = (loss * weights).mean()
return weighted_loss
训练时,每个批次将对应的权重传递进损失计算。
步骤四:评估公平性与效用权衡
重新加权通常会在准确度和公平性之间引入权衡。需同时追踪:
- 整体性能指标:准确率、AUC等。
- 群组公平性指标:人口统计平等差异、均等化几率差异等。
建议在验证集上进行网格搜索,尝试不同的权重尺度(例如将计算出的权重进行指数缩放 ( w_i^\alpha )),找到可接受的权衡点。
重新加权方法的优势与局限
优势
- 模型无关:可与任何接受样本权重的模型配合,包括逻辑回归、决策树、梯度提升树、神经网络等。
- 实现简单:常作为数据预处理的一步,无需修改模型训练代码。
- 可解释性强:权重大小直接反映了样本对公平性目标的贡献程度。
局限
- 仅能缓解训练数据内偏见:如果历史数据中某些群体的信息本身就稀缺或缺失,重新加权可能无法弥补。
- 无法处理未知偏见:需要预先定义敏感属性和公平性目标。
- 可能放大噪声:极高权重赋予少数极端样本,可能导致模型过拟合这些样本,泛化能力下降。此时可结合权重裁剪(clipping)或平滑技术。
- 公平性指标间的冲突:为一个人口统计平等设计的权重,可能恶化均等化几率,需要根据应用场景选择合适的指标。
进阶变体与替代方案
动态重新加权(Adaptive Reweighting)
训练过程中周期性评估各子群的损失或错误率,动态更新权重。例如,在每个 epoch 结束时按照当前模型对各群体的错误率比例重新分配权重,使模型持续平衡各群体的表现。
结合正则化的加权
在损失函数中加入公平性正则项,并将该正则化与样本权重联合优化。例如,使用对抗训练去除敏感信息的同时,为易受对抗攻击的样本分配更高权重,加速公平特征学习。
后处理方法补充
重新加权属于预处理(或训练中)方法,如果模型已训练完成,可考虑后处理技术(如阈值调整)直接修改决策边界以达到公平,但它们与重新加权可组合使用。
实践建议
- 从小权重开始实验:过度加权可能使模型丧失有用模式。建议初始使用理论公式计算出的权重,再通过缩放因子(如 0.5~2.0)进行调优。
- 监控训练曲线:确保加权后训练损失稳定下降,若出现剧烈震荡,可适当降低学习率或对权重做平滑。
- 在公平性与性能间寻求业务平衡:与利益相关方讨论可接受的公平性指标阈值,例如人口统计平等差异不超过0.05,同时准确率下降不超过2%。
- 交叉验证按群体分层:确保验证集和测试集中各群体比例合理,避免评估偏差。
重新加权是通往公平机器学习最直接的桥梁之一。理解其原理后,你可以用几行代码为模型注入公平性考量,并为更复杂的公平性干预打下坚实基础。