The Stat Lab

How it works

A plain-English tour of the model.

1. The four markets

Every player on every team sheet gets four predictions per round — one for each of disposals, goals, marks and fantasy points. If a bookmaker line is available it becomes the line we predict against; otherwise we fall back to the player's blended season average (65% season-to-date + 35% last-5).

2. Eleven factors per pick

  • DvP — how many of this stat the opponent concedes to the player's position vs the league average.
  • Form — last 5 games vs season-to-date.
  • Venue — career split at this ground vs everywhere else.
  • Weather — rain suppresses marks and goals, wind hurts set shots, wet weather lifts handballs.
  • Team style — how the player's own team distributes the stat to this position.
  • Line edge — gap between blended baseline and the bookmaker's line.
  • Rest & travel — interstate trips and short turnarounds drag totals.
  • Pace — projected game total vs league average; high-scoring games inflate every prop.
  • H2H — player's actual record against this exact opponent.
  • Role / TOG — last-3 time-on-ground trend signalling expanding or shrinking roles.
  • Status — manual flags for injury, expected tag, role change; "out" picks are dropped entirely.

Each factor returns a z-score in [-1, +1] with positive meaning OVER, negative meaning UNDER, plus a plain-English reason and a sample size. Confidence-cap is reduced when sample sizes are thin so we never pretend to know more than the data supports.

3. Confidence and recommendation

Z-scores are combined with the active weight set for that prop, scaled by reliability, and converted into an OVER / LEAN OVER / NEUTRAL / LEAN UNDER / UNDER call. The number you see on a pick card is pick confidence — conviction in the direction we're recommending. It runs 50 → 100, where 50 is a coin flip and a higher number means stronger conviction in whichever side we've called. A 78-confidence UNDER and a 78-confidence OVER are equally strong picks; the direction is shown by the OVER/UNDER badge next to the number.

4. Self-improvement loop

Once a round settles, every prediction is joined to the actual stat in game_logs. We learn which factors actually correlated with hits using a logistic regression on factor z-scores → hit/miss, falling back to factor edge tables if the sample is thin.

The new weight set is written as a new model_weights row, marked active, and picks generated from the next round onward use it. Old versions stay in the table for audit and rollback. The Performance page shows what the model is currently leaning on and how each factor's calibration is holding up.

5. Honesty about the limits

  • Bookmaker lines come from get_lines.py — they need a paid Odds API key for live coverage.
  • Weather forecasts use Open-Meteo (free, no key); accuracy degrades beyond 3-4 days out.
  • Venue splits need at least 3 prior games at that ground to register a signal.
  • This is a research tool. Gamble responsibly.