Whole-History Rating for Python
A maintained, pure-Python implementation of Rémi Coulom's Whole-History Rating (WHR) algorithm for estimating time-varying skills from dated pairwise results.
WHR is useful when the history of a competitor's strength matters—not only the latest leaderboard—and when later evidence should be allowed to refine earlier ratings.
Installation
pip install whole-history-rating
Python 3.11 or newer and NumPy 2.0 or newer are required.
Quickstart
from whr import WHR
model = WHR()
model.load_games(
[
"alice bob B 1",
"alice bob W 2",
"alice bob B 3",
]
)
model.auto_iterate()
print(model.ratings_for_player("alice"))
print(model.probability_future_match("alice", "bob"))
Games are formatted as black_player white_player result time_step, where the
result is B, W, or D. You can also add structured games with
create_game().
Why Whole-History Rating?
Unlike an online rating update, WHR jointly revisits each competitor's complete trajectory when new results are added. A later result can therefore refine the estimated rating at an earlier date.
This implementation provides:
- retrospective smoothing of time-varying skill;
- uncertainty for ratings, differences, and changes over time;
- uncertainty-aware match predictions;
- binary outcomes and Davidson-model draws;
- learned contextual advantages such as home advantage, handicap, and komi;
- convergence and data-connectivity diagnostics;
- a reproducible comparison with KickScore and TrueSkill Through Time.
The main reason to choose WHR is not that it wins every predictive benchmark—it does not. Its strength is an interpretable, relatively lightweight model of complete pairwise histories.
Benchmark evidence
Lower log-loss is better. All systems below are trained, tuned, and evaluated under the same temporal protocol.
| Benchmark | Test set | WHR | KickScore | TrueSkill Through Time |
|---|---|---|---|---|
| NBA | 2018–19, n=1,312 | 0.666 | 0.662 | 0.688 |
| ATP tennis | 2014, n=2,816 | 0.614 | 0.606 | 0.604 |
| Football, three outcomes | 2022–23, n=1,826 | 1.008 | 1.013 | 1.023 |
No system wins every dataset, and the gaps are small. WHR leads the three-outcome football comparison, KickScore leads the NBA comparison, and TrueSkill Through Time leads tennis. Domain-specific NBA models using rosters, injuries, and travel still outperform all three generic rating systems.
The complete protocol, hyperparameter grids, limitations, data sources, and reproduction commands are in the benchmark report and benchmark README.
Applications
WHR can be used for dated pairwise-comparison histories such as:
- board games including Go and chess;
- sports and esports rankings;
- historical leaderboards;
- matchmaking analysis;
- human-preference experiments;
- pairwise evaluation of models or systems.
The model observes outcomes, dates, and optional contextual effects. It does not use domain-specific information such as rosters, injuries, maps, prompts, or evaluator identities. For LLM evaluation, treat it as a rating component rather than a complete evaluation methodology.
Documentation
- User guide: complete examples, configuration, uncertainty, draws, handicap, and komi.
- API reference: the supported high-level surface.
- Benchmark report: protocol, results, and caveats.
- Changelog: release-by-release compatibility notes.
The documentation site can be built locally with:
uv sync --group docs
uv run --group docs mkdocs build --strict
Implementation characteristics
- Pure Python with NumPy used where batching is beneficial.
- No compiled extension required.
- Binary and drawn outcomes.
- Learned contextual advantages.
- Reproducible real-data benchmark suite.
- High-level compatibility alias for the former
Baseclass.
The project originated as a port of the GoShrine Ruby implementation and has since added a modern API, diagnostics, draws, learned contextual advantages, uncertainty-aware predictions, and cross-library benchmarks.
Citation
If you use this package in research, cite both the software and Rémi Coulom's original WHR paper. GitHub exposes the complete metadata from CITATION.cff.
Rémi Coulom. “Whole-History Rating: A Bayesian Rating System for Players of Time-Varying Strength.” Computers and Games, LNCS 5131, 113–124, 2008. DOI: 10.1007/978-3-540-87608-3_11.
Development
uv sync --dev
uv run ruff check whr tests benchmarks
uv run mypy
uv run pytest
The fast CI suite also runs a synthetic benchmark smoke test. Full real-data benchmarks are intentionally manual because they download external datasets and can take hours.
License
MIT. See the license text.
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 whole_history_rating-3.6.1.tar.gz.
File metadata
- Download URL: whole_history_rating-3.6.1.tar.gz
- Upload date:
- Size: 220.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.14.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a7b32268df98452b135495a544b5f18a105528d1e584d5d51f74d7f7e75ea0ac
|
|
| MD5 |
ec347dd7d1d1cc74cd828cc5aa1ef87a
|
|
| BLAKE2b-256 |
f7264d728fbc8ba870839ccd991d1fa8b7d2072003091a816eb8e2970bb719dd
|
File details
Details for the file whole_history_rating-3.6.1-py3-none-any.whl.
File metadata
- Download URL: whole_history_rating-3.6.1-py3-none-any.whl
- Upload date:
- Size: 47.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.14.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c7923a1c66d7f32eeb28c6bf05e4e12a5e395812f06683252e1357a4ffc49fff
|
|
| MD5 |
ac4b9db1d447b39f2444918e171c59dd
|
|
| BLAKE2b-256 |
78da20ed2951bf1ff13534ef4641a3a858680fa4fc402fb1e2609cd0c731b4b4
|