知识体系篇-数据标注与处理(05)模型测试与评估:模型公平性与偏见检测
AI模型公平性与偏见检测摘要 本文系统介绍了AI模型偏见问题及其检测方法。偏见主要来源于训练数据、标注过程和算法优化目标,会通过模型预测放大社会不平等。文章详细解析了四种公平性定义(统计均等、均等机会、预测率均等和个体公平),指出这些标准存在理论矛盾,需根据业务场景权衡选择。通过Python代码示例演示了贷款审批场景下的偏见检测方法,包括统计均等差异计算、均等机会指标(TPR/FPR)分析和差异影
·
模型公平性与偏见检测
专栏:人工智能训练师(三级)备考全攻略
模块:卷三·知识体系 — 第四部分·模型测试与评估
难度:⭐⭐⭐☆☆
考试权重:中高频(AI伦理必考,选择+简答)
一、为什么模型会有偏见?
AI偏见的来源链条:
现实世界(存在历史偏见)
│
▼
训练数据(记录和放大偏见)
│
▼
机器学习模型(学习到偏见)
│
▼
模型预测(输出带有偏见的结果)
│
▼
现实影响(贷款拒绝/简历筛除/错误诊断)
例:
历史招聘数据中,技术岗位90%为男性。
模型学到"男性→更适合技术岗"的偏见。
新简历筛选时,同等条件下女性被拒绝率更高。
1.1 偏见的三个来源
| 来源 | 说明 | 示例 |
|---|---|---|
| 数据偏见 | 训练数据不代表总体,存在采样偏差 | 人脸识别训练集以白人为主 |
| 标注偏见 | 标注者的主观偏见影响标签质量 | 标注者认为"女性不适合编程" |
| 算法偏见 | 模型优化目标忽视弱势群体 | 最大化整体准确率导致少数族裔误判率高 |
二、公平性的定义与度量
2.1 公平性定义全景
公平性(Fairness)没有唯一定义,
常见的公平性定义相互矛盾,不可能同时满足。
常用公平性定义(记住这几个!)
① 统计均等(Demographic Parity)
各群体获得正向预测的概率相等
P(Ŷ=1|A=0) = P(Ŷ=1|A=1)
② 均等机会(Equalized Odds)
各群体的真正例率(TPR)和假正例率(FPR)相等
P(Ŷ=1|Y=1, A=0) = P(Ŷ=1|Y=1, A=1) ← TPR相等
P(Ŷ=1|Y=0, A=0) = P(Ŷ=1|Y=0, A=1) ← FPR相等
③ 预测率均等(Predictive Parity)
各群体中预测为正例时,真实为正例的概率相等
P(Y=1|Ŷ=1, A=0) = P(Y=1|Ŷ=1, A=1) ← Precision相等
④ 个体公平性(Individual Fairness)
相似的个体应该得到相似的预测结果
| 公平性定义 | 数学要求 | 直觉解释 | 适用场景 |
|---|---|---|---|
| 统计均等 | 各群体正预测率相等 | 给每类人"同等机会" | 招聘/贷款初筛 |
| 均等机会 | 各群体TPR相等 | 对真正合格者"一视同仁" | 信用评分/假释 |
| 预测率均等 | 各群体Precision相等 | 预测为"高风险"时同等准确 | 医疗诊断/刑事司法 |
| 个体公平 | 相似者得相似结果 | 不因身份不同被区别对待 | 通用场景 |
2.2 公平性困境
理论证明:统计均等、均等机会、预测率均等三者不可兼得
(Chouldechova 2017, Kleinberg et al. 2017)
意味着:
没有"完美的"公平性定义
必须根据业务场景选择优先满足哪种公平性
工程实践中需要明确权衡
三、偏见检测实战
import numpy as np
import pandas as pd
from sklearn.metrics import confusion_matrix, classification_report
# =========================================
# 构造示例数据(贷款审批场景)
# =========================================
np.random.seed(42)
n = 2000
data = pd.DataFrame({
"gender": np.random.choice(["male", "female"], n, p=[0.5, 0.5]),
"age_group": np.random.choice(["young", "middle", "senior"], n),
"income": np.random.normal(50000, 20000, n),
"credit_score": np.random.randint(300, 850, n),
})
# 真实标签:根据信用分和收入决定(与性别无关)
data["true_label"] = (
(data["credit_score"] > 600) &
(data["income"] > 40000)
).astype(int)
# 模型预测:存在对女性的偏见(女性批准率人为降低)
data["pred_label"] = data["true_label"].copy()
female_mask = data["gender"] == "female"
data.loc[female_mask & (data["pred_label"] == 1), "pred_label"] = \
np.random.choice([0, 1], female_mask.sum() // 2, p=[0.2, 0.8])
# =========================================
# 偏见检测工具类
# =========================================
class FairnessAuditor:
"""AI公平性审计工具"""
def __init__(self, y_true, y_pred, sensitive_attr):
self.y_true = np.array(y_true)
self.y_pred = np.array(y_pred)
self.sensitive = np.array(sensitive_attr)
self.groups = np.unique(self.sensitive)
def demographic_parity(self):
"""统计均等:各群体正预测率"""
results = {}
for group in self.groups:
mask = self.sensitive == group
results[group] = self.y_pred[mask].mean()
rates = list(results.values())
disparity = max(rates) - min(rates)
print("\n📊 统计均等(Demographic Parity)")
for group, rate in results.items():
print(f" {group}: 正预测率 = {rate:.2%}")
print(f" 差异(Disparity) = {disparity:.2%}",
"✅" if disparity < 0.1 else "❌ 偏见!")
return results, disparity
def equalized_odds(self):
"""均等机会:各群体TPR和FPR"""
results = {}
for group in self.groups:
mask = self.sensitive == group
tn, fp, fn, tp = confusion_matrix(
self.y_true[mask], self.y_pred[mask]
).ravel()
tpr = tp / (tp + fn) if (tp + fn) > 0 else 0
fpr = fp / (fp + tn) if (fp + tn) > 0 else 0
results[group] = {"TPR": tpr, "FPR": fpr}
tpr_values = [v["TPR"] for v in results.values()]
fpr_values = [v["FPR"] for v in results.values()]
tpr_disparity = max(tpr_values) - min(tpr_values)
fpr_disparity = max(fpr_values) - min(fpr_values)
print("\n📊 均等机会(Equalized Odds)")
for group, metrics in results.items():
print(f" {group}: TPR={metrics['TPR']:.2%}, FPR={metrics['FPR']:.2%}")
print(f" TPR差异 = {tpr_disparity:.2%}", "✅" if tpr_disparity < 0.05 else "❌")
print(f" FPR差异 = {fpr_disparity:.2%}", "✅" if fpr_disparity < 0.05 else "❌")
return results
def disparate_impact_ratio(self):
"""
差异影响比(DIR)
DIR = 弱势群体正预测率 / 优势群体正预测率
DIR < 0.8 → 存在系统性歧视(美国EEOC标准:4/5规则)
"""
rates = {}
for group in self.groups:
mask = self.sensitive == group
rates[group] = self.y_pred[mask].mean()
max_group = max(rates, key=rates.get)
min_group = min(rates, key=rates.get)
dir_value = rates[min_group] / rates[max_group]
print(f"\n📊 差异影响比(DIR)= {dir_value:.3f}")
if dir_value < 0.8:
print(f" ❌ DIR < 0.8,违反4/5规则,存在歧视风险!")
else:
print(f" ✅ DIR ≥ 0.8,通过4/5规则")
return dir_value
def full_audit(self):
"""运行完整审计"""
print("=" * 50)
print(" AI公平性审计报告")
print("=" * 50)
self.demographic_parity()
self.equalized_odds()
self.disparate_impact_ratio()
print("=" * 50)
# 运行审计
auditor = FairnessAuditor(
y_true=data["true_label"],
y_pred=data["pred_label"],
sensitive_attr=data["gender"]
)
auditor.full_audit()
# 预期输出:
# 统计均等 - female: 72%, male: 85% → 差异13% ❌ 偏见!
# DIR = 0.847 → 接近4/5规则边界
四、Fairlearn:专业公平性检测库
# pip install fairlearn
from fairlearn.metrics import (
MetricFrame,
demographic_parity_difference,
equalized_odds_difference
)
from sklearn.metrics import accuracy_score
# =========================================
# 使用 MetricFrame 分群评估
# =========================================
mf = MetricFrame(
metrics={"accuracy": accuracy_score},
y_true=data["true_label"],
y_pred=data["pred_label"],
sensitive_features=data["gender"]
)
print("各群体准确率:")
print(mf.by_group)
print(f"\n最大差异: {mf.difference()['accuracy']:.4f}")
# =========================================
# 公平性指标计算
# =========================================
dp_diff = demographic_parity_difference(
y_true=data["true_label"],
y_pred=data["pred_label"],
sensitive_features=data["gender"]
)
print(f"\n统计均等差异(越接近0越公平): {dp_diff:.4f}")
eo_diff = equalized_odds_difference(
y_true=data["true_label"],
y_pred=data["pred_label"],
sensitive_features=data["gender"]
)
print(f"均等机会差异(越接近0越公平): {eo_diff:.4f}")
五、偏见缓解方法
缓解偏见的三个时间节点:
① 预处理(Pre-processing)
在训练前修正数据
方法:重采样、重新加权、对抗去偏
② 训练中(In-processing)
在训练过程中添加公平性约束
方法:公平性正则化项、对抗训练去偏
③ 后处理(Post-processing)
在预测后调整输出
方法:阈值调整(各群体用不同决策阈值)
校准(Calibration)
| 方法 | 阶段 | 优点 | 缺点 |
|---|---|---|---|
| 重采样 | 预处理 | 简单易实现 | 可能丢失信息 |
| 对抗去偏 | 训练中 | 效果好,端到端 | 训练复杂,不稳定 |
| 公平性正则化 | 训练中 | 与模型紧耦合 | 需要调整正则强度 |
| 阈值调整 | 后处理 | 无需改动模型 | 可能损失整体精度 |
六、考试重点总结
6.1 核心概念
| 概念 | 关键点 |
|---|---|
| 三类偏见来源 | 数据偏见/标注偏见/算法偏见 |
| 统计均等 | 各群体正预测率相等 |
| 均等机会 | 各群体TPR和FPR相等 |
| 差异影响比DIR | < 0.8则违反4/5规则,存在歧视风险 |
| 公平性不可兼得 | 三种定义数学上相互矛盾 |
6.2 高频选择题
Q: 以下哪个不是AI偏见的来源?
A: 模型架构选择(架构本身不引入偏见)✅
Q: 差异影响比(DIR)低于什么值被认为存在歧视风险?
A: 0.8(4/5规则)✅
Q: "弱势群体真正例率等于优势群体真正例率"是哪种公平性?
A: 均等机会(Equalized Odds)✅
Q: 统计均等和均等机会可以同时满足吗?
A: 一般情况下不能同时满足 ✅
Q: 以下哪种方法属于后处理阶段的偏见缓解?
A: 阈值调整(为不同群体设置不同决策阈值)✅
七、思维导图
📌 备考贴士:公平性是AI伦理的核心考点,记住三类偏见来源和三种公平性定义。“差异影响比DIR<0.8存在歧视风险"是选择题高频考点,4/5规则一定要记住。简答题常考"如何缓解AI模型偏见”,背熟预处理/训练中/后处理三阶段框架即可。
更多推荐



所有评论(0)