Treść z repozytorium z zachowaniem nagłówków, przykładów, kodu, tabel, linków i obrazów.
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:
| Need | Go instead |
|---|---|
| Pure cross-sectional comparison with no recency | EDA / stats skills |
| Opponent-adjusted strength is the real goal | also ratings-strength-models |
| Static season aggregates already sufficient and time-safe | simpler baselines |
| Feature legality review of a finished matrix | leakage-audit |
Installation
ewma_form.py requires pandas. compare_form_windows.py additionally requires NumPy and scikit-learn:
python -m pip install pandas numpy scikit-learnParquet input also needs pyarrow or fastparquet.
Workflow
- Define the entity and frequency (team-game, player-game, week).
- Sort by entity + time; handle missing games explicitly.
- Choose window/decay rules; tune only inside training folds.
- Apply `shift(1)` / as-of so current game is never inside the feature.
- Compare form features against static baselines under walk-forward validation.
- Watch early-season small-sample explosions — min-games thresholds or shrinkage.
- Document window/span, shift rule, and min history.
- Hand off to baselines / predictive models / leakage audit.
Core Techniques
| Technique | Sports use | Time-safety rule |
|---|---|---|
| Expanding mean | season-to-date win % / PF | shift before expand |
| Rolling mean | last K games form | shift then rolling |
| EWMA | recency-weighted form | ewm on shifted series |
| Rest days | schedule gaps | diff of game dates |
| Season phase | week number, month | known pre-game |
| Regime split | rule changes, coaching eras | flag 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.
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.csvGenerated 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
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_marginThe 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
| Problem | Mitigation |
|---|---|
| Week 1 empty history | NA features + drop or league prior |
| Tiny n rolling windows | require pre_games_played >= k |
| Noisy short rolls | shrinkage toward league mean / expanding mean |
| Bye weeks | rest_days feature; don’t fill with zeros blindly |
| Offseason gaps | don’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
- No centered rolling windows that peek forward.
- No “season average including current game.”
- Early-season priors/shrinkage when n is tiny.
- Validate across seasons, not one hot streak.
- Opponent strength still matters — raw form ≠ opponent-adjusted strength (
ratings-strength-models). - 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
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
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_marginBundled Resources
references/
| File | Contents |
|---|---|
| form_feature_recipes.md | shift/roll/expand/EWMA recipes |
| early_season.md | small-sample handling |
| rest_and_gaps.md | byes and calendar gaps |
scripts/
| File | Contents |
|---|---|
ewma_form.py | shifted EWMA form table |
compare_form_windows.py | walk-forward compare roll vs EWMA features |
Related Skills
| Need | Skill |
|---|---|
| Feature legality | feature-rules |
| Ratings (opponent-adjusted) | ratings-strength-models |
| EDA | eda-sports |
| Models | baseline-models, predictive-modeling |
| Leakage | leakage-audit |
Quick Command Card
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
