在构建和部署AI模型的过程中,评估模型的性能(如准确率、召回率)是标准流程。然而,模型在不同人群子集(如基于性别、种族、年龄)上的表现可能存在显著差异,这便是“公平性偏差”。Fairlearn是一个强大的开源工具包,专门用于评估和缓解机器学习系统中的公平性问题。本文将重点介绍如何使用Fairlearn的核心组件MetricFrame来量化这些偏差,实现高度实操性的公平性评估。
1. 为什么需要量化公平性?
公平性偏差通常表现为模型在敏感特征(Sensitive Features)的不同群体上,关键性能指标(Metrics)的差异。例如,如果一个贷款审批模型对“女性”群体的误拒率(False Negative Rate)远高于“男性”群体,我们就说模型存在“机会不平等”的偏差。
量化是解决问题的第一步。Fairlearn通过提供统一的接口,帮助我们计算群体差异。
2. 环境准备与数据设置
首先,确保安装了必要的库:
pip install fairlearn scikit-learn pandas numpy
我们将使用一个模拟数据集,其中包含一个敏感特征Gender,并故意引入一些偏差,以演示评估过程。
import numpy as np
import pandas as pd
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score, recall_score
from fairlearn.metrics import MetricFrame
# 设定随机种子以保证结果可复现
np.random.seed(42)
N = 1000
# 模拟数据集
data = pd.DataFrame({
'Feature1': np.random.rand(N),
'Feature2': np.random.randint(0, 10, N),
'Gender': np.random.choice(['Male', 'Female'], N), # 敏感特征
'Target': np.random.randint(0, 2, N) # 目标变量
})
# 故意制造偏差:假设在数据中,Female群体的Target更容易是1
data.loc[data['Gender'] == 'Female', 'Target'] = np.random.choice([0, 1], size=data[data['Gender'] == 'Female'].shape[0], p=[0.3, 0.7])
data.loc[data['Gender'] == 'Male', 'Target'] = np.random.choice([0, 1], size=data[data['Gender'] == 'Male'].shape[0], p=[0.7, 0.3])
# 数据预处理与分割
X = pd.get_dummies(data[['Feature1', 'Feature2', 'Gender']], drop_first=True)
y = data['Target']
sensitive_features = data['Gender']
X_train, X_test, y_train, y_test, sensitive_train, sensitive_test = train_test_split(
X, y, sensitive_features, test_size=0.3, random_state=42
)
# 训练模型
model = LogisticRegression(solver='liblinear')
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
3. 使用 MetricFrame 进行公平性评估
MetricFrame是Fairlearn中用于计算和比较群体指标的核心工具。它接收评估指标函数、真实值、预测值和敏感特征,并自动按敏感特征分组计算指标。
我们将评估两个关键指标:整体准确率(Accuracy)和真阳性率(True Positive Rate, 即Recall)。
真阳性率(TPR)是衡量在所有实际为正例的样本中,模型正确预测为正例的比例。如果TPR在不同群体间存在显著差异,则违反了“机会平等”(Equality of Opportunity)原则。
# 定义我们需要评估的指标字典
metric_fns = {"Accuracy": accuracy_score, "True Positive Rate (Recall)": recall_score}
# 实例化 MetricFrame
grouped_metrics = MetricFrame(
metrics=metric_fns,
y_true=y_test,
y_pred=y_pred,
sensitive_features=sensitive_test
)
print("\n--- 1. 总体和群体指标 --- ")
# by_group 属性显示了每个群体和所有样本的指标
print(grouped_metrics.by_group)
示例输出(部分):
--- 1. 总体和群体指标 ---
Accuracy True Positive Rate (Recall)
Gender
Female 0.865385 0.941176
Male 0.640523 0.301370
(overall) 0.763333 0.669811
从结果可以看出,模型对Female群体的准确率和真阳性率均远高于Male群体。这表明模型在预测积极结果时,严重偏向了Female群体。
4. 计算和解读偏差量化指标
MetricFrame提供了两种核心方法来直接量化群体间的最大差异:difference()和ratio()。
- ****difference()****: 计算指标的最大值和最小值之间的绝对差值(Max – Min)。
- ****ratio()****: 计算指标的最小值和最大值之间的比率(Min / Max)。
对于大部分指标(如准确率、TPR),我们通常希望difference接近于0,而ratio接近于1。
print("\n--- 2. 公平性偏差分析 --- ")
# 计算准确率的最大差异
acc_diff = grouped_metrics.difference()['Accuracy']
print(f"最大差异 (Accuracy, Difference): {acc_diff:.4f}")
# 计算真阳性率(Recall)的最小比率
tpr_ratio = grouped_metrics.ratio()['True Positive Rate (Recall)']
print(f"最小比率 (TPR, Ratio): {tpr_ratio:.4f}")
# 计算真阳性率的最大差异
tpr_diff = grouped_metrics.difference()['True Positive Rate (Recall)']
print(f"最大差异 (TPR, Difference): {tpr_diff:.4f}")
解读分析:
- ****TPR Ratio** 接近0.32:由于Male群体的TPR是Female群体的约三分之一,这个比率(Min/Max)远低于理想值1。这意味着在实际为正例的样本中,Male群体被正确识别的机会比Female**群体低了近70%。这是一个严重的“机会不平等”偏差。
- ****Accuracy Difference** 接近0.22**:两个群体间的准确率差异高达22%,表明模型的总体性能也极度不均衡。
总结
通过使用Fairlearn的MetricFrame,我们能够系统地、量化地评估AI模型在关键性能指标上是否存在公平性偏差。这一步骤是模型部署前不可或缺的一环,尤其对于涉及敏感决策的AI系统。识别出偏差后,下一步就可以利用Fairlearn提供的缓解算法(如ExponentiatedGradient或GridSearch)来优化模型,提高其跨群体的公平性。
汤不热吧