Leximin calibration for survey weights
Project description
fairlex: leximin calibration
fairlex implements risk-averse calibration of survey weights using leximin objectives.
Unlike standard calibration that either (a) hits all margins exactly (sometimes creating
spiky weights) or (b) accepts uneven misses, leximin prioritizes uniform guarantees: it
shrinks the worst margin error first (then the next worst, etc.) and can also cap how
far any weight is allowed to move from its base value.
Why use it?
When exact calibration is infeasible under weight caps.
- When targets are noisy/inconsistent and you want bounded misses rather than fragile exact hits.
- When you need fairness/stability—no margin (or subgroup) becomes the sacrificial lamb.
- In rolling waves, to prevent whiplash by bounding the worst per-unit weight changes.
fairlex is designed to be both easy to use and
flexible enough to support different calibration objectives. The two
principal calibration strategies are:
- Residual leximin – finds weights that minimise the worst absolute
deviation from the target margins (
min–maxresiduals). This can drive margin errors down to machine precision, but may result in large weight adjustments. - Weight‐fair leximin – first performs residual leximin, then minimises the largest relative change from the base weights while keeping residuals at their optimum level. This yields a more stable set of weights.
Installation
fairlex requires Python 3.12+ and depends on numpy>=1.26 and
scipy>=1.11. You can install it via pip once uploaded to PyPI:
pip install fairlex
For development, clone this repository and install the dependencies:
git clone https://github.com/finite-sample/fairlex.git
cd fairlex
pip install -e .[dev]
Usage
Construct a membership matrix A of shape (m, n), where each row
corresponds to a margin and each column to a survey unit. Each entry
represents whether the unit belongs to the margin (1.0 or 0.0 for simple
groups). Supply the target totals b, the base weights w0 and call
the desired calibration function:
import numpy as np
from fairlex import leximin_weight_fair, evaluate_solution
# Example data: two margins (sex and age) plus total
A = np.array([
# sex: female
[1, 0, 1, 0, 1],
# sex: male
[0, 1, 0, 1, 0],
# age: young
[1, 1, 0, 0, 1],
# age: old
[0, 0, 1, 1, 0],
# total
[1, 1, 1, 1, 1],
], dtype=float)
target = np.array([6, 4, 6, 4, 10], dtype=float) # Feasible targets
w0 = np.array([1, 1, 1, 1, 1], dtype=float)
# Calibrate using weight‐fair leximin
res = leximin_weight_fair(A, target, w0, min_ratio=0.5, max_ratio=2.0)
# Inspect the weights and diagnostics
weights = res.w
metrics = evaluate_solution(A, target, weights, base_weights=w0)
print(metrics)
evaluate_solution returns a dictionary with a variety of diagnostics,
including the maximum absolute residual, effective sample size (ESS), design
effect and quantiles of the weight distribution. If you supply the base
weights via base_weights, it also reports relative deviations from the
original weights.
Project details
Release history Release notifications | RSS feed
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 fairlex-0.3.0.tar.gz.
File metadata
- Download URL: fairlex-0.3.0.tar.gz
- Upload date:
- Size: 9.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
21c956707133af6fc8e2daba2af24b3b4fb7ecbf24251ded319ef5f95ef08078
|
|
| MD5 |
e981614e9eaac7b5b0eebed4198cf780
|
|
| BLAKE2b-256 |
88049b98a59dbd03e189ac9f6e36505c5a59914736c69c969d8559e5d3c42470
|
Provenance
The following attestation bundles were made for fairlex-0.3.0.tar.gz:
Publisher:
python-publish.yml on finite-sample/fairlex
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
fairlex-0.3.0.tar.gz -
Subject digest:
21c956707133af6fc8e2daba2af24b3b4fb7ecbf24251ded319ef5f95ef08078 - Sigstore transparency entry: 780673122
- Sigstore integration time:
-
Permalink:
finite-sample/fairlex@7bdb9dd2744b032ebe1d47c8fb012bd969c009b2 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/finite-sample
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@7bdb9dd2744b032ebe1d47c8fb012bd969c009b2 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file fairlex-0.3.0-py3-none-any.whl.
File metadata
- Download URL: fairlex-0.3.0-py3-none-any.whl
- Upload date:
- Size: 9.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
37f6075c884368829311aae4165fea98597dfe802eea30bd5770a3ac4ceb237e
|
|
| MD5 |
82d2ae744c65c66af9b87cf4463296fb
|
|
| BLAKE2b-256 |
394c56cc7c7fe190f1ba75d3c44568d04241e4f7d056e4135c08e6d6b395c137
|
Provenance
The following attestation bundles were made for fairlex-0.3.0-py3-none-any.whl:
Publisher:
python-publish.yml on finite-sample/fairlex
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
fairlex-0.3.0-py3-none-any.whl -
Subject digest:
37f6075c884368829311aae4165fea98597dfe802eea30bd5770a3ac4ceb237e - Sigstore transparency entry: 780673124
- Sigstore integration time:
-
Permalink:
finite-sample/fairlex@7bdb9dd2744b032ebe1d47c8fb012bd969c009b2 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/finite-sample
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@7bdb9dd2744b032ebe1d47c8fb012bd969c009b2 -
Trigger Event:
workflow_dispatch
-
Statement type: