Three times a day (morning, noon, and evening, to pick up newly announced starting pitchers), a scheduled GitHub Actions job grades finished games, rebuilds every feature, retrains, and publishes win probabilities for the day's games. No server, no manual steps.
There is no backend at all. Python trains the model and exports it as JSON, and Node.js runs inference with a custom pure-JS engine (rfPredict.js), all inside a scheduled GitHub Actions job that commits fresh static files for GitHub Pages to serve. Nothing runs between updates, so there's nothing to host, scale, or pay for, and every prediction is versioned in git.
Walk-forward validation: each season is predicted by a model trained only on the seasons before it, the same way it runs in production.
An earlier version scored 60.5% on its test season, which is too good for baseball. The cause was that the model used season-total stats, so each game could "see" performance from games that hadn't happened yet. Rebuilding every stat point-in-time dropped accuracy to an honest 55.3%. From there, each change was judged on the same 12,138 out-of-sample games: switching to a regularized logistic regression and adding Marcel-style pitcher projections raised it to 56.6%. XGBoost, a forest blend, and data augmentation were tried and dropped because their gains were within noise.
Beyond the model, Baseball Oracle publishes its picks in the open and grades every one, so anyone can check how it's really doing.
Calibrated win probabilities for every game on the schedule, refreshed three times a day as starting pitchers are announced.
Each prediction breaks down into plain-language factors, like starting pitching, bullpen, and form, showing exactly how many points each one moved the odds.
Every pick is recorded before first pitch and never edited. A running chart and a filterable table grade each one against the final score and the always-home baseline.
Charts for season-by-season accuracy, calibration, confidence, and feature importance show how the model makes its calls.