Jackson Angell
A platform built on my own League of Legends match history: a Riot API pipeline into Snowflake, five from-scratch models predicting my next ranked champion, and this site to show it all. This page covers the "why".
What this is
A pipeline that pulls every match I play from the Riot Games API into Snowflake, then layers models and a dashboard on top. Prediction guesses my next champion (ranked games only); Statistics and Playstyle cover the social and stylistic side across every game.
The models, and why the fun one is on the front page
Five models on a ladder of complexity, all trained on ranked solo queue only (queue 420). In ranked I pick what I believe is my best champion, so my history predicts my future; normals and ARAMs are experiments a model would just learn as noise. Features are recency-weighted (45-day halflife) so they follow a pool swap within a handful of games.
The Prediction page shows the two-step sampler: it samples a role, then a champion within it, rather than taking the most-likely answer. That draw happens once per new ranked game (seeded off my latest match, so it's stable until I play again) and lands on a pocket pick every so often, which is what makes checking back worthwhile.
Behind it: a logistic argmax, an XGBoost model (kept in to show how a data-hungry algorithm behaves on little data), a decay baseline, and a uniform floor. Each logs a pick for every past game beside the champion I actually played, so accuracy is measured, not asserted. See the scoreboard.
Pipeline architecture
- Match discovery: poll Match-V5 for new match IDs and upsert them into a
match_idsdiscovery log, so re-runs are idempotent. - Match ingestion: fetch full detail for anything not already in Snowflake,
then parse ~90 columns of participant stats into
matches/participants. - Champion reference sync: check Data Dragon's latest patch against a
pipeline_statekey/value table, and refresh the champions table only when the patch actually changed. - Walk-forward prediction: for every ranked game lacking one, write a row to
the wide
predictionstable (the actual champion beside all five models' picks) in a single batched insert. - Live prediction: publish each model's pick for the next, still-unplayed game
to
analytics_outputunderlive_prediction. - Publishing: stats, model rollups, and the playstyle analysis land as JSON
rows in the single generic
analytics_outputtable, keyed by output name, so this site reads them all with one query shape.
Stack
| Layer | Choice |
|---|---|
| Warehouse | Snowflake, key-pair authenticated |
| Pipeline | Python, scheduled on GitHub Actions (requests, pandas, scikit-learn, XGBoost) |
| Website | Flask + gunicorn, deployed on Render |
| Assets | Champion art pre-fetched from Data Dragon, served as static files |
| AI summaries | Claude API, called on demand and rate-limited per visitor |