Library / SDK
dssg/aequitas avatar
dssg/aequitas

Aequitas, a bias auditing toolkit for binary classifiers and Fair ML experiments

Bias Auditing & Fair ML Toolkit

777 stars128 forksPythonMIT

At a glance

What is it?
dssg/aequitas measures disparate impact across sensitive attributes in a pandas dataframe and, since version 1.0, adds Aequitas Flow for running fairness experiments with pre-processing, in-processing and post-processing methods. The audit side is lightweight and the experimental side pulls in torch, fairlearn, fairgbm and aif360.
Who is it for?
Adopt Aequitas when you need a repeatable fairness audit of a binary classifier and a way to compare mitigation methods on the same data, especially in policy or public sector settings where the audit has to be documented. Skip it if your task is multi-class prediction, ranking fairness, or text and image fairness, since the toolkit is scoped to binary classification with categorical sensitive attributes.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 164 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What a bias audit in Aequitas actually requires of your data

Aequitas is an open source bias auditing and Fair ML toolkit from the Center for Data Science and Public Policy, aimed at data scientists, machine learning researchers and policymakers. The README describes it as an easy-to-use and transparent tool for auditing predictors of ML models and for experimenting with correcting biased models in binary classification settings.

The audit entry point is deliberately plain. You need a pandas DataFrame with three kinds of column: label_value as the target variable, score as the model output, and one or more sensitive attributes named sens_attr_1, sens_attr_2 and so on. The README's table shows the shape with example rows of a label and a score plus categorical values in the sensitive columns.

Two constraints are stated and worth honouring. Only one sensitive attribute is required, so you can audit a single dimension without having everything, and all sensitive attributes must be in categorical format. That second point is a real limitation rather than a formality: a continuous sensitive attribute such as income or age has to be binned before the audit means anything, and the choice of bins is yours, which puts an interpretive decision outside the tool.

The audit itself is two lines:

python
from aequitas import Audit

audit = Audit(df)

and the summary is a call that names the metrics you care about:

python
audit.summary_plot(["tpr", "fpr", "pprev"])

A single metric against a single attribute is also available, which is the shape most reports end up using:

python
audit.disparity_plot(attribute="sens_attr_2", metrics=["fpr"])

Aequitas Flow and the DefaultExperiment entry point

Version 1.0.0 introduced Aequitas Flow, which the README describes as augmenting bias audits with bias mitigation and allowing experimentation with Fair ML methods. Where the audit tells you a disparity exists, Flow is the part that tries candidate mitigations and lets you compare them.

The easy entry point is DefaultExperiment. A dataset is required, with a label column, a sensitive attribute column and features:

python
from aequitas.flow import DefaultExperiment

experiment = DefaultExperiment.from_pandas(dataset, target_feature="label_value", sensitive_feature="attr", experiment_size="small")
experiment.run()

experiment.plot_pareto()

Two parameters shape the run. The experiment_size decides how many models per method are trained, with four documented values: test for 1 model per method, small for 10, medium for 50 and large for 100. The methods parameter selects all methods or a subset, namely preprocessing or inprocessing.

The choice of size is the practical knob. A test-sized run is a smoke check that the pipeline wires together, while a large run at 100 models per method is what you need before believing a comparison, and the compute cost scales accordingly. The README notes that finer aspects such as the algorithms, the number of runs and the dataset splitting are configurable in more granular detail through the lower level Experiment class.

The pareto plot is the output to look at. Fairness and performance trade off against each other, so the interesting question is not which method is best on one metric but which methods sit on the frontier, and a plot is a better way to read that than a table of scores.

The three method families and their fit-transform shape

Flow organizes mitigation into the standard three places you can intervene in a machine learning pipeline, and each has its own API.

Pre-processing methods change the data before training. The example is PrevalenceSampling, which fits on the training split and returns a resampled triple:

python
from aequitas.flow.methods.preprocessing import PrevalenceSampling

sampler = PrevalenceSampling()
sampler.fit(dataset.train.X, dataset.train.y, dataset.train.s)
X_sample, y_sample, s_sample = sampler.transform(dataset.train.X, dataset.train.y, dataset.train.s)

In-processing methods change the learner itself. FairGBM is a gradient boosting variant that takes the same three arrays:

python
from aequitas.flow.methods.inprocessing import FairGBM

model = FairGBM()
model.fit(X_sample, y_sample, s_sample)
scores_val = model.predict_proba(dataset.validation.X, dataset.validation.y, dataset.validation.s)
scores_test = model.predict_proba(dataset.test.X, dataset.test.y, dataset.test.s)

Post-processing methods change the decision rule after scores exist. BalancedGroupThreshold is fitted on a validation split and then produces corrected scores:

python
from aequitas.flow.methods.postprocessing import BalancedGroupThreshold

threshold = BalancedGroupThreshold("top_pct", 0.1, "fpr")
threshold.fit(dataset.validation.X, scores_val, dataset.validation.y, dataset.validation.s)

Note the split discipline that the API implies. The pre-processing sampler and the in-processing model are fitted on train, the post-processing threshold is fitted on validation, and the test split is only used for scoring. That ordering is the difference between a mitigation that generalises and one that has overfitted the group structure.

The optional flow dependency group lists torch, optuna, aif360, lightgbm, fairgbm, fairlearn and hydra-core, plus a hyperparameter-tuning package. So Flow is where the heavy dependencies live, and installing it means accepting torch into your environment.

Package structure, optional extras and the web app

The core package is small in dependency terms. The main requirement list is matplotlib, pandas, pyyaml, seaborn, altair, scipy, validators, numpy, fastparquet and requests, and the build backend is hatchling. The pyproject.toml declares the version as 1.1.0, requires Python 3.10 up to but not including 3.14, and classifies the project as Production/Stable for development status.

There are two optional extras beyond flow. The cli extra pulls in sqlalchemy, tabulate, xhtml2pdf, ohio and markdown2, which suggests the CLI can write reports to a database and render them to PDF. The webapp extra is flask with flask-bootstrap, and the repository carries serve.py, manage.py, a Dockerfile and .ebextensions and .elasticbeanstalk directories, so there is a web application and an Elastic Beanstalk deployment path for it.

The examples directory shows the shape of a worked case. compas_data_for_aequitas.py prepares the COMPAS recidivism dataset, nyc_sqf_data_for_aequitas.py does the same for New York stop-and-frisk data, and there are directories for configs, data, experiment results, methods and raw_data.

That example choice is telling. Both COMPAS and stop-and-frisk are the datasets where fairness disputes have been concrete and public, and the companion tutorial at dssg.github.io/fairness_tutorial and the linked publications are where the methodological argument lives.

The notebooks are published as Colab links so the workflow can be run without setting up an environment, and one of them is specifically about adding your own method to Aequitas Flow, which is the extension path if the built-in methods do not cover your case.

Where Aequitas fits, and what it will not tell you

The honest scope statement is binary classification with categorical sensitive attributes. Multi-class prediction, ranking or recommendation fairness, and fairness in text or image models are outside what the tool measures, and a team that needs those should not read a clean Aequitas report as coverage.

The second limitation is interpretive rather than technical. Every fairness metric expresses a trade-off between a group's outcomes, and choosing which metric to optimise is a policy decision with a normative edge that no library can make for you. The audit will happily report true positive rate, false positive rate and prevalence disparity for every attribute, and choosing among them, and setting a threshold for acceptable disparity, is work that stays with you. The BalancedGroupThreshold signature, which names a metric explicitly as its third argument, makes that choice visible in the code.

The third limitation is a mismatch between the audit and the deployment. Aequitas measures a model's predictions on a dataset, and the group categories you supply define who is being compared. If your sensitive attributes are coarse, or if the intersectional groups that matter most are missing because the categories are not crossed, the report will be cleaner than reality.

The alternative in the same space is fairlearn, which also ships metrics and mitigation methods and is one of the packages in Flow's own optional dependencies. The difference in approach is that Aequitas wraps fairness work as an audit-then-experiment pipeline with plots and reports aimed at documentation and policy audiences, while fairlearn is a set of estimators and metrics you compose yourself. If your requirement is a documented audit that a reviewer can read, Aequitas is the closer fit. If you want the primitives inside your own modelling code, fairlearn is the simpler dependency.

Editorial conclusion

Adopt Aequitas when you need a repeatable fairness audit of a binary classifier and a way to compare mitigation methods on the same data, especially in policy or public sector settings where the audit has to be documented. Skip it if your task is multi-class prediction, ranking fairness, or text and image fairness, since the toolkit is scoped to binary classification with categorical sensitive attributes. Verify first by loading your own dataframe in the documented label_value, score and sens_attr format and running audit.summary_plot, and check that the sensitive attributes you care about are represented in the categories your data actually uses.

Frequently asked questions

What columns does my dataframe need for an Aequitas bias audit?

The audit needs a label_value column holding the target variable, a score column holding the model output, and at least one sensitive attribute column named sens_attr_1 and so on. Only one sensitive attribute is required, and all of them must be in categorical format.

How do I run a fairness audit with Aequitas?

Create an Audit with the dataframe and then request a summary for the metrics of interest, for example audit.summary_plot(["tpr", "fpr", "pprev"]). A single metric against one attribute is available through audit.disparity_plot(attribute="sens_attr_2", metrics=["fpr"]).

What does the experiment_size option control in Aequitas Flow?

It sets how many models are trained per method: test means 1 model per method, small means 10, medium means 50 and large means 100. The methods parameter separately selects all methods or a subset of preprocessing or inprocessing.

What is the difference between Aequitas pre-processing, in-processing and post-processing methods?

Pre-processing methods transform the data before training, in-processing methods change the learner itself, and post-processing methods adjust the decision rule after scores are produced. Each type has its own class in aequitas.flow.methods with a fit and transform or predict interface.

What Python versions and dependencies does Aequitas support?

The pyproject.toml requires Python 3.10 up to but not including 3.14 and lists classifiers for 3.10 through 3.13. The core install needs pandas, numpy, matplotlib, seaborn, altair, scipy and similar, while the flow extra adds torch, optuna, aif360, fairgbm and fairlearn.

Official sources

  1. dssg/aequitas on GitHub
  2. Issues
  3. License: MIT
  4. Project website
  5. README
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/dssg-aequitas.svg)](https://hysenlabs.com/projects/dssg-aequitas)

Was this useful?