Skip to content

Commit a0e9674

Browse files
valvesssclaude
andcommitted
docs(o0): third-observer source audit — verdict GO
Transfermarkt via dcaribou/transfermarkt-datasets: CC0-1.0, public no-account DuckDB mirror (~200MB). Lineups >=95% from 2013; 24/38 divisions join (first tiers) = 84k frozen matches in era, ~45-50k on strong-join leagues; end-to-end matchday lineup-value query verified (City 799M vs Newcastle 398M, 22/22). national_teams carries squad value + FIFA rank for the O3 WC hook. Decisions fixed for O1 in docs/SPIKE-O0.md; gitignore covers data/*.duckdb. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent c5302cf commit a0e9674

3 files changed

Lines changed: 72 additions & 7 deletions

File tree

study/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# raw match data (restricted by football-data.co.uk ToS; regenerable, hash-frozen)
22
data/*.csv
3+
data/*.duckdb
34
data/canonical/
45
outputs/*.log
56
outputs/_provenance/

study/docs/RESEARCH-AGENDA.md

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -195,13 +195,12 @@ preference parameters (CPT) are themselves invariant.
195195
**disjoint information set** — player attributes only: no match results, no odds —
196196
turns the duet into a panel and makes the invariance claim structural.
197197

198-
- **O0 [spike] Source audit** — Kaggle `davidcariboo/player-scores` (Transfermarkt
199-
mirror: 60k+ games, 400k+ historical market valuations, `game_lineups`,
200-
`appearances`, national teams; weekly refresh, OSS pipeline
201-
`dcaribou/transfermarkt-datasets`). Audit the coverage join vs the frozen
202-
archive (team-name mapping à la `fdcanon.py`); license posture: raw dump stays
203-
in `data/` (gitignored), only derived aggregates committed. Complement/fallback:
204-
SoFIFA (EA) player-rating dumps.
198+
- **O0 [spike] Source audit** ✅ DONE 2026-07-06 — verdict **GO**, see
199+
`docs/SPIKE-O0.md`. Source is CC0-1.0 with a public no-account DuckDB mirror
200+
(~200 MB). Lineups usable from 2013 (≥95%); 24/38 divisions join (first tiers
201+
only) = 84k frozen matches in the era, ~45–50k on the strong-join leagues.
202+
End-to-end lineup-value query verified. Decisions fixed: state = log matchday
203+
lineup value; eval era 2013+; match clubs globally, league as tiebreaker.
205204
- **O1 [new data] The observer**`skewlib/players.py`: team state = log
206205
matchday-lineup market value (fallback: season squad value — decide in O0 by
207206
coverage), link `strength gap → (pH, pD, pA)` by ordered probit (reuse the

study/docs/SPIKE-O0.md

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
# Spike O0 — third-observer source audit (Transfermarkt)
2+
3+
> 2026-07-06. Verdict: **GO**. Source: `dcaribou/transfermarkt-datasets`
4+
> (Kaggle mirror `davidcariboo/player-scores`), **CC0-1.0** (public domain),
5+
> weekly refresh, OSS pipeline. Direct download, **no account needed**:
6+
> `https://pub-e682421888d945d684bcae8890b0ec20.r2.dev/data/transfermarkt-datasets.duckdb`
7+
> (~200 MB DuckDB; keep in `data/`, gitignored — same posture as every raw dump).
8+
9+
## Coverage
10+
11+
- **Games:** 88,943 across 70 competitions, seasons 2005–2025; dense from 2012.
12+
- **Lineups (`game_lineups`):** usable from **2013** — ≥95% of games carry a full
13+
starting XI per side from 2013-14 onward. This sets the evaluation era.
14+
- **Valuations (`player_valuations`):** 400k+ rows, dense from ~2011;
15+
20k+ players covered per recent year.
16+
- **Scope caveat:** **first tiers only** (31 domestic leagues). None of our
17+
second/third tiers (E1–E3, EC, SP2, I2, F2, D2, SC1–SC3) nor IRL/FIN/CHN.
18+
19+
## Join vs the frozen archive (matches.csv, 2013+)
20+
21+
24 of our 38 divisions map to a TM first tier (`DIV2COMP` below) = **84,091
22+
frozen matches** in the lineup era. Naive-normalised name match rates:
23+
24+
- **79–100%**: E0, SP1, I1 (100%), F1, D1, N1, P1, B1, T1, G1, SC0, USA, DEN, SUI
25+
→ a small hand-curated mapping table (the `fdcanon.py` precedent) closes these
26+
to ~100%.
27+
- **28–73%** (ARG, BRA, JAP, MEX, RUS, SWE, NOR, POL, ROM, AUT): mostly an
28+
artifact — `clubs.domestic_competition_id` reflects *current* membership, so
29+
relegated clubs drop out of the per-league pool (e.g. RO1 shows 19 clubs vs
30+
40 frozen teams). **O1 must match against the full `clubs` table**, league
31+
used only as a tiebreaker.
32+
33+
Realistic O2 sample: the ~14 strong divisions ≈ **45–50k matches** — far above
34+
the per-bucket noise floor (SE(skew) ≈ 0.1 needs ~500/bucket).
35+
36+
## End-to-end sanity
37+
38+
Starting-lineup market value at match date via
39+
`game_lineups → player_valuations` (latest valuation ≤ match date):
40+
Man City **€799M** vs Newcastle **€398M** (2023-08-19), 22/22 starters valued.
41+
42+
## O3 hook (World Cup)
43+
44+
`national_teams` (124 teams) carries `total_market_value` + `fifa_ranking`
45+
directly — the prospective third `p` column for the WC ledger needs no squad
46+
reconstruction for *current* values. Historical national squads would need
47+
Wikipedia squad lists + player join (only if we backtest past WCs).
48+
49+
## DIV2COMP (frozen division → TM competition)
50+
51+
```python
52+
DIV2COMP = {'E0':'GB1','SP1':'ES1','I1':'IT1','F1':'FR1','D1':'L1','N1':'NL1',
53+
'P1':'PO1','B1':'BE1','T1':'TR1','G1':'GR1','SC0':'SC1','ARG':'ARG1',
54+
'USA':'MLS1','BRA':'BRA1','JAP':'JAP1','MEX':'MEX1','RUS':'RU1','DEN':'DK1',
55+
'SWE':'SE1','NOR':'NO1','POL':'PL1','ROM':'RO1','SUI':'C1','AUT':'A1'}
56+
```
57+
58+
## Decisions fixed for O1
59+
60+
1. **State = log matchday starting-lineup market value** (coverage confirmed);
61+
season squad value only as fallback for pre-2013 or missing lineups.
62+
2. **Evaluation era 2013+**; link (ordered probit) trained on an earlier,
63+
disjoint slice of the era split — exact split decided in O1.
64+
3. Match clubs globally (not per-league); commit the curated name map,
65+
never the raw dump.

0 commit comments

Comments
 (0)