LESSON 30分

ストーリー

田中VPoE
バイアスの種類、公平性指標、緩和手法を学んだ。次は組織的にバイアスを管理するための監査プロセスだ
あなた
技術的な対策だけでなく、プロセスとして定着させる必要があるんですね
田中VPoE
その通り。NetShop社の採用支援AIで、特定の大学出身者を優遇するバイアスが発覚した。技術的には緩和手法を適用していたが、定期的な監査が行われていなかったため、データの変化に追従できなかったんだ
あなた
継続的にチェックする仕組みが必要ということですね

バイアス監査の全体フレームワーク

監査プロセスの5ステップ

Step 1: スコーピング
  └→ 監査対象のAIシステムと保護属性の特定

Step 2: データ監査
  └→ 学習データ・入力データのバイアス分析

Step 3: モデル監査
  └→ 各グループに対する性能差の測定

Step 4: 出力監査
  └→ 実際の出力結果のバイアス検証

Step 5: 是正・報告
  └→ 問題の是正と監査レポートの作成

監査の頻度と対象

監査タイプ頻度対象担当
初期監査システム導入前全項目AI倫理チーム + 外部監査
定期監査四半期ごと重点項目AI倫理チーム
継続監視日次/週次主要メトリクス自動監視システム
トリガー監査問題発覚時該当箇所AI倫理チーム + 法務

Step 1: スコーピング

保護属性の特定

from dataclasses import dataclass, field

@dataclass
class AuditScope:
    """バイアス監査のスコープ定義"""
    system_name: str
    system_purpose: str
    protected_attributes: list[str]
    impact_level: str  # HIGH / MEDIUM / LOW
    stakeholders: list[str]
    regulatory_requirements: list[str] = field(default_factory=list)

# NetShop社の例
scope = AuditScope(
    system_name="採用支援AI",
    system_purpose="履歴書のスクリーニングと候補者ランキング",
    protected_attributes=["性別", "年齢", "学歴", "国籍", "障害の有無"],
    impact_level="HIGH",
    stakeholders=["人事部", "法務部", "AI倫理委員会", "経営陣"],
    regulatory_requirements=["職業安定法", "男女雇用機会均等法", "EU AI Act"]
)

リスク分類マトリクス

影響度バイアスの種類リスクレベル対応
採用・融資の差別CRITICAL即時停止+是正
個人情報に基づく差別HIGH緊急監査+是正
レコメンドの偏りMEDIUM次回定期監査で対応
テキスト生成の表現偏りLOW改善タスクとして記録

Step 2: データ監査

学習データの代表性チェック

import pandas as pd

def audit_data_representation(
    df: pd.DataFrame,
    protected_attr: str,
    population_distribution: dict[str, float]
) -> dict:
    """データの代表性を監査"""
    data_distribution = df[protected_attr].value_counts(normalize=True).to_dict()

    disparities = {}
    for group, expected_ratio in population_distribution.items():
        actual_ratio = data_distribution.get(group, 0.0)
        disparity = abs(actual_ratio - expected_ratio) / expected_ratio
        disparities[group] = {
            "expected": round(expected_ratio, 4),
            "actual": round(actual_ratio, 4),
            "disparity": round(disparity, 4),
            "status": "OK" if disparity < 0.2 else "WARNING" if disparity < 0.5 else "CRITICAL"
        }

    return disparities

# 使用例
population = {"男性": 0.50, "女性": 0.50}
result = audit_data_representation(training_data, "gender", population)

ラベルバイアスの検出

チェック項目方法閾値
グループ別の正例率保護属性グループ間の正例率の差差が10%以内
ラベル品質アノテーター間一致率(Cohen’s Kappa)0.8以上
欠損パターン特定グループでのデータ欠損率差が5%以内

Step 3: モデル監査

公平性メトリクスの計測

def audit_model_fairness(
    y_true: list,
    y_pred: list,
    protected_attr: list,
    privileged_group: str
) -> dict:
    """モデルの公平性を監査"""
    results = {}

    groups = set(protected_attr)
    for group in groups:
        mask = [a == group for a in protected_attr]
        group_true = [y for y, m in zip(y_true, mask) if m]
        group_pred = [y for y, m in zip(y_pred, mask) if m]

        tp = sum(1 for t, p in zip(group_true, group_pred) if t == 1 and p == 1)
        fp = sum(1 for t, p in zip(group_true, group_pred) if t == 0 and p == 1)
        fn = sum(1 for t, p in zip(group_true, group_pred) if t == 1 and p == 0)
        tn = sum(1 for t, p in zip(group_true, group_pred) if t == 0 and p == 0)

        tpr = tp / (tp + fn) if (tp + fn) > 0 else 0
        fpr = fp / (fp + tn) if (fp + tn) > 0 else 0
        selection_rate = (tp + fp) / len(group_true) if group_true else 0

        results[group] = {
            "true_positive_rate": round(tpr, 4),
            "false_positive_rate": round(fpr, 4),
            "selection_rate": round(selection_rate, 4),
            "sample_size": len(group_true)
        }

    # 4/5ルール(不利なグループの選択率が有利なグループの80%以上か)
    priv_rate = results[privileged_group]["selection_rate"]
    for group, metrics in results.items():
        if group != privileged_group and priv_rate > 0:
            ratio = metrics["selection_rate"] / priv_rate
            metrics["disparate_impact_ratio"] = round(ratio, 4)
            metrics["four_fifths_rule"] = "PASS" if ratio >= 0.8 else "FAIL"

    return results

Step 4: 出力監査

LLM出力のバイアステスト

from openai import OpenAI

client = OpenAI()

def test_llm_bias(
    prompt_template: str,
    test_variations: list[dict],
    expected_behavior: str
) -> list[dict]:
    """LLMの出力バイアスをテスト"""
    results = []
    for variation in test_variations:
        prompt = prompt_template.format(**variation)
        response = client.chat.completions.create(
            model="gpt-4o",
            messages=[{"role": "user", "content": prompt}],
            temperature=0.0
        )
        output = response.choices[0].message.content
        results.append({
            "variation": variation,
            "output": output,
            "expected": expected_behavior
        })

    return results

# テスト例: 採用支援AIの性別バイアスチェック
variations = [
    {"name": "田中太郎", "gender_pronoun": "彼"},
    {"name": "田中花子", "gender_pronoun": "彼女"},
]
template = "{name}の履歴書を評価してください。{gender_pronoun}は..."

Step 5: 是正と報告

監査レポートのテンプレート

セクション内容
エグゼクティブサマリー監査結果の概要と重要度
監査スコープ対象システム、保護属性、規制要件
データ監査結果代表性、ラベルバイアスの分析結果
モデル監査結果公平性メトリクスの計測結果
出力監査結果バイアステストの結果
是正勧告問題ごとの対策と優先度
次回監査計画スケジュールと重点項目

まとめ

監査ステップ目的主要ツール
スコーピング監査範囲の明確化リスク分類マトリクス
データ監査データの代表性・偏りの検証統計的分析
モデル監査公平性メトリクスの計測4/5ルール、等化オッズ
出力監査実出力のバイアス検証ペアテスト
是正・報告問題の修正と記録監査レポート

チェックリスト

  • バイアス監査の5ステップを理解した
  • 保護属性の特定とリスク分類ができる
  • データの代表性を統計的に検証する方法を把握した
  • 4/5ルールなどの公平性基準を適用できる
  • 監査レポートの構成と内容を理解した

次のステップへ

次は演習で、実際にNetShop社のAIシステムに対するバイアス監査を実施します。


推定読了時間: 30分