Methodologysnapshot · 2026-04-16 06:06:19 UTC

方法论 · Methodology

童帝足球如何从数据到情报 · 14 个环节 · 可追溯的全链路说明。 每一节都包含公式、当前线上参数、相关代码路径与对应蓝图文档。

数据谱系 · 从原始源到用户结论

data lineage · 9 stages
SportmonksOdds APIClubElo
↓ 数据标准化
  1. 01数据标准化normalize
  2. 02强度 / ELOrolling-20 + ELO
  3. 03λ 期望进球λ_home · λ_away
  4. 04Poisson 得分分布8 × 8 grid
  5. 05概率派生1X2 / AH / OU / BTTS
  6. 06Platt 校准全局 Newton 法
  7. 07edge_signalsmodel − market
  8. 08final_signals门槛 + 触发
  9. 09execution_view用户看到的结论
§01

数据获取与来源

童帝依赖三个主数据源的交叉覆盖,不使用任何未签约数据源;系统只对外标注实际跑通的数据源。

Sportmonks
ACTIVE
赛程 / 阵容 / xG / xGOT / 比赛事件
20K 调用 / 月 · 99.8% 成功率
The Odds API
ACTIVE
1X2 / OU / BTTS 赔率 · 多博彩商共识
$30 / 月 · 每 6 小时刷新
ClubElo
ACTIVE
球队动态 ELO 评分
本地拉取 · 每日 1 次
硬约束

不使用未签约数据源。任何分析输出都必须能回溯到上述三个源的某次真实抓取;无法回溯的数据不出现在产品里。 Understat 已迁移至 Sportmonks 作为 xG 主源,Understat 仅在"变更历史"中被提及。

标准化流程
  • · 联赛 key 规范化(如 eng_premier_league / esp_la_liga
  • · 球队别名映射(team_aliases.json
  • · 博彩商权重(bookmakers.json · 覆盖 18+ 家)
相关表:matches · match_results · odds_api_raw · fair_odds · clubelo_ratings_raw
§02

球队强度与 ELO

用 rolling-20 比赛窗口估计进攻 / 防守强度,并对联赛均值做 Bayesian shrinkage,避免小样本极端化。

rolling-20 强度 + Bayesian shrinkage
rolling-20 goal window:
  attack_strength  = goals_for_20     / (20 × league_avg_home_goals)
  defense_strength = goals_against_20 / (20 × league_avg_away_goals)

Bayesian shrinkage toward league mean 1.0:
  adjusted = (k × 1.0 + n × raw) / (k + n)
  k = 5   (shrinkage parameter)

ELO blend:
  strength_final = w × adjusted_rolling + (1 − w) × f(elo_diff)
当前线上参数
强度收缩 k5对 rolling-20 向联赛均值收缩
阵容收缩 k3阵容先验更强,收缩更少
rolling 窗口20 场主客场分别统计
ELO 融合权重 w0.70偏向 rolling,ELO 作补充
§03

比赛预期进球 λ

用主客场强度 × 对方防守强度 × 联赛基准进球数得到每支队的 λ,是 Poisson 分布的唯一输入。

λ_home / λ_away(L-01 审计 GREEN)
λ_home = home_attack_strength × away_defense_strength × league_avg_home_goals
λ_away = away_attack_strength × home_defense_strength × league_avg_away_goals

league_avg_* 来自 load_league_avgs() 实时查询(非 fixture 列)
L-02 说明

存储的 λ 使用 load_league_avgs() 实时查询,fixture_goal_expectation.league_avg_home_goals 列仅作参考。 审计状态:YELLOW → GREEN。

§04

得分分布(Poisson 8×8)

假定主客场进球数条件独立服从 Poisson,枚举 0–7 全得分网格,归一化后作为所有派生市场的基础概率矩阵。

8 × 8 score matrix · 归一化
P(home = i, away = j) = Poisson(i ; λ_home) × Poisson(j ; λ_away)

SCORE_MAX = 7      (i, j ∈ {0, 1, ..., 7})
After grid: renormalize so sum(P) = 1
尾部质量 · 经验值
典型 λ ≈ 1.5< 0.001可忽略
中等 λ ≈ 2.5< 0.005正常范围
高 λ > 4.0≤ 0.02偶发极端对局
独立性假设

Dixon-Coles 的 ρ 修正在 shadow 审计中显示 ρ = 0.00 最优, 即独立 Poisson 在我们的数据集上已逼近理论下界,额外的相关性修正不带来增益。 该结论见 /model-state/closed-paths · Dixon-Coles ρ

§05

1X2 / AH / OU / BTTS 派生

在 8×8 score matrix 上做事件累加,得到四个市场组的原始概率。所有派生仅为求和映射,不引入任何隐式模型。

1X2
P(home)  = Σ_{i > j}  P(i, j)
P(draw)  = Σ_{i = j}  P(i, j)
P(away)  = Σ_{i < j}  P(i, j)
AH 亚盘
AH lines: 0.00 · -0.25 · -0.50 · -0.75 · -1.00

win_credit_prob = P(FULL_WIN) + 0.5 × P(HALF_WIN)
OU 大小球 · BTTS 两队进球
OU k.5:
  P(over)  = Σ_{i + j > k} P(i, j)
  P(under) = 1 − P(over)           ← 规范实现

BTTS:
  P(yes) = 1 − P(home = 0) − P(away = 0) + P(0, 0)
  P(no)  = 1 − P(yes)
L-08 · YELLOW · 已隔离

当前生产代码使用 p_under = total − p_over, 对高 λ(> 4.0)场景有 最高 8.3% 误差。由于 OU 当前不在生产信号链中,对线上零影响。任何 OU edge 工作开始前必须先修复为 p_under = 1 − p_over

§06

Platt 全局校准

用 sigmoid(a·p_raw + b) 对模型原始概率做全局单参数重映射,降低系统性偏差。优化器采用 Newton 法 + 2×2 Hessian。

Platt 单参数形式
p_calibrated = sigmoid(a × p_raw + b)
             = 1 / (1 + exp(−(a × p_raw + b)))

optimizer:
  Newton 法 · 2 × 2 Hessian · max_iter = 200
  train on rolling n_train settled matches
市场结果abECE beforeECE after
1X2 v1.0home8.8724-4.21690.0830.027
1X2 v1.0draw10.6561-3.79330.0210.012
1X2 v1.0away9.3623-3.89880.0800.023
AH p1c.v1home8.4593-4.0221

AH Platt 已拟合但尚未正式投产,参数等治理门通过后随市场窗口一并激活。

§07

边际信号层

把模型校准概率与每家博彩商的 fair 概率对比,得到逐行 edge_signals。support_count 是多博彩商共识强度。

edge + support_count
edge = model_prob − market_fair_prob

support_count = |{ providers | provider ≠ 'model_poisson'
                   AND fair_prob 可用 AND 数据新鲜 }|
写入规则
  • · 所有市场组走同一链路(1X2 / AH / OU / BTTS)
  • · model_poisson 作为模型 vs 市场背景信号存在,在 edge_signals 表内但不计入 final
  • · 进入 final 的前提: provider ≠ 'model_poisson'
§08

最终信号层

在 edge_signals 之上叠加阈值门槛与触发条件,筛出用户实际能看到的 final_signals。门槛随市场组、校准版本独立配置。

门槛与触发
accept(signal) ⇔
    support_count ≥ threshold_support
  AND |edge|        ≥ threshold_edge
  AND freshness     ≤ max_latency
  AND trigger_condition(signal)  is TRUE
  AND provider      ≠ 'model_poisson'
示例门槛(不同市场组独立)
threshold_support · 1X2≥ 3需要至少 3 家博彩商共识
threshold_edge · 1X2≥ 0.020ECE 校准后尺度
max_latency≤ 6h与 odds_refresh 对齐
trigger_condition市场组定义见蓝图 BP-08
§09

盘口时序特征

在多快照赔率序列上抽取 7 组家族化时序特征(steam / slope / late_move / reversal / volatility / abs_move / dispersion)作为情报中心输入。

T-13 完整特征
consensus_timeseries: AVG(fair_prob) per snapshot_ts

opening: 最早时间戳(> 24h before kickoff)
mid:     最接近 kickoff 前 6h 的快照
pre:     kickoff 前最近快照

delta_open_mid = p_mid − p_open
delta_mid_pre  = p_pre − p_mid
delta_open_pre = delta_open_mid + delta_mid_pre

abs_move       = | delta_open_pre |
steam_k        = 加权最近 3 个 delta_p   (k = 3)
ols_slope      = OLS 斜率(p_t ~ time_to_kickoff)
late_move_sign = sign(delta_mid_pre)
reversal_flag  = 1 if sign(d_om) ≠ sign(d_mp) AND 幅度显著
volatility     = std(delta_p)

基于这 7 组家族做 bucket 分析: reversal · abs_move · steam · support · dispersion · slope · late_move。所有时序披露仅作为研究性情报陈列在 /intelligence,不直接驱动交易决策。

§10

阵容情境模型

用首发 XI 相对 rolling-20 的质量偏差,推导 λ 的小幅调整(β_att / β_def),并按 signal subset 做前向观察。

阵容情境
lineup_quality_delta : 首发 XI 相对 rolling-20 的质量偏差

λ sensitivity:
  β_att = 0.06
  β_def = 0.03
  (HOLD_FROZEN · n = 23 / 60)

P3-A7 signal subset:
  S_signal = { matches | z_total ≠ 0 }
  S_zero   = { matches | z_total = 0 }
当前状态
P3-A2 Lineup λHOLD_FROZENβ 参数已冻结 · n = 23 / 60
P3-A7 Signal subsetPASS_SIGNAL_SUBSET_STABLE前向观察期 · 研究辅助
P3-A6 Lineup OU/BTTSREADY_FOR_REAUDITsubset 稳定 · 可重新审计
§11

xGOT 独立路线

一条独立于 Poisson 主线的研究路径:用球员级 xGOT 聚合再接 λ_weight(α, β) 映射,形成与主线平行的得分分布样本。

xGOT 管线
xGOT_home = Σ player_xGOT_home × λ_weight(α, β)
xGOT_away = Σ player_xGOT_away × λ_weight(α, β)

λ_nextgen = λ_base × (1 + α × (xGOT / league_avg_xGOT − 1))

P_xgot(i, j) = Poisson(i ; λ_xgot_home) × Poisson(j ; λ_xgot_away)

Best params: α = 0.05 · β = 0.05
Brier gap:   −0.000700  vs 独立 Poisson
当前状态
T-14 xGOT shadowSHADOW_PASS最佳参数已锁定
T-14-B 前向FORWARD_INITIALIZEDsettled = 0 / 30
α / β0.05 / 0.05Brier gap -0.000700
定位声明 · 必读

xGOT 路线属于 研究辅助 · 非独立信号。即使 Brier gap 为负,它也不会被单独 promote 为 production。任何出现在产品里的 xGOT 输出都必须配合主线 1X2 正式信号一起解读。

§12

前向门控与治理

每一条研究路径通过独立的门控注册和快照表跟踪前向表现。童帝从不直接把 shadow PASS 提升到 production。

注册表 / 快照表字段
signal_candidate_registry:
  module_id   · variant   · status
  verdict     · reviewer  · decided_at

forward_gate_registry_snapshot:
  module_key  · status_bucket
  settled_n   · required_n   · ready_flag
  last_eval   · action
状态桶
INITIALIZEDHOLD_FROZENREADY_FOR_REAUDITSHADOW_VALIDATED_AWAIT_GOV_GATEFORWARD_REJECTED

所有模块晋升必须经过治理门。实时状态见 /model-state

§13

校准性能评估

三个主指标:Brier(整体均方)、LogLoss(概率信息量)、ECE(10 桶期望校准误差)。Reliability Diagram 作视觉诊断。

Brier / LogLoss / ECE
Brier Score = (1/n) × Σ (p − y)²

LogLoss     = −(1/n) × Σ [ y × log(p) + (1 − y) × log(1 − p) ]

ECE (10-bin) = Σ_k (n_k / n) × | avg_p_k − acc_k |
Reliability Diagram
X : 预测概率(分 10 桶)
Y : 实际命中率(该桶内样本的真阳占比)
对角线 y = x  ≡  完美校准
偏离方向 → 过信 / 欠信的诊断
当前线上指标 · 1X2 production
Brier0.174生产窗口 · 见首页 KPI
ECE (home / draw / away)0.027 / 0.012 / 0.023较 Platt 前 3× 改善
系统综合得分93.9 / 100P10 审计汇总
§14

已知代码缺陷披露

透明披露当前代码库中的 3 条已知 YELLOW 缺陷。我们公开它们而不是隐藏;所有条目均有明确的影响范围与修复前置条件。

L-08 · YELLOW · 已隔离

位置:build_fixture_market_probabilities.py
问题:p_under = total − p_over 对高 λ 有 最高 8.3% 误差
影响:零(OU 未在生产信号链中)
必修:任何 OU edge 工作开始前

L-11 · YELLOW

位置:Meta Overlay V2
问题: xg_available = 0 使用 zero-fill · 语义上"无 xG"被当作"0 期望进球"
影响:零(Meta V2 已 FORWARD_REJECTED

L-14 · YELLOW

位置:sidelined_snapshots
问题:全部记录 severity = 1.0,部分伤停(轻伤 / 疑似)未做细粒度区分
未来:细粒度版本已在路径中,将接入 P3-A7 signal subset