# equal-odds
![PyPI publishing status](https://github.com/AndreFCruz/equal-odds/actions/workflows/python-publish.yml/badge.svg)
![PyPI version](https://badgen.net/pypi/v/equal-odds)
![OSI license](https://badgen.net/pypi/license/equal-odds)
![Python compatibility](https://badgen.net/pypi/python/equal-odds)
<!-- ![PyPI version](https://img.shields.io/pypi/v/equal-odds) -->
<!-- ![OSI license](https://img.shields.io/pypi/l/equal-odds) -->
<!-- ![Compatible python versions](https://img.shields.io/pypi/pyversions/equal-odds) -->
Fast postprocessing of any score-based predictor to meet fairness criteria.
The `equal-odds` package can achieve strict or relaxed fairness constraint fulfillment,
which can be useful to compare ML models at equal fairness levels.
## Installing
Install package from [PyPI](https://pypi.org/project/equal-odds/):
```
pip install equal-odds
```
Or, for development, you can clone the repo and install from local sources:
```
git clone https://github.com/AndreFCruz/equal-odds.git
pip install ./equal-odds
```
## Getting started
```py
# Given any trained model that outputs real-valued scores
fair_clf = RelaxedEqualOdds(
predictor=lambda X: model.predict_proba(X)[:, -1], # for sklearn API
# predictor=model, # use this for a callable model
tolerance=0.05, # fairness constraint tolerance
)
# Fit the fairness adjustment on some data
# This will find the optimal _fair classifier_
fair_clf.fit(X=X, y=y, group=group)
# Now you can use `fair_clf` as any other classifier
# You have to provide group information to compute fair predictions
y_pred_test = fair_clf(X=X_test, group=group_test)
```
## How it works
Given a callable score-based predictor (i.e., `y_pred = predictor(X)`), and some `(X, Y, S)` data to fit, `RelaxedEqualOdds` will:
1. Compute group-specific ROC curves and their convex hulls;
2. Compute the `r`-relaxed optimal solution for the chosen fairness criterion (using [cvxpy](https://www.cvxpy.org));
3. Find the set of group-specific binary classifiers that match the optimal solution found.
- each group-specific classifier is made up of (possibly randomized) group-specific thresholds over the given predictor;
- if a group's ROC point is in the interior of its ROC curve, partial randomization of its predictions may be necessary.
## Implementation road-map
We welcome community contributions for [cvxpy](https://www.cvxpy.org) implementations of other fairness constraints.
Currently implemented fairness constraints:
- [x] equality of odds [(Hardt et al., 2016)](https://proceedings.neurips.cc/paper/2016/file/9d2682367c3935defcb1f9e247a97c0d-Paper.pdf);
- i.e., equal group-specific TPR and FPR;
<!--
- [ ] equal opportunity;
- i.e., equal group-specific TPR;
- [ ] demographic parity;
- i.e., equal group-specific predicted prevalence;
-->
Raw data
{
"_id": null,
"home_page": "https://github.com/AndreFCruz/equal-odds",
"name": "equal-odds",
"maintainer": "",
"docs_url": null,
"requires_python": ">=3.8",
"maintainer_email": "",
"keywords": "ml,optimization,fairness",
"author": "AndreFCruz",
"author_email": "",
"download_url": "https://files.pythonhosted.org/packages/a5/d9/29f4d16ec6861429264298c9f308062c6896a6c72dce81c64328013b04af/equal-odds-0.0.7.tar.gz",
"platform": null,
"description": "# equal-odds\n\n![PyPI publishing status](https://github.com/AndreFCruz/equal-odds/actions/workflows/python-publish.yml/badge.svg)\n![PyPI version](https://badgen.net/pypi/v/equal-odds)\n![OSI license](https://badgen.net/pypi/license/equal-odds)\n![Python compatibility](https://badgen.net/pypi/python/equal-odds)\n<!-- ![PyPI version](https://img.shields.io/pypi/v/equal-odds) -->\n<!-- ![OSI license](https://img.shields.io/pypi/l/equal-odds) -->\n<!-- ![Compatible python versions](https://img.shields.io/pypi/pyversions/equal-odds) -->\n\nFast postprocessing of any score-based predictor to meet fairness criteria.\n\nThe `equal-odds` package can achieve strict or relaxed fairness constraint fulfillment, \nwhich can be useful to compare ML models at equal fairness levels.\n\n\n## Installing\n\nInstall package from [PyPI](https://pypi.org/project/equal-odds/):\n```\npip install equal-odds\n```\n\nOr, for development, you can clone the repo and install from local sources:\n```\ngit clone https://github.com/AndreFCruz/equal-odds.git\npip install ./equal-odds\n```\n\n\n## Getting started\n\n```py\n# Given any trained model that outputs real-valued scores\nfair_clf = RelaxedEqualOdds(\n predictor=lambda X: model.predict_proba(X)[:, -1], # for sklearn API\n # predictor=model, # use this for a callable model\n tolerance=0.05, # fairness constraint tolerance\n)\n\n# Fit the fairness adjustment on some data\n# This will find the optimal _fair classifier_\nfair_clf.fit(X=X, y=y, group=group)\n\n# Now you can use `fair_clf` as any other classifier\n# You have to provide group information to compute fair predictions\ny_pred_test = fair_clf(X=X_test, group=group_test)\n```\n\n\n## How it works\n\nGiven a callable score-based predictor (i.e., `y_pred = predictor(X)`), and some `(X, Y, S)` data to fit, `RelaxedEqualOdds` will:\n1. Compute group-specific ROC curves and their convex hulls;\n2. Compute the `r`-relaxed optimal solution for the chosen fairness criterion (using [cvxpy](https://www.cvxpy.org));\n3. Find the set of group-specific binary classifiers that match the optimal solution found.\n - each group-specific classifier is made up of (possibly randomized) group-specific thresholds over the given predictor;\n - if a group's ROC point is in the interior of its ROC curve, partial randomization of its predictions may be necessary.\n\n\n## Implementation road-map\n\nWe welcome community contributions for [cvxpy](https://www.cvxpy.org) implementations of other fairness constraints.\n\nCurrently implemented fairness constraints:\n- [x] equality of odds [(Hardt et al., 2016)](https://proceedings.neurips.cc/paper/2016/file/9d2682367c3935defcb1f9e247a97c0d-Paper.pdf);\n - i.e., equal group-specific TPR and FPR;\n<!--\n- [ ] equal opportunity;\n - i.e., equal group-specific TPR;\n- [ ] demographic parity;\n - i.e., equal group-specific predicted prevalence;\n-->\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "_PACKAGE UNDER CONSTRUCTION_",
"version": "0.0.7",
"project_urls": {
"Homepage": "https://github.com/AndreFCruz/equal-odds"
},
"split_keywords": [
"ml",
"optimization",
"fairness"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "c9cefa7565e3200796145567762cb631539aef14d4000dcec319b5ea5e212685",
"md5": "d9a54d84b3bc397b43458774047b517b",
"sha256": "c5ac6913e9a1eb360c6bd54c1ae6c657e2c8281485ba60094fc2ad5376ef0461"
},
"downloads": -1,
"filename": "equal_odds-0.0.7-py3-none-any.whl",
"has_sig": false,
"md5_digest": "d9a54d84b3bc397b43458774047b517b",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.8",
"size": 18183,
"upload_time": "2023-05-30T09:34:22",
"upload_time_iso_8601": "2023-05-30T09:34:22.366888Z",
"url": "https://files.pythonhosted.org/packages/c9/ce/fa7565e3200796145567762cb631539aef14d4000dcec319b5ea5e212685/equal_odds-0.0.7-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "a5d929f4d16ec6861429264298c9f308062c6896a6c72dce81c64328013b04af",
"md5": "d5634abfbc272b455d28944674fe400a",
"sha256": "f66a1b2f583271f05a8ef5ca35f1fd27960fa94f47daaa5c0457c549f421d949"
},
"downloads": -1,
"filename": "equal-odds-0.0.7.tar.gz",
"has_sig": false,
"md5_digest": "d5634abfbc272b455d28944674fe400a",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.8",
"size": 18007,
"upload_time": "2023-05-30T09:34:25",
"upload_time_iso_8601": "2023-05-30T09:34:25.663995Z",
"url": "https://files.pythonhosted.org/packages/a5/d9/29f4d16ec6861429264298c9f308062c6896a6c72dce81c64328013b04af/equal-odds-0.0.7.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2023-05-30 09:34:25",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "AndreFCruz",
"github_project": "equal-odds",
"github_not_found": true,
"lcname": "equal-odds"
}