Core Issues

Bias and Fairness

Understand how bias enters AI systems and techniques to measure and mitigate it.

Types of Bias in AI

Data Bias

The training data doesn't represent the real world accurately:

  • Historical bias: Past discrimination is reflected in data
  • Representation bias: Some groups are underrepresented
  • Measurement bias: Proxies for protected characteristics

Algorithmic Bias

The model amplifies or introduces disparities:

  • Feedback loops: Biased predictions create biased outcomes
  • Optimization bias: Optimizing for average hides group disparities

Fairness Definitions

Different mathematical definitions of fairness (and they can conflict):

  • Demographic parity: Equal positive rates across groups
  • Equal opportunity: Equal true positive rates
  • Equalized odds: Equal true/false positive rates
  • Individual fairness: Similar individuals treated similarly

Bias Mitigation Strategies

Pre-processing: Fix biased training data

In-processing: Add fairness constraints during training

Post-processing: Adjust model outputs to be fairer

Example

python
import numpy as np
from typing import Optional

# Measuring fairness metrics
def compute_fairness_metrics(
    predictions: list[int],
    ground_truth: list[int],
    group: list[str]  # "A" or "B"
) -> dict:
    """Compute key fairness metrics for binary classification"""
    metrics = {}

    for g in set(group):
        mask = [i for i, x in enumerate(group) if x == g]

        preds_g = [predictions[i] for i in mask]
        truth_g = [ground_truth[i] for i in mask]

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

        positive_rate = (tp + fp) / len(preds_g) if preds_g else 0
        true_positive_rate = tp / (tp + fn) if (tp + fn) > 0 else 0
        false_positive_rate = fp / (fp + tn) if (fp + tn) > 0 else 0

        metrics[g] = {
            "positive_rate": positive_rate,
            "true_positive_rate": true_positive_rate,
            "false_positive_rate": false_positive_rate,
            "count": len(preds_g)
        }

    return metrics

# Example: loan approval model
np.random.seed(42)
n = 200

ground_truth = np.random.binomial(1, 0.5, n).tolist()
groups = ["A"] * 100 + ["B"] * 100

# Biased model: group B has lower approval rate even controlling for merit
biased_predictions = [
    1 if (gt == 1 and random.random() < 0.9) or (gt == 0 and random.random() < 0.1)
    else 0
    for gt in ground_truth[:100]
] + [
    1 if (gt == 1 and random.random() < 0.6) or (gt == 0 and random.random() < 0.1)
    else 0
    for gt in ground_truth[100:]
]

import random
metrics = compute_fairness_metrics(biased_predictions, ground_truth, groups)

print("Fairness Audit Report")
print("=" * 40)
for group, m in metrics.items():
    print(f"
Group {group} (n={m['count']}):")
    print(f"  Approval rate: {m['positive_rate']:.1%}")
    print(f"  True positive rate: {m['true_positive_rate']:.1%}")
    print(f"  False positive rate: {m['false_positive_rate']:.1%}")

# Check demographic parity
rates = [m["positive_rate"] for m in metrics.values()]
disparity = max(rates) - min(rates)
print(f"
Demographic parity gap: {disparity:.1%}")
if disparity > 0.1:
    print("ALERT: Significant fairness concern detected (>10% gap)")
Try it yourself — PYTHON