Fair-Seldonian
Fairness-constrained machine learning with high-confidence guarantees
A Python framework implementing the Quasi-Seldonian Algorithm (QSA) for training ML models that provably satisfy fairness constraints. Given a behavioral constraint and a confidence level δ, the algorithm either returns a model satisfying the constraint with probability ≥ 1 − δ, or returns No Solution Found — never an unsafe model.
Built on the Seldonian algorithm framework by Thomas et al. (2019), with extensions for tighter confidence bounds through constant-aware delta allocation, union bound optimization, and decomposed candidate-safety intervals.
Quick links
| Documentation | parulgupta1004.github.io/fair-seldonian |
| Repository | github.com/parulgupta1004/fair-seldonian |
| Example notebook | examples/quickstart.ipynb |
| Paper | Thomas et al., Science 366 (2019) — doi:10.1126/science.aag3311 |
Installation
git clone https://github.com/parulgupta1004/fair-seldonian.git
cd fair-seldonian
uv sync # core dependencies
uv sync --extra experiments # + Ray for parallel experiments
uv sync --extra plots # + matplotlib for visualization
uv sync --extra notebook # + JupyterLab to run examples/quickstart.ipynb
Or with pip:
pip install fair-seldonian
pip install "fair-seldonian[notebook]" # JupyterLab + matplotlib to run the quickstart
pip install "fair-seldonian[experiments,plots]"
Usage
from fair_seldonian.algorithms import QSA
from fair_seldonian.models import eval_ghat
from fair_seldonian.data import get_data, data_split
data = get_data(N=10000, features=5, t_ratio=0.4,
tp0_ratio=0.4, tp1_ratio=0.6, random_seed=42)
X_te, Y_te, T_te, X_tr, Y_tr, T_tr = data_split(
frac=0.5, all_data=data, random_state=1, m_test=0.2)
theta, theta1, passed = QSA(X_tr, Y_tr, T_tr, "opt", None, None)
if passed:
print("Upper bound:", eval_ghat(theta, theta1, X_te, Y_te, T_te, "opt"))
else:
print("No Solution Found")
Custom configuration:
from fair_seldonian.config import SeldonianConfig
from fair_seldonian.constraints.inequalities import Inequality
config = SeldonianConfig(delta=0.01, inequality=Inequality.T_TEST, candidate_ratio=0.5)
theta, theta1, passed = QSA(X_tr, Y_tr, T_tr, "opt", None, None, config)
Built-in fairness constraints:
Common fairness definitions ship as ready-to-use builders — no need to write the
postfix constraint string by hand. Each takes a tolerance epsilon; the parity
builders also take the two sensitive-attribute values to compare (default
("1", "0")):
from fair_seldonian import SeldonianConfig, demographic_parity
config = SeldonianConfig(constraint=demographic_parity(epsilon=0.1))
| Builder | Bounds (<= epsilon) |
|---|---|
demographic_parity |
gap in predicted-positive rate (statistical parity) |
equal_opportunity |
gap in true-positive rate |
equalized_odds |
combined true- and false-positive-rate gaps |
error_rate |
one group's misclassification rate |
error_rate_parity |
gap in misclassification rate (overall accuracy equality) |
See the Fairness constraints docs for definitions and references.
Examples
A runnable, end-to-end walkthrough lives in examples/quickstart.ipynb:
- generating synthetic data with a controllable fairness gap
- training with QSA and reading the high-confidence safety guarantee
- contrasting fair data (model certified) with unfair data (No Solution Found)
- decoding and customizing the postfix constraint,
delta, and inequality - comparing the five algorithm variants side by side
- visualizing accuracy vs. the certified fairness bound, with and without QSA, on the same dataset
Install the notebook dependencies and launch it with:
pip install "fair-seldonian[notebook]"
jupyter lab examples/quickstart.ipynb
View it rendered on nbviewer, or in the documentation's Examples section.
Prefer plain scripts? The examples/ directory has runnable .py
versions — quickstart.py, fairness_guarantee.py, and custom_constraint.py —
plus real_world_adult.ipynb, a notebook that
applies QSA to the UCI Adult income dataset (with saved outputs so the results
render on GitHub). All are described in examples/README.md:
uv run python examples/quickstart.py
Algorithm variants
| Mode | Description |
|---|---|
base |
Standard Hoeffding bound, uniform δ-splitting |
mod |
Decomposed candidate/safety estimation error |
const |
Constant-aware δ allocation |
bound |
Union bound optimization for repeated variables |
opt |
All optimizations combined |
uv run python -m fair_seldonian.experiments.runner opt
uv run python -m fair_seldonian.experiments.plots
Citation
@software{fair_seldonian,
author = {Parul Gupta},
title = {Fair Seldonian Framework},
year = {2020}
}
This work builds on:
Thomas, P.S., da Silva, B.C., Barto, A.G., Giguere, S., Brun, Y., & Brunskill, E. (2019). "Preventing undesirable behavior of intelligent machines." Science, 366(6468), 999–1004.
Contributing
Contributions are welcome! Please see CONTRIBUTING.md for guidelines, or open an issue to get started.
Contributors
Thanks to everyone who has contributed to this project!
License
Author: Parul Gupta
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file fair_seldonian-3.1.0.tar.gz.
File metadata
- Download URL: fair_seldonian-3.1.0.tar.gz
- Upload date:
- Size: 61.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a5f8c660087266965503efeb71e73cd4fee5431d69ed3c535dd3a46932914017
|
|
| MD5 |
e3def5f4370b6f980fd6d8edc3f1b3e2
|
|
| BLAKE2b-256 |
e304e3d481ca402c17cfe85ef4593c9378958b81bcb13d4a774f3f8eff64d399
|
Provenance
The following attestation bundles were made for fair_seldonian-3.1.0.tar.gz:
Publisher:
publish.yml on parulgupta1004/fair-seldonian
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
fair_seldonian-3.1.0.tar.gz -
Subject digest:
a5f8c660087266965503efeb71e73cd4fee5431d69ed3c535dd3a46932914017 - Sigstore transparency entry: 2283223904
- Sigstore integration time:
-
Permalink:
parulgupta1004/fair-seldonian@a871518064b54d156a256b27de3e44c7353a7c27 -
Branch / Tag:
refs/tags/v3.1.0 - Owner: https://github.com/parulgupta1004
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@a871518064b54d156a256b27de3e44c7353a7c27 -
Trigger Event:
push
-
Statement type:
File details
Details for the file fair_seldonian-3.1.0-py3-none-any.whl.
File metadata
- Download URL: fair_seldonian-3.1.0-py3-none-any.whl
- Upload date:
- Size: 31.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c111774f4809b5f777e5adb8406ce71ac5fbaa6a2b633d73fb7664b3fcb3711f
|
|
| MD5 |
a8c57d3b4cc344f9d22ea7e11976e416
|
|
| BLAKE2b-256 |
a35f2072c5e9d8b529deaef6c3b97d12ee2bf65cc2fc411c8de8e04fa3920522
|
Provenance
The following attestation bundles were made for fair_seldonian-3.1.0-py3-none-any.whl:
Publisher:
publish.yml on parulgupta1004/fair-seldonian
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
fair_seldonian-3.1.0-py3-none-any.whl -
Subject digest:
c111774f4809b5f777e5adb8406ce71ac5fbaa6a2b633d73fb7664b3fcb3711f - Sigstore transparency entry: 2283223988
- Sigstore integration time:
-
Permalink:
parulgupta1004/fair-seldonian@a871518064b54d156a256b27de3e44c7353a7c27 -
Branch / Tag:
refs/tags/v3.1.0 - Owner: https://github.com/parulgupta1004
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@a871518064b54d156a256b27de3e44c7353a7c27 -
Trigger Event:
push
-
Statement type: