Skip to main content

onside

A regularized adjusted plus-minus framework for football. Open source. Mathematically grounded. One number per player.

pip install onside

Every action counted.


What this is

A Python library and accompanying dataset that produces a single rating for every player in a covered league, decomposed into offensive and defensive components, calibrated against actual match outcomes.

onside answers a question football fans argue about constantly: how much does this player actually contribute? Goals and assists tell you about the last action of a sequence. They don't tell you about the switch of play that created the chance, the press that forced the turnover, the goal-line clearance that prevented the opponent's chance. onside credits every action by how much it changed the probability of a goal — for or against.

The framework integrates three established techniques from the sports analytics literature into a single open-source pipeline:

  • VAEP (Valuing Actions by Estimating Probabilities) for outfield action value
  • PSxG − Goals for goalkeeper shot-stopping
  • Regularized Adjusted Plus-Minus (RAPM) for context-controlled player ratings

Each of these is well-known in the literature. None of them, as far as we are aware, has been published as a clean, free, public Python package for football. onside is that package.

What it isn't

  • Not a betting product
  • Not a fantasy football optimizer
  • Not a replacement for watching matches
  • Not the final word on player quality
  • Not a model of off-ball contribution — this is an open problem in the literature, and we are explicit about it

How it works

For every action in every match — every pass, dribble, tackle, interception, save — the library computes the change in goal probability that action produced.

A pass that moves the ball from a low-threat zone to a high-threat zone gets positive credit. A turnover gets negative credit. A goal-line clearance gets large positive defensive credit. Sum these per-action values across a season, control for teammate and opponent quality using regularized regression (the same technique used to compute NBA RAPM), and you get one offensive and one defensive rating per player, with confidence intervals.

Goalkeepers are handled separately using post-shot expected goals (PSxG) because their critical actions — saves — aren't well-encoded in standard event data.

For the math, see docs/PAPER.md. For data sources, see docs/DATA_SOURCES.md.

Quickstart

import onside

# Load a season's worth of data (downloads + caches if not local)
data = onside.load("statsbomb-open", competition="laliga", season="2023-24")

# Compute action values for every event
values = onside.value(data)

# Compute season ratings with cross-validated ridge regression
ratings = onside.rate(values, regularization="cv")

# Top 20 players by total rating
print(ratings.top(20))

# Decompose by offense / defense, filter by position
print(ratings.by("defensive", position="CB"))

What gets shipped

Artifact What it is
pip install onside The library — load data, compute action values, fit ratings
Pre-trained models (GitHub releases) Score and concede probability functions, PSxG model, all version-tagged
Public dataset (Hugging Face / Kaggle) Cleaned event data and computed ratings, ready to use
onside.fc Companion site — leaderboards, per-player pages, methodology explainer

Why this exists

Football analytics has terrific public infrastructure for shot-quality (xG via Understat, FBref) and event-data parsing (socceraction, kloppy, mplsoccer). What is missing is a single, principled, cross-position, context-controlled player rating — the football equivalent of NBA RAPM.

Several research papers describe how to build one. None ship a turn-key package. The closest analogs are paywalled (Twenty First Group, StatsBomb's internal models, PFF's grades) or single-paper releases that don't keep up with new seasons.

onside is the open implementation. Methodology is public. Code is public. Models are versioned and reproducible. Predictions come with confidence intervals. The bad ones aren't hidden.

Status

Pre-release. Working toward v0.1.0. The first stable release will cover the StatsBomb open-data scope (men's and women's World Cups, La Liga, FA WSL, Champions League finals, and a small set of historical matches). Subsequent releases extend coverage to FBref-derived data for the Big 5 European leagues, MLS, and Liga MX.

Acknowledging what came before

onside builds on:

  • Decroos, T., Bransen, L., Van Haaren, J., & Davis, J. (2019). Actions Speak Louder than Goals: Valuing Player Actions in Soccer. KDD.
  • Sicilia, A., Pelechrinis, K., & Goldsberry, K. (2019). DeepHoops: Evaluating Micro-Actions in Basketball Using Deep Feature Representations of Spatio-Temporal Data. KDD.
  • Sill, J. (2010). Improved NBA Adjusted +/- Using Regularization and Out-of-Sample Testing. MIT Sloan Sports Analytics Conference.

Full citations and discussion in docs/PAPER.md.

License

Code: MIT. Methodology and writeups: CC BY 4.0. Data is sourced from public providers; their licenses apply to the underlying data.

Citation

Dondisch, L. (2026). onside: A regularized adjusted plus-minus framework for football.
https://github.com/dondischl12/onside

Metadata

Release files for onside 1.0.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 onside 1.0.0
File Size Uploaded
onside-1.0.0.tar.gz 24.8 MB Details

Built distribution (wheel)

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

Total release size: 24.9 MB

Release files / onside-1.0.0.tar.gz

Download URL onside-1.0.0.tar.gz
Size 24.8 MB
Tags Source
SHA-256 checksum
How to use checksums
384252be0ff2678c9203d7468ecb7c045afcea3f54443c224a1bccb87c6e9d5f
BLAKE2b-256 checksum
How to use checksums
630075dfc2ded03da00de3dae7bff2cab65fb2d769ca83b3ce8b4967d028bd24
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.11.11

Release files / onside-1.0.0-py3-none-any.whl

Download URL onside-1.0.0-py3-none-any.whl
Size 41.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
1604f2cd0df1bff444b4b57e662f9952516bedf19630a4ab63f3743a6fcb9233
BLAKE2b-256 checksum
How to use checksums
69ebbee27fecf3655324e48894e0ffde7c98cc934aeee5dc0e99a5cedb735686
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.11.11

Release history Release notifications | RSS feed

This release

1.0.0 This release

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