bias-audit

Par mkurman · zorai

Audite les biais d'un dataset sur les attributs protégés — parité démographique, égalisation des chances, écarts de représentation et biais intersectionnels. Génère des rapports d'écarts exploitables avec des métriques par groupe.

npx skills add https://github.com/mkurman/zorai --skill bias-audit

Audit de Biais

Aperçu

Le biais dans les données d'entraînement produit des modèles biaisés, un point c'est tout. Cet audit mesure la représentation, les disparités de résultats et les lacunes intersectionnelles pour que vous puissiez corriger les problèmes avant l'entraînement.

Quand l'Utiliser

Utilisez-le quand : vous construisez des modèles qui prennent des décisions concernant les personnes, vous déployez dans des domaines réglementés, ou quand des attributs protégés (genre, race, âge, etc.) sont disponibles.

Métriques Essentielles

Audit de Représentation

import pandas as pd
import numpy as np

def representation_audit(df, protected_cols, population_benchmark=None):
    """Check if dataset representation matches population."""
    n = len(df)
    results = {}

    for col in protected_cols:
        dist = df[col].value_counts(normalize=True).to_dict()
        results[col] = {
            "distribution": dist,
            "n_groups": len(dist),
            "min_group_pct": min(dist.values()),
            "max_group_pct": max(dist.values()),
            "imbalance_ratio": max(dist.values()) / (min(dist.values()) + 1e-10),
        }

    # Intersectional audit
    if len(protected_cols) >= 2:
        intersectional = df.groupby(protected_cols).size() / n
        min_intersection = intersectional.min()
        results["intersectional"] = {
            "n_intersections": len(intersectional),
            "min_pct": min_intersection,
            "empty_groups": (intersectional == 0).sum(),
        }

    return results

Audit de Parité des Résultats

def outcome_audit(df, label_col, protected_col, positive_label=1):
    """Check if outcomes differ across protected groups."""
    groups = df.groupby(protected_col)

    metrics = {}
    for group, data in groups:
        metrics[group] = {
            "n": len(data),
            "positive_rate": (data[label_col] == positive_label).mean(),
            "label_distribution": data[label_col].value_counts().to_dict(),
        }

    # Disparity metrics
    pos_rates = [m["positive_rate"] for m in metrics.values()]
    disparity = max(pos_rates) - min(pos_rates)

    return {
        "per_group": metrics,
        "max_disparity": disparity,
        "disparity_ratio": max(pos_rates) / (min(pos_rates) + 1e-10),
    }

Seuils Importants

Métrique Vert Jaune Rouge
Ratio de taille de groupe (max/min) < 3:1 3:1-10:1 > 10:1
Disparité de résultats < 5pp 5-15pp > 15pp
Groupe d'intersection minimum > 1% 0,1-1% < 0,1%

Plan de Remédiation

  1. Groupes sous-représentés : Suréchantillonnez, collectez plus de données, ou utilisez l'augmentation synthétique.
  2. Disparité de résultats : Vérifiez si la qualité des labels diffère selon les groupes. Vérifiez si la définition des labels est biaisée.
  3. Lacunes intersectionnelles : Signalez-les même si vous ne pouvez pas les corriger — ne cachez pas les cellules à zéro.
  4. Documentez : Ce que vous avez mesuré, ce que vous avez trouvé, ce que vous en avez fait. La transparence est le strict minimum.

Skills similaires