OO toolkit for lattice-based performance models and the horse-race inverse problem
Project description
thurstone
An object‑oriented toolkit for lattice‑based performance models and the horse‑race inverse problem (inferring relative ability from market prices, a.k.a. the ability transform). This package seeks to revitalize Thurstone Class V models which have tended to play a poor cousin to Plackett-Luce and other alternatives due to lack of tractability. It implements a relatively recent fast algorithm.
Uses
(Beyond horseracing)
See the notebook for examples of the use of this ability transform.
See the paper for why this is useful in lots of places, according to a wise man. For instance, the algorithm may also find use anywhere winning probabilities or frequencies are apparent, such as with e-commerce product placement, in web search, or, as is shown in the paper: addressing a fundamental problem of trade.
Highlights
This is the successor to the winning package. Essentially a clean up and mild generalization. New and inherited functionality includes:
- Uniform lattice with explicit
Landunit(UniformLattice). - Normalized
Densitywith safe integer/fractional shifts, centering, convolution, and dilation. Negative mass is rejected; zero‑mass vectors are allowed as an explicit off‑lattice sentinel in extreme shifts. - Clean
RaceandStatePricerAPI for risk‑neutral state prices (winning probabilities), now multiplicity‑aware. AbilityCalibratorsolves the inverse problem with per‑runner monotone interpolation (sorted price→offset tables) and returns abilities in physical units.ClusterSplitterhandles offsets that hang off the lattice (both directions) with symmetric clustering and coarse‑to‑fine recursion, including walkover behavior and an equal‑share rule only when all offsets hang on one side and are tightly bunched (spread < support width).order_statsmodule: multiplicity‑awarewinner_of_manyandexpected_payoff_with_multiplicity(draws split by 1/(1 + multiplicity)).- Tie handling via pluggable
TieModel(default: 0.5 split).
Quickstart
from thurstone import UniformLattice, Density, AbilityCalibrator, STD_L, STD_UNIT
lat = UniformLattice(L=STD_L, unit=STD_UNIT)
base = Density.skew_normal(lat, loc=0.0, scale=1.0, a=0.0) # symmetric base
# Inverse calibration from dividends -> abilities (physical units)
from thurstone import StatePricer
dividends = [3.2, 4.8, 12.0, 7.5, 20.0]
cal = AbilityCalibrator(base)
ability = cal.solve_from_dividends(dividends) # abilities in same units as lattice grid
prices = cal.state_prices_from_ability(ability) # forward map (prices sum to 1)
Design notes
- Fractional shifts are performed on the CDF then differenced back to preserve mass and monotonicity.
- The inverse loop builds per‑runner
(price, offset)tables (holding others fixed), sorts them by price, uniques on the price key, clips, and usesnp.interp. ClusterSplittersplits at the largest gap near the center, evaluates both sides, and combines refined within‑group prices using coarse group shares from a dilated lattice. It exhibits:- Walkover: sufficiently better (left) runners take ~1, sufficiently worse (right) get ~0.
- Equal‑share only when all runners hang on the same side and are indistinguishable at resolution (spread < support width).
- Forward pricing and inverse calibration use multiplicity‑aware payoffs:
win + draw/(1 + multiplicity_rest). This improves accuracy in dense/tie regimes.
Testing
- Optional test extras:
pip install -e ".[test]" - Run tests:
pytest -q - Property tests (Hypothesis) are auto‑skipped if Hypothesis is not installed.
- A performance benchmark (pytest‑benchmark) is included and auto‑skips if the plugin is missing.
- Multiplicity tests ensure clone ties scale multiplicity correctly and that multiplicity‑aware payoffs differ from naive half‑point splits.
Examples
- Plot offset densities for 150 runners:
- Requires matplotlib:
pip install matplotlib - Run:
python examples/plot_offset_densities_150.py
- Requires matplotlib:
- 2D calibration with per‑runner scales (150 runners, scales 15→20):
- Run:
python examples/calibrate_with_scales_150.py
- Run:
Interactive Visualizations
Explore Thurstone models interactively in your browser:
- Diffeomorphism Explorer: Interactive visualization of cube-to-simplex mappings using racing dynamics with real-time parameter controls
- All Interactive Demos: Collection of browser-based visualizations and educational tools
Run locally: python -m http.server 8000 --directory docs then visit http://localhost:8000
Cite
See
- Cotton, Peter. “Inferring Relative Ability from Winning Probability in Multientrant Contests,” SIAM Journal on Financial Mathematics, 12(1), 295–317 (2021). DOI:
https://doi.org/10.1137/19M1276261 - Original reference implementation and additional context:
https://github.com/microprediction/winning
BibTeX:
@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}
}
Contribute
The most obvious improvement would be a rust implementation.
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 thurstone-0.1.0.tar.gz.
File metadata
- Download URL: thurstone-0.1.0.tar.gz
- Upload date:
- Size: 102.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
11042a3b140b67c6d8e2dc766deed1484ba0e7bb507ea225a5940f48153ef9a9
|
|
| MD5 |
2c52851c32f5b54a3bffc52c3746be7a
|
|
| BLAKE2b-256 |
f13c1b4224048a98a86f086a8971996fcdab634909c49cd6487f49ddc7fbac19
|
File details
Details for the file thurstone-0.1.0-py3-none-any.whl.
File metadata
- Download URL: thurstone-0.1.0-py3-none-any.whl
- Upload date:
- Size: 127.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a268af2d6c15b4b90e9acc76c2414e5e652eb5bddb9796b1f783c45f44ebddd9
|
|
| MD5 |
b2408dae57e80e3853b73afde19f8455
|
|
| BLAKE2b-256 |
46ed52d86faece93ee87a22d70acb363a362011ce7985b99820d755bf78f52b3
|