這個專案怎麼運作
站上每個數字背後的端到端流程——資料進、機率出——寫給有技術背景、但不熟博弈的讀者。
技術棧
Python ETL
資料擷取與建模工作:Elo + 賽程 + 賠率 ingest、Dixon–Coles 引擎、Monte Carlo 模擬與校正。
Supabase(Postgres)
單一真相來源。所有工作以 idempotent upsert 寫入並帶 provenance;service key 僅存在於 server 端。
Next.js + Tailwind
App Router 前端、雙語(next-intl)。透過 server 端 API 唯讀——瀏覽器永不接觸資料庫。
流程逐步拆解
- 1
資料 ingest
World Football Elo 評分與官方賽程由 fail-loud 的 Python 工作抓取——對不上的隊名或缺欄位會直接 raise,而非靜默臆測。每次寫入都是 idempotent upsert,並標記 as-of 日期與來源。
- 2
隊伍身分對應
各來源對隊伍的命名都不同(Elo 兩碼、football-data 隊名、FIFA 三碼)。alias 層把它們統一到單一 canonical id;對不上的一律 raise,絕不新增重複隊伍。
- 3
Elo → 隊伍實力
兩隊的 Elo 差距成為模型衡量相對實力的依據。地主國(美國、加拿大、墨西哥)在自家球場享有由歷史擬合的約 85 Elo 主場加成;其餘場次一律視為中立場。
- 4
Dixon–Coles 擬合 + 閘門
以 Poisson 為基礎的 Dixon–Coles 模型把 Elo 差距轉成期望進球,並加上低比分修正。參數在 2010 年以來約 1,900 場國際賽上 backtest(近期比賽權重較高),且只有在未見過的比賽上勝過前一版才部署——嚴格的驗證閘門。
- 5
逐場預測
模型為每場比賽建立完整的比分機率表,再加總成 1X2、大小分與雙方進球。預測在開賽前凍結——不逐場重跑——因此 track record 評的是真正的賽前預測。
- 6
Monte Carlo 小組模擬
整個小組賽被重複模擬數萬次,每次都依真實 FIFA tiebreaker(積分、對戰成績、淨勝球)排名。統計各次結果,得出每隊小組第一、第二或以最佳第三名晉級的機率。
- 7
淘汰賽模擬
8 個最佳第三名依 FIFA Annex C 對應表配入槽位,接著把對戰表一路打到奪冠。真實淘汰賽賽果一到就鎖定對應分支,讓預測與實際發生的結果保持一致。
- 8
賠率 ingest + 去 vig
Pinnacle(低水、精準的莊家)賠率被 ingest,且只在變動時才儲存。去除 vig——莊家內建的利潤——還原出公平市場機率,作為衡量模型的基準。
- 9
EV 與分數 Kelly
EV 計算機刻意做到 model-free:它把你的賠率與去 vig 市場比較,回報期望值與 ¼ Kelly 注額。其算術(web/lib/value.ts)是 Python 引擎的 parity 測試移植版,以 golden-vector 測試保持同步。
- 10
校正與賽中重擬
每輪結束後以 Brier 對市場評分模型。賽中重擬(dc-v1.2)只用已完賽的比賽訓練,並以防 leakage 閘門禁止使用賽後資訊——讓校正衡量的是真正的預測力,而非事後諸葛。
誠實的框架
模型是實驗性的,永遠與市場並列——絕不當作唯一正解。收盤市場賠率通常是能取得的最準估計;模型是對照與學習工具,非投注建議。