Skip to main content

fairlex: leximin calibration

PyPI version PyPI Downloads PyPI - Python Version License: MIT

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.

  1. When targets are noisy/inconsistent and you want bounded misses rather than fragile exact hits.
  2. When you need fairness/stability—no margin (or subgroup) becomes the sacrificial lamb.
  3. 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–max residuals). 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.

Release files for fairlex 0.3.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for fairlex 0.3.0
File Size Uploaded
fairlex-0.3.0.tar.gz 9.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for fairlex 0.3.0
File Interpreter ABI Platform
fairlex-0.3.0-py3-none-any.whl Python 3 none any Details

Total release size: 19.3 kB

Release files / fairlex-0.3.0.tar.gz

Download URL fairlex-0.3.0.tar.gz
Size 9.3 kB
Tags Source
SHA-256 checksum
How to use checksums
21c956707133af6fc8e2daba2af24b3b4fb7ecbf24251ded319ef5f95ef08078
BLAKE2b-256 checksum
How to use checksums
88049b98a59dbd03e189ac9f6e36505c5a59914736c69c969d8559e5d3c42470
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

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 Dec 28, 2025.

Transparency log

Release files / fairlex-0.3.0-py3-none-any.whl

Download URL fairlex-0.3.0-py3-none-any.whl
Size 9.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
37f6075c884368829311aae4165fea98597dfe802eea30bd5770a3ac4ceb237e
BLAKE2b-256 checksum
How to use checksums
394c56cc7c7fe190f1ba75d3c44568d04241e4f7d056e4135c08e6d6b395c137
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

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 Dec 28, 2025.

Transparency log

Release history Release notifications | RSS feed

This release

0.3.0 This release

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page