ストーリー
公平性指標の前提知識
保護属性とグループ
保護属性(Protected Attributes):
性別、年齢、人種、宗教、障害の有無、出身地 など
→ これらに基づく差別は法的にも倫理的にも問題
グループの定義:
保護属性の値に基づいてグループを分ける
例: 性別 → グループA(男性)、グループB(女性)
混同行列の復習
予測: 正 予測: 負
実際: 正 TP(真陽性) FN(偽陰性)
実際: 負 FP(偽陽性) TN(真陰性)
True Positive Rate (TPR) = TP / (TP + FN) ... 感度
False Positive Rate (FPR) = FP / (FP + TN)
Positive Predictive Value (PPV) = TP / (TP + FP) ... 適合率
主要な公平性指標
1. Demographic Parity(統計的均衡)
定義: すべてのグループで「陽性と判定される割合」が等しいこと
P(Y_hat = 1 | Group = A) = P(Y_hat = 1 | Group = B)
例: 融資審査AI
男性の承認率: 60%
女性の承認率: 60%
→ Demographic Parityを満たす
男性の承認率: 60%
女性の承認率: 40%
→ Demographic Parityを満たさない
| 長所 | 短所 |
|---|---|
| 直感的に理解しやすい | グループ間の実際の差を無視する |
| 結果の平等を保証 | 精度を犠牲にする場合がある |
| 法的要件を満たしやすい | 逆差別の可能性 |
2. Equal Opportunity(機会の均等)
定義: すべてのグループで「真陽性率(TPR)」が等しいこと
P(Y_hat = 1 | Y = 1, Group = A) = P(Y_hat = 1 | Y = 1, Group = B)
例: 不正検知AI
実際に不正な取引の検出率:
グループA: 90%
グループB: 90%
→ Equal Opportunityを満たす
実際に不正な取引の検出率:
グループA: 90%
グループB: 70%
→ Equal Opportunityを満たさない
| 長所 | 短所 |
|---|---|
| 「適格な人を平等に扱う」という直感に合う | 不適格な人の扱いは考慮しない |
| 精度を大きく犠牲にしない | FPRの差は許容してしまう |
3. Equalized Odds(均等化オッズ)
定義: すべてのグループでTPRとFPRの両方が等しいこと
Equal Opportunity + False Positive Rateの均等
TPR: P(Y_hat=1 | Y=1, A) = P(Y_hat=1 | Y=1, B)
FPR: P(Y_hat=1 | Y=0, A) = P(Y_hat=1 | Y=0, B)
→ Equal Opportunityより厳しい条件
→ 正の予測も負の予測も公平
4. Calibration(較正)
定義: 「スコアXと判定されたグループAとBで、実際の陽性率が等しい」こと
P(Y = 1 | Score = s, Group = A) = P(Y = 1 | Score = s, Group = B)
例: 信用スコアAI
スコア80点のグループA: 返済率85%
スコア80点のグループB: 返済率85%
→ Calibrationを満たす
スコア80点のグループA: 返済率85%
スコア80点のグループB: 返済率70%
→ Calibrationを満たさない(同じスコアでも実態が異なる)
指標の比較と選定
各指標の比較表
| 指標 | 焦点 | 適したユースケース |
|---|---|---|
| Demographic Parity | 結果の均等 | 採用、融資(結果平等が重視される場面) |
| Equal Opportunity | 適格者の平等な扱い | 不正検知、医療診断 |
| Equalized Odds | 全体的な予測の公平性 | 刑事司法、リスク評価 |
| Calibration | スコアの信頼性 | 信用スコア、保険料算定 |
指標間のトレードオフ
重要な事実:
すべての公平性指標を同時に満たすことは
数学的に不可能(Impossibility Theorem)
→ 文脈に応じて、最も重要な指標を選ぶ必要がある
公平性指標の実装
class FairnessMetrics:
"""公平性指標を計算するクラス"""
def demographic_parity(
self, predictions: list, groups: list
) -> dict:
"""Demographic Parityを計算"""
group_rates = {}
for pred, group in zip(predictions, groups):
if group not in group_rates:
group_rates[group] = {"positive": 0, "total": 0}
group_rates[group]["total"] += 1
if pred == 1:
group_rates[group]["positive"] += 1
rates = {
g: d["positive"] / d["total"]
for g, d in group_rates.items()
}
max_diff = max(rates.values()) - min(rates.values())
return {
"rates": rates,
"max_difference": max_diff,
"satisfied": max_diff < 0.1, # 10%以内なら合格
}
def equal_opportunity(
self, predictions: list, actuals: list, groups: list
) -> dict:
"""Equal Opportunityを計算"""
group_tpr = {}
for pred, actual, group in zip(predictions, actuals, groups):
if actual != 1:
continue
if group not in group_tpr:
group_tpr[group] = {"tp": 0, "total_positive": 0}
group_tpr[group]["total_positive"] += 1
if pred == 1:
group_tpr[group]["tp"] += 1
tpr = {
g: d["tp"] / d["total_positive"]
for g, d in group_tpr.items()
if d["total_positive"] > 0
}
max_diff = max(tpr.values()) - min(tpr.values())
return {
"tpr_by_group": tpr,
"max_difference": max_diff,
"satisfied": max_diff < 0.1,
}
NetShop社での公平性指標の適用
| AIシステム | 推奨指標 | 理由 |
|---|---|---|
| 商品レコメンド | Demographic Parity | 全ユーザーに同等の推薦品質を保証 |
| カスタマーサポート | Equal Opportunity | 同じ問題を持つユーザーに同等の解決率 |
| 不正検知 | Equalized Odds | 不正・正常の両方で公平な判定 |
| 信用スコア | Calibration | スコアの信頼性を全グループで保証 |
まとめ
| 指標 | 定義 | 数式 |
|---|---|---|
| Demographic Parity | 全グループで陽性判定率が等しい | P(Y_hat=1|A) = P(Y_hat=1|B) |
| Equal Opportunity | 全グループでTPRが等しい | P(Y_hat=1|Y=1,A) = P(Y_hat=1|Y=1,B) |
| Equalized Odds | TPRとFPRの両方が等しい | TPRとFPRの均等 |
| Calibration | 同スコアで実際の陽性率が等しい | P(Y=1|Score=s,A) = P(Y=1|Score=s,B) |
チェックリスト
- 4つの公平性指標の定義と違いを説明できる
- 各指標の長所・短所を理解した
- ビジネスの文脈に応じた指標の選定ができる
- 公平性指標の実装方法を理解した
推定所要時間: 30分