CertIFI: Certifiably Intersectionally Fair & Interpretable models
certifi-learn finds the most biased subgroup in data or in a model's predictions,
and trains interpretable classifiers (linear models and rule sets) that are
certifiably fair on all intersectional subgroups, for example all combinations
of sex, race and age group.
Features
-
Bias detection. Find the subgroup with the largest violation of
- Subgroup Discrepancy / MSD,
- Statistical Parity Subgroup Fairness (SPSF),
- False Positive Subgroup Fairness (FPSF).
Subgroups can be
- conjunctions of protected attribute values (e.g.
SEX = Female AND RAC1P = Black). The exact search is fast, needs no solver, and its result is proven optimal. - linear threshold functions of the protected attributes, found by MIO.
-
Fair training. Linear classifiers and DNFs (rule sets), trained to optimality under the constraint that every subgroup has bias at most γ. Fairness constraints are generated lazily: only the subgroups that are actually violated are added, so there's no need to enumerate the exponentially many subgroups.
-
A scikit-learn-style API that works with pandas DataFrames. Categorical features are encoded automatically.
Installation
pip install "certifi-learn[gurobi]"
Prebuilt wheels are available for Linux, macOS and Windows (Python 3.9+). To install the latest version from GitHub instead, you need a Rust toolchain:
pip install "certifi-learn[gurobi] @ git+https://github.com/Epanemu/CertIFI"
Optional dependencies (extras):
| Extra | Needed for |
|---|---|
gurobi |
Training classifiers (Gurobi lazy-constraint callbacks) and MIO detection. Requires a Gurobi license, free for academic use. |
highs |
MIO detection with the open-source HiGHS solver, an alternative to Gurobi |
mio |
Pyomo only, if you bring your own solver installation |
examples |
The folktables example |
Bias detection on conjunction subgroups needs no extras.
Quickstart
Finding the most biased subgroup
from certifi_learn import find_subgroup
from certifi_learn.encoding import TabularEncoder
# protected: DataFrame of protected attributes, y: binary labels, y_pred: model predictions
enc = TabularEncoder(protected) # binarizes into literals like "SEX = Female"
P = enc.binary(protected, negations=False)
names = enc.binary_names(negations=False)
# bias in the data: subgroup whose share differs most between positive and negative labels
sg = find_subgroup(P, y, measure="msd")
print(f"MSD = {sg.value:.3f}, proven optimal: {sg.optimal}")
print(sg.describe(names))
# e.g., on ACS Income (examples/detect_and_train.py):
# MSD = 0.194, proven optimal: True
# AGEP between [17, 24.2)
# certify that no subgroup has bias above a threshold
sg = find_subgroup(P, y, measure="msd", gamma=0.25) # None: no subgroup has MSD > 0.25
# bias of a classifier
sg = find_subgroup(P, y_pred, measure="fpsf", y_true=y)
# also allow negated literals, e.g. "NOT RAC1P = White"
sg = find_subgroup(P, y_pred, measure="spsf", negations=True)
# linear subgroups (MIO, requires a solver)
sg = find_subgroup(P, y_pred, measure="spsf", subgroups="linear", solver="highs", time_limit=300)
find_subgroup returns a DetectedSubgroup with the violation value (of the
chosen measure, on the given data), the membership mask, optimal (whether the subgroup is proven to be the most biased),
and describe() / contains(X_new). If you pass gamma=..., it returns a subgroup
only if one violates the threshold, and None otherwise. That None certifies
γ-fairness, unless a warning reports that the search was stopped by the time limit.
Training a fair classifier
from certifi_learn import FairLinearClassifier, FairDNFClassifier
clf = FairLinearClassifier(gamma=0.01, measure="fpsf", time_limit=600)
clf.fit(X, y, X_protected) # X may include the protected attributes
y_pred = clf.predict(X_test)
print(clf.n_cuts_) # number of subgroups constrained during training
print(clf.describe_cut_subgroups()) # which ones
rules = FairDNFClassifier(n_terms=3, gamma=0.01, measure="fpsf").fit(X, y, X_protected)
print(rules.describe())
Common parameters:
| Parameter | Values |
|---|---|
measure |
"fpsf", "fpsf_by_sd" (FPSF constraints, with violating subgroups found by maximizing Subgroup Discrepancy on negative samples), "spsf", "msd", or None (no fairness constraint) |
subgroups |
"conjunction" or "linear" |
subgroup_negations |
Also allow negated literals in conjunction subgroups (e.g. RAC1P != White), which constrains a larger set of subgroups. Default False. |
gamma |
Fairness threshold. Every subgroup must have bias ≤ γ on the training data. |
detection_backend |
"exact" (default) or "mio", for finding violating conjunction subgroups. Linear subgroups always use MIO. |
time_limit |
Solver time limit in seconds. The best solution found so far is returned. |
Model-specific parameters:
| Model | Parameter | Values |
|---|---|---|
FairLinearClassifier |
sparsity |
Weight of the penalty on the proportion of non-zero coefficients (default 0) |
FairDNFClassifier |
n_terms |
Number of terms (rules) of the DNF (default 3) |
γ-fairness is guaranteed on the training data. On new data, the bias can be
somewhat higher. Audit your model on held-out data with find_subgroup.
Bias measures
For a classifier h and a subgroup S:
| Measure | Definition |
|---|---|
| SPSF | P(S) · |P(h=1) − P(h=1 | S)| |
| FPSF | P(S, y=0) · |P(h=1 | y=0) − P(h=1 | S, y=0)| |
| SD / MSD | |P(S | y=1) − P(S | y=0)|, i.e. how differently S is represented among positive and negative samples. Maximized over conjunctions, this is the Maximum Subgroup Discrepancy. |
certifi_learn.measures evaluates these for a given subgroup mask.
certifi_learn.exact exposes the Rust search directly (msd, spsf, fpsf), with
options such as sample weights, negated literals and grouped one-hot columns. See
docs/subgroup_pruning_proof.tex for the
algorithm and its proof of correctness.
Example
examples/detect_and_train.py runs end to end on
the US Census data (ACS Income, via folktables).
It finds the most biased subgroup in the data, trains an unconstrained and a fair
linear model, and audits both on test data:
pip install "certifi-learn[gurobi,examples]"
python examples/detect_and_train.py
Development
pip install -e ".[gurobi,highs,test,examples]" # builds the Rust extension
pytest
Tests that need HiGHS or a Gurobi license are skipped if those are not available.
Citation
@inproceedings{nemecek2026intersectional,
author = {N\v{e}me\v{c}ek, Ji\v{r}\'{\i} and Kozdoba, Mark and Kryvoviaz, Illia and Pevn\'{y}, Tom\'{a}\v{s} and Mare\v{c}ek, Jakub},
booktitle = {Advances in Neural Information Processing Systems},
title = {Intersectional Fairness via Mixed-Integer Optimization},
volume = {39, Main Conference},
year = {2026}
}
License
Metadata
Release files for certifi-learn 0.2.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| certifi_learn-0.2.1.tar.gz | 68.3 kB | With provenance | Details for certifi_learn-0.2.1.tar.gz |
Built distributions (wheels)
| File | Actions Reset | |||
|---|---|---|---|---|
| certifi_learn-0.2.1-cp39-abi3-win_amd64.whl | CPython 3.9 | abi3 | Windows x86-64 | Details for certifi_learn-0.2.1-cp39-abi3-win_amd64.whl |
| certifi_learn-0.2.1-cp39-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl | CPython 3.9 | abi3 | Linux glibc 2.17+ x86-64 | Details for certifi_learn-0.2.1-cp39-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl |
| certifi_learn-0.2.1-cp39-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl | CPython 3.9 | abi3 | Linux glibc 2.17+ ARM64 | Details for certifi_learn-0.2.1-cp39-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl |
| certifi_learn-0.2.1-cp39-abi3-macosx_11_0_arm64.whl | CPython 3.9 | abi3 | macOS 11.0+ ARM64 | Details for certifi_learn-0.2.1-cp39-abi3-macosx_11_0_arm64.whl |
| certifi_learn-0.2.1-cp39-abi3-macosx_10_12_x86_64.whl | CPython 3.9 | abi3 | macOS 10.12+ x86-64 | Details for certifi_learn-0.2.1-cp39-abi3-macosx_10_12_x86_64.whl |
Total release size: 1.4 MB
Release files / certifi_learn-0.2.1.tar.gz
| Download URL | certifi_learn-0.2.1.tar.gz |
|---|---|
| Size | 68.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
0acd51f3e725a613f6514353cd2658998797aea87d746d4ae8f4927059805544
|
|
BLAKE2b-256 checksum How to use checksums |
ae5aa65e7620a27ea4891a95400f6f32392057122d3429d6e69748dd0729cede
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 4, 2026.
Transparency logRelease files / certifi_learn-0.2.1-cp39-abi3-win_amd64.whl
| Download URL | certifi_learn-0.2.1-cp39-abi3-win_amd64.whl |
|---|---|
| Size | 198.8 kB |
| Tags | CPython 3.9 Windows x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
4c62ef666ab45b4081423768321bcb4c9fbc04e8fc4f337e5b1bbb9167b1532b
|
|
BLAKE2b-256 checksum How to use checksums |
7b2f3621e76621464b6ef42ef59606fe5d89ceb5c38f30777397025e56f638ad
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 4, 2026.
Transparency logRelease files / certifi_learn-0.2.1-cp39-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl
| Download URL | certifi_learn-0.2.1-cp39-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl |
|---|---|
| Size | 301.3 kB |
| Tags | CPython 3.9 Linux glibc 2.17+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
a5e3cfc8a68938168812c767e008caa9bcae0f8b3762947331a5eacecdd23329
|
|
BLAKE2b-256 checksum How to use checksums |
8e37efb6fa6eeccd6bdfc659bfc2505be34028663f0c33fff0601b4adad956d7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 4, 2026.
Transparency logRelease files / certifi_learn-0.2.1-cp39-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl
| Download URL | certifi_learn-0.2.1-cp39-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl |
|---|---|
| Size | 300.3 kB |
| Tags | CPython 3.9 Linux glibc 2.17+ ARM64 abi3 |
|
SHA-256 checksum How to use checksums |
569b88421140db2609a1e52ee5595cc21d382dd1e3ce96f43c7daba72028b04e
|
|
BLAKE2b-256 checksum How to use checksums |
3453fc1809433f46736fcf8cf35fc3018943dc6c74380f0f0333cc8d44debdf6
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 4, 2026.
Transparency logRelease files / certifi_learn-0.2.1-cp39-abi3-macosx_11_0_arm64.whl
| Download URL | certifi_learn-0.2.1-cp39-abi3-macosx_11_0_arm64.whl |
|---|---|
| Size | 284.9 kB |
| Tags | CPython 3.9 abi3 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
f36d6f8428606404cc071418834e34c09f5b04c4b8094413a4257052061be487
|
|
BLAKE2b-256 checksum How to use checksums |
2d7b1987e92044be9ecb377c8a9114376f9ec287023997b514834fa68e2d4597
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 4, 2026.
Transparency logRelease files / certifi_learn-0.2.1-cp39-abi3-macosx_10_12_x86_64.whl
| Download URL | certifi_learn-0.2.1-cp39-abi3-macosx_10_12_x86_64.whl |
|---|---|
| Size | 293.5 kB |
| Tags | CPython 3.9 abi3 macOS 10.12+ x86-64 |
|
SHA-256 checksum How to use checksums |
390c03a34cf7434783b5a1434f4190692cfd26bf84eae3597805f839e911ea49
|
|
BLAKE2b-256 checksum How to use checksums |
53aec10541360fe5a576c3d3b463aac859659abf97fa32cf50b4bd95920e82d7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 4, 2026.
Transparency logSecurity for certifi-learn 0.2.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 6 files in this release have been uploaded with provenance metadata.
Attestation for certifi_learn-0.2.1.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 4, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.