AI/ML 详解:公平、偏见与去偏

Day 51 · 2026-07-08
面向:有编程经验的非 AI 方向工程师 · 难度:进阶

偏见的来源Sources of Bias

数据管线机制
一句话类比

模型偏见不是"某行代码写错了",而是像一条 ETL 数据管线——采集、抽样、打标、聚合每层都可能注入系统性偏斜,最后在模型里累积放大。跟分布式系统一样:污染往往不在终点,而是上游某个采样节点悄悄丢了数据,下游全盘继承还不自知。"垃圾进垃圾出"是对的,但偏见更隐蔽——合规、完整、没有 bug 的数据,依然可以是有偏的

它解决什么问题 + 工作机制

要治理偏见,先得知道它从哪进来。学界把机器学习管线里的偏见拆成几个互相独立的注入点——这很重要,因为不同来源要用完全不同的手段修,混为一谈只会白费力气:

  • 历史偏见(historical bias)——数据如实反映了一个不公正的世界。某岗位历来男性居多,模型学到的是"事实",但这事实本身就需要纠正;
  • 代表性偏见(representation bias)——采样让某些群体样本过少。人脸数据集深肤色样本稀缺 → 模型在这些人群误差系统性偏高;
  • 测量偏见(measurement bias)——想预测的东西无法直测,只能用代理标签(proxy)。想预测"犯罪"却只有"被捕"数据,而执法强度在人群间不均——代理与真值的偏差直接变成模型偏见;
  • 聚合偏见(aggregation bias)——用一个模型硬套异质人群,对谁都不最优;
  • 学习/评估偏见——损失函数最小化总体误差,天然牺牲少数群体;测试集若同样不均还会掩盖问题。
偏见沿管线的注入点

真实世界(不公正)→①历史数据采集→②代表性抽样→③测量打标(代理)
                    ↓
训练→④聚合/学习模型放大的偏见部署→反馈回真实世界(闭环强化)
↑ 每个 ① ~ ④ 是独立注入点,需要不同修法;部署又把偏见喂回世界,形成正反馈
代码示例
import pandas as pd

# 一份"看起来干净"的招聘历史数据:无缺失、无错误,但有偏
df = pd.read_csv("hiring.csv")  # 列: gender, hired(0/1)

# ① 代表性检查:各群体样本量是否悬殊?
print(df["gender"].value_counts(normalize=True))

# ② 历史偏见检查:正标签(hired)在群体间的基础比率(base rate)差多少?
#    模型会把这个历史差异当"信号"学下来并放大
base_rates = df.groupby("gender")["hired"].mean()
print(base_rates)
print("基础比率差(disparity):", base_rates.max() - base_rates.min())
# 差距大 → 直接拿去训练 = 把历史不公固化进模型
常见误区 + 实践场景
"把 gender、race 敏感列删掉,模型就公平了"——错,这叫 fairness through unawareness,几乎无效。敏感属性会通过代理变量泄漏:邮编关联种族、名字暗示性别、消费暴露收入。删标签只让你看不见偏见,模型照样从代理里重建它。要做的是测量偏见,而非蒙上眼睛。
📌 BigCat 场景:用 AI 筛简历 / 供应商 / 投资标的时,先问自己——参考数据来自哪个历史时期、哪种筛选逻辑?若历史本身有系统性倾斜,AI 给的"最优推荐"其实是在放大那个历史,而非给你中立判断。

公平性度量Fairness Metrics

定义群体公平
一句话类比

"公平"不是一个指标,而是像 SLA 定义——同一个系统,你可以承诺"每个租户吞吐量相同",也可以承诺"每个租户错误率相同",这是两份不同的合同,无法同时满足所有人。公平性度量就是把"公平"翻译成可计算的数学条件,而选哪个定义本身就是价值判断,不是技术细节。

它解决什么问题 + 工作机制

"这个模型公平吗"无法回答,除非你先说清按哪种公平。两个最主流的群体公平(group fairness)定义,分歧的根源在于:看输出,还是看错误?

  • 人口均等(Demographic Parity / 统计均等)——要求正预测率在各群体相等:P(Ŷ=1 | A=甲) = P(Ŷ=1 | A=乙)。直觉:录取率对每个群体一样,不管各群体真实合格率如何。它只看模型输出的分布;
  • 机会均等(Equalized Odds)——要求真阳率(TPR)和假阳率(FPR)在各群体都相等。直觉:在真正合格的人里,各群体被录取的概率一样(TPR 相等);在不合格的人里,各群体被误录的概率也一样(FPR 相等)。它看的是"模型犯错的方式"是否对各群体一致;
  • 均等机会(Equal Opportunity)——机会均等的放松版,要求 TPR 相等(合格者被公平对待),不管 FPR。当"漏掉真正合格的人"是主要伤害时用它。

关键区别:人口均等无视真值 Y,只看输出比率;机会均等以真值为条件,要求错误分布一致。所以若两群体真实合格率本就不同,这两个定义会打架——强行拉平录取率,必然在某群体制造更高错误率。这不是 bug,是下一张卡的数学必然。

定义数学条件以真值为条件?适用直觉
人口均等正预测率相等要求结果分布本身平等
机会均等TPR 且 FPR 相等要求"犯错方式"平等
均等机会仅 TPR 相等只在意别漏掉合格者
代码示例
from fairlearn.metrics import (MetricFrame,
    demographic_parity_difference, equalized_odds_difference)
from sklearn.metrics import selection_rate, true_positive_rate

# y_true 真值, y_pred 预测, A 敏感属性(如 gender)
mf = MetricFrame(
    metrics={"选择率": selection_rate, "真阳率TPR": true_positive_rate},
    y_true=y_true, y_pred=y_pred, sensitive_features=A)

print(mf.by_group)          # 逐群体看每个指标

# 一个数概括差距: 0 = 完全公平, 越大越不公
print("人口均等差:", demographic_parity_difference(
    y_true, y_pred, sensitive_features=A))     # 选择率的组间极差
print("机会均等差:", equalized_odds_difference(
    y_true, y_pred, sensitive_features=A))     # TPR/FPR 组间极差的较大者
# 两个数往往一个小一个大——印证它们在衡量不同的"公平"
常见误区 + 实践场景
"选一个公平指标优化到 0 就万事大吉"——错。单一指标可被钻空子:只满足人口均等,可以靠"甲群体随机录取、乙群体精准录取"凑数,录取率相等但质量天差地别。指标是诊断工具不是目标函数;孤立地优化某个数值到 0,往往在别处制造新的不公。
📌 BigCat 场景:当有人(或某供应商)宣称"我们的 AI 模型经过公平性认证",第一个要追问的是——按哪个定义? 人口均等还是机会均等?这两个答案对应完全不同的价值取向和适用场景。听不到明确答案,"公平"就是营销词。

公平的不可能定理Impossibility Theorem

数学trade-off核心
一句话类比

公平性有自己的 CAP 定理。就像分布式系统里一致性(C)、可用性(A)、分区容忍(P) 三者不可兼得,风险评分模型里的三种公平——校准(calibration)、假阳率均衡、真阳率均衡——在群体基础比率不同时,数学上不可能同时满足。这不是工程没做好,是定理证明了的天花板:你必须选择牺牲哪一个。

它解决什么问题 + 工作机制

2016 年,两组研究者(Kleinberg 等;以及 Chouldechova)几乎同时证明了这个结果,起因是著名的 COMPAS 累犯预测争议——ProPublica 指控该算法对黑人被告假阳率更高,厂商 Northpointe 反驳说算法是校准的(同一分数对各群体含义相同)。不可能定理揭示:双方都对,因为他们要的两种公平根本无法共存

三个条件的白话:

  • 校准:模型说"70% 会累犯",那在各群体里打这个分的人,实际累犯率都该是 70%。分数含义对所有群体一致;
  • 假阳率均衡:在不会累犯的人里,各群体被误判为高危的比例相同;
  • 真阳率均衡:在累犯的人里,各群体被正确识别的比例相同。

定理内容:只要两群体基础比率不同(真实累犯率不一样)、且模型不是 100% 完美,上面三条最多同时满足两条。为什么?——校准强迫"同一分数=同一真实风险",但当一个群体整体基础比率更高,为维持校准,模型必然在该群体要么放更多假阳、要么漏更多真阳,错误无法在群体间对齐。基础比率的差异被"挤"进了错误率里,躲不掉。

公平性的"CAP 三角"(基础比率不同时)

    校准 Calibration
     /   \
   /      \
假阳率均衡— ✗ 不可兼得 —真阳率均衡

↑ 三选二。COMPAS 之争:Northpointe 守"校准",ProPublica 要"假阳率均衡"——两者数学互斥
代码示例
import numpy as np
# 用最小例子看"校准"和"假阳率均衡"如何互相绞杀
# 两个群体, 基础比率不同: A组真实正例率 0.6, B组 0.3

def rates(y_true, score, thr=0.5):
    pred = (score >= thr).astype(int)
    tpr = pred[y_true == 1].mean()          # 真阳率
    fpr = pred[y_true == 0].mean()          # 假阳率
    return tpr, fpr

# 假设两组模型都完美校准(分数=真实概率), 但基础比率不同
rng = np.random.default_rng(0)
yA = (rng.random(10000) < 0.6).astype(int)  # A: 高基础比率
yB = (rng.random(10000) < 0.3).astype(int)  # B: 低基础比率
sA = np.where(yA==1, rng.random(10000)*.5+.5, rng.random(10000)*.5)
sB = np.where(yB==1, rng.random(10000)*.5+.5, rng.random(10000)*.5)

print("A组 TPR,FPR:", rates(yA, sA))
print("B组 TPR,FPR:", rates(yB, sB))
# 两组用同一阈值(都校准)→ 但 FPR 不相等; 想拉平 FPR 就得
# 给两组不同阈值 → 同一分数含义就不同了 → 打破校准。无解。
常见误区 + 实践场景
"总能找到一个足够聪明的算法同时满足所有公平定义"——错,这被数学证明排除了(除非基础比率恰好相等或模型完美,现实都不成立)。这不是"再努力一下"能突破的工程难题,而是逻辑天花板。当 CAP 定理对待:接受取舍存在,显式选择牺牲哪个、为什么。
📌 BigCat 场景:任何声称"我们的 AI 完全公平、没有任何偏见"的产品,要么没理解不可能定理,要么在回避取舍。作为技术决策者,正确的问题不是"公平吗",而是"你选了哪种公平、放弃了哪种、这个取舍谁来承担"——这才是负责任的表述。

去偏方法与因果公平Debiasing & Causal Fairness

干预因果
一句话类比

去偏就像数据质量治理——你可以在入库时清洗(预处理)、写入约束里强制(训练中)、或读取时打补丁(后处理),三个位置各有代价。因果公平更进一步:不满足于"相关性上看起来平等",而是问一个反事实——"如果这个人的敏感属性被改掉,决策会变吗?"——把公平从统计相关升级到因果机制。

它解决什么问题 + 工作机制

知道了偏见来源和度量,怎么修?三类干预按作用于管线的位置划分:

  • 预处理(pre-processing)——改数据:重加权、重采样、或变换特征表示去掉敏感信息。经典是 Bolukbasi 2016 词向量去偏——找出嵌入里的"性别方向"并把职业词投影掉。优点:与下游解耦;缺点:可能损失有用信号;
  • 训练中(in-processing)——改目标:损失里加公平约束,或用对抗去偏——加一个判别器专门从表示里猜敏感属性,主模型被训练到让它猜不出来。优点:权衡最优;缺点:要动模型内部;
  • 后处理(post-processing)——改输出:模型不动,只按群体调决策阈值。Hardt 等 2016 证明用群体特定阈值可精确达成机会均等。优点:无需重训、可套黑盒 API;缺点:显式按群体区别对待,可能有法律/伦理争议。

因果公平(causal fairness)是另一条路线。前面所有度量都是相关性的,无法区分"邮编影响决策"是因为邮编本身相关,还是因为它是种族的代理反事实公平(Kusner 等 2017)的定义:一个决策公平,当且仅当在反事实世界里——把个体敏感属性 A 改成另一个值、并沿因果图更新所有由 A 导致的下游变量——预测分布不变。它要求先画因果图(causal DAG),区分"A 的合法后代"和"应被阻断的歧视路径"。

去偏干预的三个位置 + 因果视角

数据→[预处理:重采样/表示去偏]→训练→[训练中:公平约束/对抗]→模型→[后处理:分组阈值]→决策

因果图视角(反事实公平)
A 敏感属性──合法路径?──→Ŷ 决策
  └──代理泄漏(邮编/名字)──✗应阻断──→
↑ 反事实问:改掉 A 并更新其后代,Ŷ 会变吗?变=不公
代码示例
from fairlearn.postprocessing import ThresholdOptimizer
from sklearn.ensemble import GradientBoostingClassifier

# 后处理去偏:不重训模型,只按群体调阈值达成"机会均等"
base = GradientBoostingClassifier().fit(X_tr, y_tr)

fair = ThresholdOptimizer(
    estimator=base,
    constraint="equalized_odds",   # 目标公平定义(见上一张卡)
    predict_method="predict_proba",
    prefit=True)

# 拟合时必须传敏感属性——它为每个群体学一组阈值
fair.fit(X_tr, y_tr, sensitive_features=A_tr)
y_fair = fair.predict(X_te, sensitive_features=A_te)
# 代价: 通常总体精度略降——这就是不可能定理里你付的"公平税"
# 注意: 推理时也要敏感属性, 部署上可能涉及合规限制
常见误区 + 实践场景
"去偏 = 让模型更准"——错,恰恰相反。在不可能定理的约束下,去偏通常要牺牲一部分总体精度换取错误分布更均衡——这是成本不是免费午餐。诚实的做法是量化这个"公平税"有多大、谁受益谁承担。此外因果公平强依赖你画的因果图——图画错了,"因果公平"只是给错误结论套层严谨外壳。
📌 BigCat 场景:搭个人 AI 决策辅助(筛人、选项目)时,与其事后补救,不如在设计阶段就想清楚:哪些因素是合法依据、哪些只是相关的代理。把这张"因果图"显式画出来——既是去偏前提,也逼你把判断标准讲清楚,本身就是一次高质量思维训练。
Takeaway + 思考题
💡 公平不是能"达成"的状态,而是一组需显式选择的取舍:选定义、认代价、画因果、担后果。回避取舍的"绝对公平",是最不负责任的公平。
🤔 你用 AI 辅助决策时,有没有把某个"统计相关"误当成"合理依据"?画一张因果图,哪些箭头其实该被阻断?

深入资源Further Reading

深入思考Deep Questions

1. "删掉敏感属性就公平"为什么几乎总是无效?这和"数据匿名化为什么会失败"是不是同一个道理?
是同一个道理,机制都是信息通过相关变量泄漏(proxy leakage / 高维重识别)。匿名化失败在于:删掉姓名身份证,"邮编+生日+性别"就能重识别绝大多数人(Sweeney 的经典结果),身份信息冗余分布在其他字段里。删敏感属性同理:种族编码在邮编、消费、语言、社交图里,模型有足够代理去重建那一列——你删的是"标签"不是"信息"。深层教训一致:信息不因你不看它就消失。正解方向也一致:从"藏起来"转向"显式建模并控制"——隐私用差分隐私给出可量化的泄漏上界,公平用感知敏感属性的方法主动测量约束。反直觉但关键:要实现公平,你往往必须在训练/评估时用敏感属性,而不是删掉它。
2. 相关性公平和因果公平在什么情况下会给出相反结论?为什么"画因果图"既是因果公平的力量,也是它最大的软肋?
分歧的经典场景:存在合法中介变量。某岗位录取和"相关工作经验"强相关,经验又和敏感属性相关。纯相关度量(人口均等)看到录取率组间不等就判不公、要求拉平;因果视角可能认为"经验→录取"是合法路径,只要不是敏感属性的直接歧视或代理泄漏就不算不公——结论相反。因果公平的力量在于能区分"合法相关"和"歧视相关",这是纯统计做不到的(统计上二者一模一样)。软肋也在此:区分依赖你先验假设的因果图,而因果图通常无法只从数据验证(相关不能证因果)。把"经验"当合法中介还是历史歧视的产物?换张图结论就翻转。所以因果公平没消除价值判断,只是把它前移显式化到画图这步——既让假设可讨论(好事),也藏着一个可能被操纵的建模选择(风险)。
3. 部署后模型会把预测反馈回真实世界("高危"标签影响执法强度、再产出新数据)。这个回路怎样让偏见自我强化?和"缓存雪崩/重试风暴"有何异同?
机制是正反馈导致的自我实现:判某区"高犯罪"→ 警力倾斜 → 逮捕数上升(哪怕真实犯罪率没变)→ 新数据"证实"高犯罪 → 模型更笃定。偏见不是静态的,而是被自己的预测放大,测量偏见(逮捕≠犯罪)在闭环里被加固。和分布式失控回路相似:正反馈缺阻尼、局部扰动被放大成系统性偏移,像"失败→重试→更过载→更多失败"。关键不同:分布式失控快而显性(秒级雪崩、监控立刻报警),算法偏见慢而隐性(月/年尺度、每步都"数据支持"自洽合理),发现时已固化成"事实"。可迁移治理:(1) 加阻尼/断路器,限制单一模型对世界的干预强度;(2) 反事实监控,对照"没有模型干预会怎样"的基线;(3) 探索性采样,主动在模型"不看好"的区域采真实标签,打破自证闭环。
4. 如果"完全公平"被证明不可能,那追求公平的意义是什么?这和佛学"不圆满中如何行动"、复杂系统"没有全局最优只有局部权衡"是否指向同一种成熟?
不可能定理消解的是"存在一个客观正确的公平解"这个幻觉,却恰恰提升了追求公平的意义——它把问题从"找到正确答案"转成"承认取舍的前提下,负责任地选择并承担"。这与几种成熟观指向同一处:佛学讲缘起——没有孤立自性的"公平"实体可执取,公平是随条件(基础比率、伤害类型、谁受影响)缘起的关系性判断,执着于绝对公平反而是苦的来源;但"空"不导向不作为,而是因无固定标准,故每个选择都需当下的觉察与担当。复杂系统亦然:没有全局最优,只有约束下的帕累托前沿,成熟是清醒地知道自己站在前沿哪一点、代价谁付。三者共通:放弃"有唯一正确答案"的确定性焦虑,换取"在不圆满中持续、透明、负责地选择"的能力。对追求"AI 超级个体"的人,这或是最重要的元技能——你和 AI 的每个判断都不是逼近某个客观正确,而是显式选择要成为什么样的决策者