关于 validation-design
面向体育预测模型的时间序列评估设计技能,帮助数据团队在拟合前确定折分、指标、基线和决策规则,并处理分组与时间隔离。
主要功能
- 01拟合前制定评估章程
- 02赛季及滚动起点折分
- 03选择指标与基线
- 04设置隔离期和分组
- 05折分诊断与结果报告
- 06CSV 和 JSON 折分工具
适用场景
- 01替换体育数据的随机 K 折
- 02在模型拟合前确定评估方案
- 03将同场比赛的关联行放在同一折
- 04报告各折结果及失败情况
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ walrusquant/ sports-analytic-skills --skill validation-design安装后在 Claude Code 中输入/validation-design确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/anti_patterns.mdmetrics_lock.mdsplit_patterns.mdscripts/print_folds.pywrite_charter.py详细介绍
验证设计
目标
编写一份评估章程和折表,用于模拟真实的预测流程。体育数据会随时间变化——阵容、规则、战术、对手、赛程和数据采集系统都会变化,因此随机行拆分通常不是可靠的默认做法。
选择折的划分方式时,请阅读拆分模式;冻结指标前,请阅读指标锁定指南;最终设计审查时,请阅读反模式。
何时使用此技能
适用于:
- 在拟合前锁定折、指标、基线和继续/停止规则;
- 将随机 K 折替换为按赛季或滚动起点的向前验证;
- 为球队-比赛面板数据或重复事件定义禁区期/分组;
- 用户询问如何诚实地验证体育模型。
不要将此技能用作以下工作的替代方案:
- 对特征矩阵进行泄漏审查 →
leakage-audit; - 章程锁定后拟合候选模型 →
baseline-models/predictive-modeling; - 概率可靠性诊断 →
calibration-check。
| 需求 | 请改用 |
|---|---|
| 特征合法性 | feature-rules |
| 泄漏判定 | leakage-audit |
| 基线阶梯 | baseline-models |
章程:拟合前锁定
记录:
- 问题、目标、行粒度、预测决策时间 T 和符合条件的总体;
- 按时间顺序划分的单位及明确无歧义的排序方式;
- 配对视角、重复事件、实体、赛季或系列赛的分组方式;
- 最短训练历史;采用扩展窗口还是滑动窗口,以及原因;
- 与标签或来源最终确定时间相对应的间隔/禁区期;
- 主要指标、次要诊断指标、基线和实际成功规则;
- 调参边界、提前停止所用数据和最终未触碰的留出集;
- 泄漏检查、折级报告、失败条件和允许的重跑次数。
如果在查看结果后更改章程,请创建新的评估版本,并将先前结果标记为探索性结果。
默认方案
- 按信息变得可用的时间对观测值排序,而非按文件顺序。
- 严格确保训练集早于测试集,并计入发布延迟和禁区期。
- 拟合候选模型前,先选定一个主要指标和基线。
- 当各区块有足够事件时,使用按赛季/赛事进行的向前验证。
- 当赛季区块过于粗略时,对高频预测使用更细粒度的滚动起点折。
- 仅使用过去的训练数据拟合每项变换并调整每个超参数。
- 对固定候选模型的每个外层测试折仅评分一次。
- 报告每折结果、离散程度、失败情况和与基线的差距,而不只报告汇总均值。
- 在特征族和候选模型冻结前,保留一个最终留出集。
拆分模式
按赛季向前验证
train through 2020 -> test 2021
train through 2021 -> test 2022
train through 2022 -> test 2023
对于按赛季划分的联赛,这是一个强有力的默认方案。每个测试赛季都必须有足够的符合条件的行,且此前赛季必须满足最短历史规则。
扩展窗口与滑动窗口
| 窗口 | 训练数据 | 适用情况 |
|---|---|---|
| 扩展 | 测试前的全部符合条件的历史数据 | 流程稳定;数据稀缺 |
| 滑动 | 最近 K 个区块 | 有记录的制度漂移/规则变更 |
选择 K 时,不要在最终留出集上进行优化。报告每个窗口舍弃的行数/实体数。
赛季内滚动起点
train through week 6 -> test week 7
train through week 7 -> test week 8
适用于高频标签或需要定期重新训练的场景。特征仍需按时间移位/按时点构建;时间拆分无法修复存在泄漏的矩阵。
禁区期与可用性间隔
如果标签在事件发生后才最终确定,或来源在事件发生后才发布,那么最近的训练事件可能无法立即使用。应根据实际的最大可用性延迟设置间隔,而非采用任意数值。请说明延期事件和数据修订是否会延长间隔。
分组与面板
团队比赛面板通常每场比赛有两行。将相关视角放在同一折中,并避免将成对团队行的准确率翻倍后当作独立的比赛预测准确率。球员事件行可能共享阵容、比赛或系列赛效应;应根据所要验证的主张选择分组方式。如果时间顺序是首要因素,实体分组不得意外将未来行放入训练集。
嵌套调优
Outer test block S
Inner chronological folds inside blocks < S choose configuration
Refit chosen configuration on all eligible data < S
Score S once
提前停止属于调优。它需要使用内层训练时段中的验证切片,而不是外层测试折。
指标锁定
| 任务 | 首选指标 | 次要诊断指标 |
|---|---|---|
| 获胜概率 | 对数损失 | Brier 分数、校准/ECE、准确率 |
| 分差/价值 | MAE | RMSE、偏差、残差切片 |
| 计数/比率 | 偏差或 MAE | 比率校准、零值表现 |
| 排名 | 未来时段 Spearman 相关系数 | 成对准确率、稳定性 |
仅看准确率会忽略概率质量。RMSE 对大误差的惩罚大于 MAE。应根据决策损失和目标语义选择指标,然后明确方向、聚合方式、加权方式、缺失预测的处理方式和并列处理方式。
每个候选方案都需要在完全相同的行和折上,与朴素基线及领域相关基线进行比较:训练集常数比率/均值、主场指示变量、最近值/评级,或其他简单且合规的比较方案。
折构造诊断
for fold in folds:
train = df.loc[fold.train]
test = df.loc[fold.test]
assert train["event_time"].max() < test["event_time"].min()
assert set(train["game_id"]).isdisjoint(set(test["game_id"]))
对于每个折,记录训练/测试时段、行数、事件数、实体数、目标基准比率、排除的行、可用性间隔以及必需列中的空值。检查是否有某个缩短的赛季、扩军时期、季后赛或数据源变更主导结果。
独立辅助工具
根据用户自有的 CSV、Parquet、JSON、JSONL 或 NDJSON 文件,打印扩展式前向验证折的大小。该辅助工具需要 pandas,会验证所有指定列,对不同的拆分值排序,并接受任何有序的赛季/日期/分组列。
python /path/to/validation-design/scripts/print_folds.py \
--input modeling_table.csv --split-col season \
--required-cols won,is_home,rating_diff --min-train-groups 2
python /path/to/validation-design/scripts/write_charter.py \
--out data/validation_charter.md
--min-train-groups 的默认值为 2。 这意味着前 N 个分组仅用作训练历史,绝不会作为测试折出现。以赛季 2022, 2023, 2024 为例:
- 默认值
2→ 一个测试折:2024(训练集为 2022+2023) 1→ 测试折:2023 和 2024
该辅助工具会先在 stderr 上打印计划中的测试折,然后再输出 CSV 表格。调用 baseline-models / predictive-modeling 辅助工具时应使用相同设置,以确保评估行保持一致。
该辅助工具会显示扩展式分组折的行数;但不会验证 T、依赖分组、禁运期、变换拟合或调优隔离。将设计判定为有效之前,请手动验证这些内容。支持的排序值包括有限数字、ISO 日期/时间戳,以及常见的连续赛季范围,例如 2022-23、2022/23 或 2022-2023。其他标签(包括词典序不代表时间顺序的阶段)需要显式的数字序号/日期字段。输出为 CSV,每个测试分组占一行。
反模式
| 反模式 | 失败原因 | 修正方法 |
|---|---|---|
| 对事件使用随机 K 折 | 未来结构进入训练集 | 使用仅向前的折 |
| 使用全量数据拟合缩放器/填补器 | 测试集分布发生泄漏 | 使用折内流水线 |
| 在外层测试集上提前停止 | 测试集变成调优数据 | 使用内层验证切片 |
| 反复检查最终留出集 | 产生自适应过拟合 | 冻结方案并仅评分一次 |
| 删除表现不佳的折 | 产生选择偏差 | 报告该折并解释其所属时期 |
| 只报告汇总均值 | 隐藏不稳定性 | 提供逐折表格及离散程度 |
| 没有基线 | 指标缺少参照 | 使用相同方式为合规基线打分 |
| 不同候选方案使用不同的行 | 比较不公平 | 使用共同的合格样本/披露差异 |
| 将团队行准确率称作比赛准确率 | 成对行导致重复计数 | 仅使用主队行或按比赛聚合 |
报告表格和决策
fold | train_period | test_period | train_n | test_n | baseline_primary |
candidate_primary | gap | secondary_metrics | exclusions | failures
报告各折的均值和离散程度,同时保留每一折的结果。按行数为各折加权,与各折等权平均回答的是不同的问题;请明确哪一种是主要方法。如果结论依赖于校准情况或相关的时间段/实体切片,请一并纳入。成功判定规则应综合锁定的主要指标、与基线的差距、各折是否具有有意义的一致性,以及不可妥协的数据泄漏/校准限制。
章程模板
Validation charter
Target / grain / decision time T / eligible population:
Split unit and ordering:
Grouping rule:
Minimum training history:
Window: expanding | sliding(K=)
Gap/embargo and availability rationale:
Primary metric definition:
Secondary diagnostics:
Baselines:
Inner tuning and early stopping:
Final untouched holdout:
Common evaluation rows:
Success / failure rule:
Required leakage checks:
Per-fold reporting and slice requirements:
Allowed reruns / versioning:
完整示例和完整性规则
对于团队比赛胜率:将 T 设为开球时间,按比赛对双方视角分组,按赛季向前滚动并纳入此前两个赛季,在每个外层训练集内拟合预处理并调优,以 log-loss 为主要指标,以 Brier/校准为次要指标,与恒定比率和主场指示变量基线进行比较,并报告每个赛季的结果。对于比赛级结论,应采用单一视角或比赛聚合方式。
- 任何行、依赖组、变换拟合或调优信号都不得从未来泄漏到过去。
- 在评估候选方案前锁定指标和成功判定标准;公布表现不佳的折。
- 在候选方案和特征冻结前,不得触碰最终留出集。
- 设计方案请参阅
references/split_patterns.md,指标请参阅references/metrics_lock.md,审查请参阅references/anti_patterns.md。 - 配合使用
feature-rules和leakage-audit;干净的折无法弥补不安全的特征。