Methodology¶
This document defines every metric EthicLens computes, the statistical machinery around it, and — most importantly — the methodological correction the project makes over its original specification.
The flaw we fixed¶
The original System Test Plan (original-stp.pdf) proposed to audit a model
by feeding it synthetic demographic personas and computing fairness metrics on the resulting
predictions. This cannot work:
- Synthetic personas have no ground-truth label
Y. Every error-based metric the spec names (Equalized Odds, Equal Opportunity, predictive parity, calibration) is therefore mathematically uncomputable on that data. - Because the demographic distribution is authored by the tester (
config), the measured "selection rate" reflects sampling choices and out-of-distribution model behaviour, not real-world disparate impact.
The fix¶
- Audit on real, labelled benchmarks with known protected attributes and true outcomes — Folktables/ACSIncome (primary), COMPAS, German Credit.
- Repurpose the Synthetic Profile Generator into two legitimate roles:
- Counterfactual probing — flip only the protected attribute on real records and measure the change in prediction (an individual-fairness signal; Dwork 2012, Kusner 2017).
- A bias-injection oracle — manufacture data with a known disparate impact to verify that the engine recovers it (the golden-reference test).
- Report uncertainty — bootstrap CIs, significance tests, minimum-subgroup floors on both comparison groups — and flag only statistically supported threshold violations.
Notation¶
Privileged group a = 1, unprivileged a = 0. Prediction Ŷ, ground truth Y,
selection rate r_a = P(Ŷ = 1 | A = a).
Group metrics¶
| Metric | Definition | Needs Y? |
Library check |
|---|---|---|---|
| Disparate Impact | r_0 / r_1 |
no | fairlearn.demographic_parity_ratio |
| Statistical Parity Difference | r_0 − r_1 |
no | fairlearn.demographic_parity_difference |
| Equalized Odds (difference) | max(\|TPR_1−TPR_0\|, \|FPR_1−FPR_0\|) |
yes | fairlearn.equalized_odds_difference |
| Equal Opportunity | \|TPR_1 − TPR_0\| |
yes | derived from MetricFrame |
| Predictive Parity | \|PPV_1 − PPV_0\| |
yes | derived from MetricFrame |
| FPR balance | \|FPR_1 − FPR_0\| |
yes | derived from MetricFrame |
| Calibration / ECE | binned \|accuracy − confidence\| |
yes | from scratch |
| Theil index | generalised entropy of the benefit vector | yes | from scratch |
Every from-scratch implementation is asserted equal to Fairlearn within 1e-9 in
test_vs_fairlearn.py.
That equality is the project's correctness proof.
Disparate Impact and the 4/5ths rule¶
calculate_disparate_impact(privileged_rate, unprivileged_rate) returns r_0 / r_1, raising
ValueError when r_1 == 0. A value below 0.80 is evidence of adverse impact (EEOC Uniform
Guidelines on Employee Selection Procedures, 1978).
The impossibility theorem (why we surface PPV and FPR)¶
When base rates differ between groups, predictive parity and equalized odds cannot both hold (Chouldechova 2017; Kleinberg, Mullainathan & Raghavan 2016). EthicLens shows PPV and FPR side by side on COMPAS precisely so this trade-off is visible rather than hidden behind a single metric.
Worked example: COMPAS¶
Auditing a recidivism model on the real COMPAS data (python -m ml.cli.audit_dataset compas), the
engine measures a false-positive rate of 0.24 for African-American vs 0.11 for Caucasian
defendants — Black defendants who did not reoffend are labelled high-risk about twice as
often (the ProPublica 2016 finding), with reasonably similar PPV. The base rates differ
(≈ 0.54 vs 0.37), so by the impossibility theorem the two cannot be equalised at once.
Crucially, Disparate Impact alone misses this: recidivism is an adverse outcome that is
over-assigned to the unprivileged group, and the 4/5ths rule only catches under-selection. So
EthicLens flags a group when either its DI confidence interval is below 0.80 or its
Equalized-Odds CI lower bound exceeds 0.10 — covering both favorable-outcome (hiring/lending) and
adverse-outcome (risk-scoring) decisions. On COMPAS this correctly flags race:African-American
via Equalized Odds even though its DI (≈ 2.5) sails past the selection-rate rule.
Composite Bias Score¶
A 0–1 fairness-goodness score (higher = fairer). Each component is normalised to a sub-score, then weighted:
g_DI = min(DI, 1/DI) # symmetric; 1.0 at parity; clamps the favoured-flip case
g_SPD = 1 − min(|SPD|, 1)
g_EO = 1 − min(|EO|, 1)
Composite = clamp(0.40·g_DI + 0.35·g_SPD + 0.25·g_EO, 0, 1)
Bands: < 0.60 High Risk, < 0.80 Medium Risk, ≥ 0.80 Low Risk. Worked example (the value
pinned in TS-UNIT-004): compute_composite_bias_score(0.6, −0.25, 0.15) = 0.7150. The composite is withheld when any comparison lacks DI, SPD or Equalized Odds (including
predictions-only datasets without ground-truth labels). Missing EO is never silently set
to zero. The minimum DI headline is tracked separately and may still be
published if all cohort DI comparisons meet their sample floors and have
defined reference selection rates. If any DI comparison is underpowered,
the overall minimum DI is withheld rather than cherry-picking reliable groups.
The composite
is a triage convenience, not a legal standard — see Limitations.
The weighting rationale is recorded in adr/0001-composite-weights.md.
Statistical rigour¶
- Bootstrap confidence intervals — BCa (bias-corrected & accelerated) by default, percentile
on request. Acceleration uses a jackknife, skipped for very large subgroups (falling back to
bias-corrected percentile) and reported in the interval's
methodfield. No SciPy dependency: the normal CDF / inverse-CDF come fromstatistics.NormalDist. - Significance — a pooled two-proportion z-test on the selection-rate gap.
- Minimum subgroups — both the reference and comparison group require ≥ 100 for selection
rates; both groups require ≥ 30 positive and ≥ 30 negative labels for error
metrics. Below a floor the point estimate may still be shown descriptively but its
classification is
INSUFFICIENT_DATA. Undefined ratios have null values. - Flagging policy — a group is flagged when its DI confidence interval lies entirely below 0.80, or when its Equalized-Odds CI lower bound exceeds 0.10. This catches both selection-rate bias (hiring/lending) and error-rate bias (e.g. COMPAS, where the DI rule alone is blind). No fallback to a low-n point estimate or to a degenerate/missing CI is allowed to trigger a flag. A non-flagged comparison can still be inconclusive.
References¶
- Ammann, P., & Offutt, J. (2016). Introduction to Software Testing (2nd ed.).
- Barocas, Hardt, & Narayanan (2023). Fairness and Machine Learning. fairmlbook.org.
- Chouldechova, A. (2017). Fair prediction with disparate impact. Big Data, 5(2).
- Ding, Hardt, Miller, & Schmidt (2021). Retiring Adult: New Datasets for Fair ML. NeurIPS.
- Dwork, Hardt, Pitassi, Reingold, & Zemel (2012). Fairness Through Awareness. ITCS.
- Hardt, Price, & Srebro (2016). Equality of Opportunity in Supervised Learning. NeurIPS.
- Kleinberg, Mullainathan, & Raghavan (2016). Inherent Trade-Offs in Fair Determination of Risk.
- Mitchell et al. (2019). Model Cards for Model Reporting. FAccT.