winning
A package for dealing with races, correlated or not.
winning began as the reference implementation of the lattice ability
transform (SIAM J. Financial Mathematics, 2021) and owns the whole line:
the original density-agnostic engine, the factor-correlated
generalization developed for "Scalable Share Calibration for Factor
Multinomial Probit Models", an arena of competing methods, and a
standing benchmark database.
winning.thurstone— the core engine, vendored home from the thurstone package (now a compatibility shim). Densities on a lattice, winner-of-many, dead heats, and the ability transform, for any base distribution.winning.factor— the correlated extension: all-share forward pass, share calibration, Jacobian-vector products, and factor fitting. One general race,race_probabilities, takes the distribution and the factor rank as parameters; factor probit, the classic independent transform, Luce/softmax, and correlated softmax are named special cases, and custom standardized bases plug in as callables. The Gaussian specialization keeps its dedicated tail-exact kernel.winning.methods— every contestant behind one interface: the lattice transform, direct and Sobol simulation, per-alternative factor-RQMC, GHK / Genz separation-of-variables, minimax tilting. Each passes closed-form and Monte Carlo anchors before admission.winning.bench— a seeded problem grid, cached references, and append-only accuracy-time records:python -m winning.bench.runner.
Install
pip install winning # core depends only on numpy and scipy
Quick start
Independent race: shares from abilities, and back.
import numpy as np
from winning import race_probabilities, calibrate_abilities
mu = np.array([-0.5, 0.0, 0.2, 0.3]) # lower is better (min-wins)
p = race_probabilities(mu) # array([0.443, 0.232, 0.175, 0.150])
mu_back = calibrate_abilities(p) # recovers mu (mean zero)
Correlated race: a hundred runners moved by two common factors, all shares in one pass over a shared survival field, then inverted.
rng = np.random.default_rng(0)
N, k = 100, 2
mu = rng.normal(0, 1, N); mu -= mu.mean()
V = rng.normal(0, 0.4, (N, k)) # factor loadings
D = rng.uniform(0.5, 1.5, N) # idiosyncratic variances
p = race_probabilities(mu, V=V, D=D) # all N shares, O(QNL)
mu_hat = calibrate_abilities(p, V=V, D=D) # inversion
Counterfactuals and structure from the same shared field:
from winning import removal_shares, tie_densities
q = removal_shares(mu, V=V, D=D) # q[i][j] = P(j wins | i removed)
w = tie_densities(mu, V=V, D=D) # photo-finish weights: the Jacobian's
# graph-Laplacian (circuit) conductances
For the probit literature, winning.probit speaks max-wins utilities
and shares directly — the paper's own conventions — and is the one
audited reflection onto the internal min-wins race. Both of the paper's
calibrations live here: utilities from observed shares, and the factor
structure itself from a supplied covariance.
from winning.probit import shares, utilities_from_shares, fit_factor_model
utilities = -mu # higher is better on this side
p = shares(utilities, V=V, D=D) # all N choice probabilities
u = utilities_from_shares(p, V=V, D=D) # the paper's calibration
Sigma = V @ V.T + np.diag(D)
V_hat, D_hat = fit_factor_model(Sigma, k=2) # certified rank-k contrast fit
p2 = shares(utilities, Sigma=Sigma, k=2) # same fit applied en route
One race, everything a parameter: distribution and correlation chosen per call, with factor probit just one named point in the family.
from winning.factor import race_probabilities
race_probabilities(mu) # the classic independent race
race_probabilities(mu, V=V, D=D) # factor probit
race_probabilities(mu, base="gumbel") # Luce / softmax, exactly
race_probabilities(mu, V=V, base="gumbel") # correlated softmax
race_probabilities(mu, temperature=0.7) # E[softmin(X/tau)]: soft credit
Temperature is exact, not approximate: by the Gumbel-argmin identity the softmin expectation equals the hard race with each base convolved with the tau-scaled Gumbel kernel, so the same engine serves it. It is not identifiable from a single race, so inversion holds it fixed.
Arbitrary densities (skewed, multimodal, empirical) run through custom
bases or winning.thurstone — see the module docs and research/demos/.
The paper
The correlated calibration is documented in Scalable Share Calibration
for Factor Multinomial Probit Models
(papers/factor-probit-transform,
submitted): all shares of a correlated Gaussian race in one O(QNL)
pass, matrix-free graph-Laplacian derivatives, and inversion at ten
thousand alternatives in under a minute. Every number comes from a
committed, seeded script in
research/experiments (index in its README);
research/experiments/run_all_paper.py regenerates the lot.
Demos and other languages
research/demos holds explanatory scripts (the shared
survival field, the cavity downdate). js/factor is a
dependency-free JavaScript port at machine-precision parity with the
Python, for browser demos; r/winning is a pure-R package;
rust/fastrace holds the optional compiled kernels —
build with pip install maturin && maturin develop --release, and
winning.methods uses them automatically. Julia is on the roadmap.
Rating systems (research line)
The renovation-era ratings layer — whole-density beliefs, exact
full-finish-order updates, benchmarked against TrueSkill, OpenSkill,
Glicko-2 and Elo on twelve datasets — lives in src/ pending
integration, with results in BENCHMARKS.md. Headlines:
decisive win on Formula 1 (1,158 grands prix), best calibration on
chess (ECE 0.0047), statistical ties atop WTA/ATP/EPL, and markets
remaining the ceiling wherever they exist. The ThurstoneRating API
documented there ships with a future release; it is not importable from
the current package.
History
Versions 1.x were the SIAM paper's reference implementation, and those
imports still work. A 2.0 renovation explored splitting the numerical
core into the separate thurstone package with winning as an
applications layer; the decision went the other way. winning owns the
core — heritage and name — the thurstone implementation is vendored
here as winning.thurstone, and the thurstone package is a
compatibility shim whose imports resolve to this one. The renovation's
migration notes and unported ideas are preserved in
planning/ and attic/.
Cite
@article{doi:10.1137/19M1276261,
author = {Cotton, Peter},
title = {Inferring Relative Ability from Winning Probability in Multientrant Contests},
journal = {SIAM Journal on Financial Mathematics},
volume = {12},
number = {1},
pages = {295-317},
year = {2021},
doi = {10.1137/19M1276261},
URL = {https://doi.org/10.1137/19M1276261}
}
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 winning-1.1.0.tar.gz.
File metadata
- Download URL: winning-1.1.0.tar.gz
- Upload date:
- Size: 122.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f8440293999170622c545a3bd5f0412b351b3200341edbcd4de5fa6ba60cc4a8
|
|
| MD5 |
b60408a56523746167c962666c0029d8
|
|
| BLAKE2b-256 |
76f29c60435e5d1c352756632b393cf9b99831094f43d9320fb4d261ca22bb6d
|
Provenance
The following attestation bundles were made for winning-1.1.0.tar.gz:
Publisher:
publish.yml on microprediction/winning
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
winning-1.1.0.tar.gz -
Subject digest:
f8440293999170622c545a3bd5f0412b351b3200341edbcd4de5fa6ba60cc4a8 - Sigstore transparency entry: 2503654693
- Sigstore integration time:
-
Permalink:
microprediction/winning@699ffef0a231efbc4eee462a714332951e39bc8c -
Branch / Tag:
refs/tags/v1.1.0 - Owner: https://github.com/microprediction
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@699ffef0a231efbc4eee462a714332951e39bc8c -
Trigger Event:
release
-
Statement type:
File details
Details for the file winning-1.1.0-py3-none-any.whl.
File metadata
- Download URL: winning-1.1.0-py3-none-any.whl
- Upload date:
- Size: 134.2 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 |
5535402b035fa5f3e77a7b3a5e433de854be222c9c0bb73effa4beb8b224ecca
|
|
| MD5 |
a5eadd0ebbab01200fee3e4bb2e8a47d
|
|
| BLAKE2b-256 |
8aaff4e2dc763e0f684bebf060a8c7fb98ca2080c2a030797d918b973c8da3f0
|
Provenance
The following attestation bundles were made for winning-1.1.0-py3-none-any.whl:
Publisher:
publish.yml on microprediction/winning
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
winning-1.1.0-py3-none-any.whl -
Subject digest:
5535402b035fa5f3e77a7b3a5e433de854be222c9c0bb73effa4beb8b224ecca - Sigstore transparency entry: 2503655642
- Sigstore integration time:
-
Permalink:
microprediction/winning@699ffef0a231efbc4eee462a714332951e39bc8c -
Branch / Tag:
refs/tags/v1.1.0 - Owner: https://github.com/microprediction
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@699ffef0a231efbc4eee462a714332951e39bc8c -
Trigger Event:
release
-
Statement type: