「算法偏见」常被讲成一个道德话题,但它本质上是个统计与优化问题。模型只是在最小化你给的损失函数;如果训练分布有偏、目标定义有偏、评测口径有偏,模型会忠实地把偏见学下来甚至放大。本文从数据、目标、评测三条线拆解偏见从哪来,以及工程上能怎么缓解——包括一个绕不开的硬事实:常见的公平性指标之间在数学上无法同时满足。

直觉:模型是损失函数的镜子

监督学习做的事是 minθE(x,y)D[L(fθ(x),y)]\min_\theta \; \mathbb{E}_{(x,y)\sim \mathcal{D}}[\,L(f_\theta(x), y)\,]。这里藏着三个偏见入口:

  1. D\mathcal{D}(数据分布) 本身就偏;
  2. yy(标签) 是人打的或从历史结果挖的,历史本身有偏;
  3. LL(损失) 只优化平均误差,不关心误差在不同群体上的分布。

模型对这三者照单全收。所以「去偏」不是给模型加道德约束,而是修正数据、重定义目标、重设评测。

来源一:数据

采样偏差与表征不足

如果某群体在训练集中样本稀少,模型在该群体上的误差通常更大——这不是模型「歧视」,而是它在低数据区域泛化差。设群体 gg 的样本占比 πg\pi_g,经验风险被各群体按占比加权:

R^(θ)=gπgExg[L]\hat{R}(\theta) = \sum_g \pi_g \, \mathbb{E}_{x|g}[L]

占比小的群体对总损失贡献小,优化过程自然「不太在乎」它。结果就是少数群体性能系统性偏低。

标签偏差

更隐蔽。标签 yy 往往是历史决策的产物:用「历史是否被录用」当作「是否胜任」的标签,等于把过去招聘中的人为偏好编码进了真值。模型学得越好,越精准地复刻历史歧视。

代理变量(proxy)

即使删掉敏感属性(性别、种族),模型仍能从相关特征里重建它——邮编 → 种族,购物时段 → 性别。「假装看不见」(fairness through unawareness)几乎总是失败的,因为高维特征空间里到处是代理。

来源二:目标

很多偏见来自目标被定义得过于狭窄。推荐系统优化点击率,就会放大「煽动性内容更易被点」的反馈回路;信贷模型优化整体违约率,可能以牺牲某群体的可得性为代价。这里还有一个动态放大效应:模型的输出会改变未来的数据分布(你只看到被批准者的还款情况,被拒者无标签),形成反馈回路,偏见随时间自我强化。

来源三:评测——以及一个不可能定理

最容易被跳过、却最关键的是评测口径。光看整体 accuracy 会掩盖群体差异,必须做分组评估(disaggregated evaluation)。常见的群体公平性指标有:

  • 人口均等(Demographic Parity):各群体被判为正例的比率相同,P(Y^=1G=a)=P(Y^=1G=b)P(\hat{Y}{=}1 \mid G{=}a) = P(\hat{Y}{=}1 \mid G{=}b)
  • 机会均等(Equal Opportunity):各群体真正例率(TPR)相同。
  • 预测均等(Predictive Parity / 校准):给定预测分数,各群体的真实正例概率一致。

关键事实:当各群体的真实基率不同时,校准、机会均等、人口均等这几类指标在数学上无法同时成立(除非达到完美分类,现实不可能)。这是一个已被证明的不可能结论,不是工程没做好。它的含义是:

公平不是一个能「全对」的技术目标,而是必须先做价值判断——你的场景更怕假阳还是假阴?决定了你优先保哪个指标。

举个直觉化的算术:若两群体基率不同,要让分数在两群体都校准良好,就不可能同时让两群体的假阳率相等。鱼与熊掌的取舍是结构性的。

缓解:三个阶段的干预

1
2
3
4
5
6
7
8
9
10
11
# 评测先行:任何缓解之前,先把分组指标量起来
def group_metrics(y_true, y_pred, group):
out = {}
for g in set(group):
m = [i for i in range(len(group)) if group[i] == g]
tp = sum(y_true[i] and y_pred[i] for i in m)
fp = sum((not y_true[i]) and y_pred[i] for i in m)
pos = sum(y_true[i] for i in m)
neg = sum(not y_true[i] for i in m)
out[g] = {"TPR": tp / max(pos, 1), "FPR": fp / max(neg, 1)}
return out # 看各组 TPR/FPR 差距,而不是只看总 accuracy

干预可作用在三个阶段:

  • 预处理(pre-processing):重采样/重加权让群体表征更均衡,清洗有偏标签。改的是 D\mathcal{D}
  • 训练中(in-processing):在损失里加公平性约束/正则项,例如惩罚群体间 TPR 差异:Ltotal=Ltask+λTPRaTPRbL_{total} = L_{task} + \lambda \cdot |\text{TPR}_a - \text{TPR}_b|。改的是 LL
  • 后处理(post-processing):对不同群体设不同决策阈值,使某个公平指标对齐。改的是决策规则。

各有代价:预处理简单但可能丢信息;in-processing 直接但调 λ\lambda 需在精度与公平间权衡(通常存在帕累托前沿,鱼与熊掌);后处理灵活但需要在部署时知道群体属性,可能引出合规问题。

工程权衡与常见误区

  • 误区:删掉敏感属性就公平了。 代理变量会重建它;而且删掉后你连分组评测都做不了,反而更糟。合理做法常是「保留属性用于评测/审计,但约束其在决策中的使用」。
  • 误区:只报整体指标。 没有分组评测,偏见永远不可见。disaggregated evaluation 是地基。
  • 误区:追求「完全公平」。 不可能定理告诉你必须选指标。把「选了哪个、为什么」写进文档,比假装中立诚实得多。
  • 权衡:公平 vs. 精度。 多数情况下二者存在张力,存在一条帕累托前沿;目标是在前沿上选一个对你的场景可接受的点,而非幻想同时最优。
  • 注意反馈回路。 上线后持续监控分组指标漂移,否则偏见会随数据回流悄悄放大。

小结

算法偏见不是模型「学坏了」,而是数据分布、优化目标、评测口径里的偏差被忠实放大的结果。缓解的第一步永远是分组评测——看不见就治不了。随后才是预处理/训练中/后处理的干预。而最该刻进认知的是那条不可能定理:公平指标无法同时满足,去偏的本质是带着明确价值取向,在帕累托前沿上做一个可被审计、可被问责的选择。