walrusquant/sports-analytic-skills

time-series-sports

Engineer and compare time-safe sports form features.

查看源码
仓库原始内容

按源仓库内容呈现,保留标题、案例、代码、表格、链接以及原文引用的演示图片。

Time Series & Form (Sports)

Overview

Sports performance is ordered in time. This skill builds form features and simple trajectory forecasts that are legal at decision time T:

  • rolling means
  • expanding rates
  • EWMA / decay
  • rest gaps
  • regime flags

The bundled helper constructs shifted EWMA features from a user-owned event table, and the comparison helper evaluates already-computed feature sets.

Non-negotiable: shift (or as-of) so the current game is never inside the feature.


When to Use This Skill

Use when:

  • Team/player form features for pre-game models
  • Rolling averages, EWMA, half-life decay
  • Forecasting next-game stats from trajectories
  • Handling bye weeks, missing games, season breaks
  • Comparing recency-weighted form vs static season averages
  • User says “hot streak,” “last 5,” or “recent form”

Do not use when:

NeedGo instead
Pure cross-sectional comparison with no recencyEDA / stats skills
Opponent-adjusted strength is the real goalalso ratings-strength-models
Static season aggregates already sufficient and time-safesimpler baselines
Feature legality review of a finished matrixleakage-audit

Installation

ewma_form.py requires pandas. compare_form_windows.py additionally requires NumPy and scikit-learn:

bash
python -m pip install pandas numpy scikit-learn

Parquet input also needs pyarrow or fastparquet.


Workflow

  1. Define the entity and frequency (team-game, player-game, week).
  2. Sort by entity + time; handle missing games explicitly.
  3. Choose window/decay rules; tune only inside training folds.
  4. Apply `shift(1)` / as-of so current game is never inside the feature.
  5. Compare form features against static baselines under walk-forward validation.
  6. Watch early-season small-sample explosions — min-games thresholds or shrinkage.
  7. Document window/span, shift rule, and min history.
  8. Hand off to baselines / predictive models / leakage audit.

Core Techniques

TechniqueSports useTime-safety rule
Expanding meanseason-to-date win % / PFshift before expand
Rolling meanlast K games formshift then rolling
EWMArecency-weighted formewm on shifted series
Rest daysschedule gapsdiff of game dates
Season phaseweek number, monthknown pre-game
Regime splitrule changes, coaching erasflag by date known at T

Read form_feature_recipes.md when implementing rolling, expanding, or EWMA features. Read early_season.md when choosing priors, minimum history, or shrinkage. Read rest_and_gaps.md for byes, calendar gaps, and elapsed-time features.


Standalone Feature Construction

ewma_form.py requires non-null entity/reset keys, parseable finite numeric or timestamp time/order fields, and numeric or boolean value dtypes (including pandas nullable numeric/boolean dtypes). It rejects infinite values and contradictory event ordering. Missing observations in value columns remain missing—they are never filled with zero—before each value is shifted by one event and summarized with pandas EWMA semantics.

bash
python /path/to/time-series-sports/scripts/ewma_form.py \
  --input team_games.csv --entity-col team --time-col event_time \
  --order-col event_sequence --group-cols season \
  --values won,point_margin --span 5 \
  --out team_games_with_ewma.csv

Generated fields are named pre_ewma_<value>. Omitting --group-cols carries history across the full entity timeline. If --time-col can tie, --order-col must encode genuine event order; an arbitrary row ID is not enough.

Opponent features

Compute each participant's history independently, then join the participant and opponent snapshots by stable event/entity keys. Assert that both snapshots were available before the event. Never derive opponent form from the focal row's current result.

Compare feature sets

bash
python /path/to/time-series-sports/scripts/compare_form_windows.py \
  --input modeling_table.csv --target won --split-col season \
  --features-a pre_roll3_win,pre_roll3_margin \
  --features-b pre_ewma_won,pre_ewma_point_margin

The comparison uses identical expanding folds and complete cases shared by both feature sets. It validates binary targets and finite numeric features, but does not impute them. It evaluates hypotheses already encoded in the supplied columns; it does not make illegal features legal.

Early-Season Handling

ProblemMitigation
Week 1 empty historyNA features + drop or league prior
Tiny n rolling windowsrequire pre_games_played >= k
Noisy short rollsshrinkage toward league mean / expanding mean
Bye weeksrest_days feature; don’t fill with zeros blindly
Offseason gapsdon’t treat long rest as a normal short-week rest without care

Validation

Form features are hypotheses. Evaluate alternative windows on identical chronological folds, against a static or simpler baseline.

Tune window/span inside training folds only.


Hard Constraints

  1. No centered rolling windows that peek forward.
  2. No “season average including current game.”
  3. Early-season priors/shrinkage when n is tiny.
  4. Validate across seasons, not one hot streak.
  5. Opponent strength still matters — raw form ≠ opponent-adjusted strength (ratings-strength-models).
  6. Document shift rule in every feature card / experiment log.

Anti-Patterns

  • Fixed 5-game mean with no shrinkage
  • Ignoring opponent strength in raw form
  • Treating playoffs and regular season as identical without a flag
  • Tuning window length on the final test season only
  • Filling NA form with 0.0 silently
  • Claiming “hot streak” causality from one rolling mean

Reporting Template

text
Form model: rolling / EWMA / expanding
Entity/frequency:
Windows/span:
Shift rule: shift(1) before aggregate
Min history:
Validation: vs static baseline under walk-forward
Limits: early season, injuries, opponent strength…
Reproduce:

Output Contract

Done means:

  • [ ] Entity/frequency stated
  • [ ] Shift/as-of rule stated
  • [ ] Window/span documented
  • [ ] Min history rule stated
  • [ ] Walk-forward comparison planned or done
  • [ ] Leakage check planned or done

Worked Example

bash
python /path/to/time-series-sports/scripts/ewma_form.py \
  --input team_games.csv --entity-col team --time-col event_time \
  --order-col event_sequence --group-cols season \
  --values won,point_margin --span 5 \
  --out team_games_with_ewma.csv

python /path/to/time-series-sports/scripts/compare_form_windows.py \
  --input modeling_table.csv --target won --split-col season \
  --features-a pre_roll3_win,pre_roll3_margin \
  --features-b pre_ewma_won,pre_ewma_point_margin

Bundled Resources

references/

FileContents
form_feature_recipes.mdshift/roll/expand/EWMA recipes
early_season.mdsmall-sample handling
rest_and_gaps.mdbyes and calendar gaps

scripts/

FileContents
ewma_form.pyshifted EWMA form table
compare_form_windows.pywalk-forward compare roll vs EWMA features

Related Skills

NeedSkill
Feature legalityfeature-rules
Ratings (opponent-adjusted)ratings-strength-models
EDAeda-sports
Modelsbaseline-models, predictive-modeling
Leakageleakage-audit

Quick Command Card

bash
python /path/to/time-series-sports/scripts/ewma_form.py \
  --input team_games.csv --entity-col team --time-col event_time \
  --order-col event_sequence --group-cols season \
  --values won,point_margin --span 5 \
  --out team_games_with_ewma.csv

python /path/to/time-series-sports/scripts/compare_form_windows.py \
  --input modeling_table.csv --target won --split-col season \
  --features-a pre_roll3_win,pre_roll3_margin \
  --features-b pre_ewma_won,pre_ewma_point_margin

来自同一仓库

更多 Skills

全部 Skills