Metadata-Version: 2.4
Name: fair-seldonian
Version: 3.0.0
Summary: Fairness-constrained machine learning using Seldonian algorithms with confidence bound optimizations
Project-URL: Homepage, https://github.com/parulgupta1004/fair-seldonian
Project-URL: Documentation, https://parulgupta1004.github.io/fair-seldonian/index.html
Project-URL: Repository, https://github.com/parulgupta1004/fair-seldonian
Project-URL: Issues, https://github.com/parulgupta1004/fair-seldonian/issues
Project-URL: Changelog, https://github.com/parulgupta1004/fair-seldonian/blob/master/CHANGELOG.md
Project-URL: Author, https://github.com/parulgupta1004
Author: Parul Gupta
License: MIT
License-File: LICENSE
Keywords: constraints,fairness,machine-learning,safety,seldonian
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Requires-Python: >=3.10
Requires-Dist: numpy>=1.23; python_version < '3.14'
Requires-Dist: numpy>=2.3.2; python_version >= '3.14'
Requires-Dist: pandas>=1.5; python_version < '3.14'
Requires-Dist: pandas>=2.3.3; python_version >= '3.14'
Requires-Dist: scikit-learn>=1.2; python_version < '3.14'
Requires-Dist: scikit-learn>=1.8.0; python_version >= '3.14'
Requires-Dist: scipy>=1.10; python_version < '3.14'
Requires-Dist: scipy>=1.16.1; python_version >= '3.14'
Requires-Dist: torch>=2.0; python_version < '3.14'
Requires-Dist: torch>=2.9.0; python_version >= '3.14'
Provides-Extra: dev
Requires-Dist: coverage>=7.6.1; extra == 'dev'
Requires-Dist: pytest-cov>=5.0; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Provides-Extra: experiments
Requires-Dist: ray; extra == 'experiments'
Provides-Extra: notebook
Requires-Dist: jupyterlab>=4.0; extra == 'notebook'
Requires-Dist: matplotlib; extra == 'notebook'
Provides-Extra: plots
Requires-Dist: matplotlib; extra == 'plots'
Description-Content-Type: text/markdown

# Fair-Seldonian

*Fairness-constrained machine learning with high-confidence guarantees*

[![PyPI](https://img.shields.io/pypi/v/fair-seldonian?logo=pypi&logoColor=white)](https://pypi.org/project/fair-seldonian/)
[![Python 3.10+](https://img.shields.io/badge/python-3.10%2B-blue?logo=python&logoColor=white)](https://www.python.org/downloads/)
[![Build](https://img.shields.io/github/actions/workflow/status/parulgupta1004/fair-seldonian/ci.yml?branch=master&label=build&logo=github)](https://github.com/parulgupta1004/fair-seldonian/actions)
[![codecov](https://codecov.io/gh/parulgupta1004/fair-seldonian/branch/master/graph/badge.svg)](https://codecov.io/gh/parulgupta1004/fair-seldonian)
[![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/parulgupta1004/fair-seldonian/blob/master/LICENSE)
[![Docs](https://img.shields.io/badge/docs-Sphinx-8CA1AF?logo=readthedocs&logoColor=white)](https://parulgupta1004.github.io/fair-seldonian/)
[![PyPI Downloads](https://static.pepy.tech/personalized-badge/fair-seldonian?period=total&units=INTERNATIONAL_SYSTEM&left_color=BLACK&right_color=GREEN&left_text=downloads)](https://pepy.tech/projects/fair-seldonian)
[![Paper](https://img.shields.io/badge/paper-Science%20(2019)-orange)](https://www.science.org/doi/10.1126/science.aag3311)

---

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 *&delta;*, the algorithm either returns a model satisfying the constraint with probability &ge; 1 &minus; *&delta;*, or returns **No Solution Found** — never an unsafe model.

Built on the Seldonian algorithm framework by [Thomas et al. (2019)](https://www.science.org/doi/10.1126/science.aag3311), 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](https://parulgupta1004.github.io/fair-seldonian/) |
| **Repository** | [github.com/parulgupta1004/fair-seldonian](https://github.com/parulgupta1004/fair-seldonian) |
| **Example notebook** | [examples/quickstart.ipynb](examples/quickstart.ipynb) |
| **Paper** | Thomas et al., *Science* 366 (2019) — [doi:10.1126/science.aag3311](https://www.science.org/doi/10.1126/science.aag3311) |

## Installation

```bash
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:

```bash
pip install fair-seldonian
pip install "fair-seldonian[notebook]"          # JupyterLab + matplotlib to run the quickstart
pip install "fair-seldonian[experiments,plots]"
```

## Usage

```python
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:**

```python
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)
```

## Examples

A runnable, end-to-end walkthrough lives in [`examples/quickstart.ipynb`](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:

```bash
pip install "fair-seldonian[notebook]"
jupyter lab examples/quickstart.ipynb
```

View it [rendered on nbviewer](https://nbviewer.org/github/parulgupta1004/fair-seldonian/blob/master/examples/quickstart.ipynb).

## Algorithm variants

| Mode | Description |
|------|-------------|
| `base` | Standard Hoeffding bound, uniform &delta;-splitting |
| `mod` | Decomposed candidate/safety estimation error |
| `const` | Constant-aware &delta; allocation |
| `bound` | Union bound optimization for repeated variables |
| `opt` | All optimizations combined |

```bash
uv run python -m fair_seldonian.experiments.runner opt
uv run python -m fair_seldonian.experiments.plots
```

## Citation

```bibtex
@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](CONTRIBUTING.md) for guidelines, or open an [issue](https://github.com/parulgupta1004/fair-seldonian/issues) to get started.

## Contributors

Thanks to everyone who has contributed to this project!

<a href="https://github.com/parulgupta1004/fair-seldonian/graphs/contributors">
  <img src="https://contrib.rocks/image?repo=parulgupta1004/fair-seldonian" />
</a>

## License

[MIT](LICENSE)

---

**Author:** [Parul Gupta](https://www.linkedin.com/in/parulgupta04/)
