mcpField
M
matchup-win-probability-sim

matchup-win-probability-sim

github.com/lyndonkl数据与数据库18747 次安装9 周前更新
代码仓库

关于 matchup-win-probability-sim

用于根据双方预测值和不确定性估算梦幻体育分类对决胜率的工作流技能,提供蒙特卡洛模拟与泊松二项计算,并支持逆向分类和可复现运行。

主要功能

  1. 01蒙特卡洛对决模拟
  2. 02泊松二项计算
  3. 03逆向分类比较
  4. 04分类及整体胜率
  5. 05方差估计与审计轨迹

适用场景

  1. 01估算梦幻体育对决胜率
  2. 02比较各分类的强弱项
  3. 03在优化循环中快速确定性估算

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/lyndonkl/claude --skill matchup-win-probability-sim

安装后在 Claude Code 中输入/matchup-win-probability-sim确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

resources/
methodology.md
template.md
resources/evaluators/
rubric_matchup_win_probability_sim.json

详细介绍

对阵获胜概率模拟器

目录

示例

场景:Yahoo MLB 10 项 H2H 对阵,第 8 周,阈值 = 10 项中赢下 6 项。类别:R、HR、RBI、SB、OBP(打击);K、ERA、WHIP、QS、SV(投球)。ERA 和 WHIP 为反向指标(越低越好)。

输入(两支球队本周剩余时间的预测;mean = 预期产出,stddev = 不确定性):

Cat我方 mean我方 stddev对手 mean对手 stddev是否反向?
R428387no
HR123.5144no
RBI409418no
SB62.542no
OBP0.3350.0150.3280.014no
K5510509no
ERA3.850.454.100.50yes
WHIP1.220.081.280.09yes
QS41.531.4no
SV21.251.5no

使用 random_seed=42、cat_win_threshold=6、n_simulations=10000 运行两种模式:

蒙特卡洛输出:

  • matchup_win_probability = 0.612
  • expected_cats_won = 6.18
  • variance_estimate = 2.42(赢下的类别数的方差)
  • per_cat_win_probability:R 0.64、HR 0.35、RBI 0.47、SB 0.72、OBP 0.64、K 0.64、ERA 0.65、WHIP 0.68、QS 0.69、SV 0.08

泊松二项分布输出(用于对比,使用相同的每类别获胜概率作为 PB 递推的输入):

  • matchup_win_probability = 0.605
  • expected_cats_won = 6.18(精确值——每类别概率之和)
  • variance_estimate = 2.11(独立伯努利变量之和的方差)

解读:我方略占优势(约 61%)。SV 是明显放弃的类别(获胜概率为 8%)。HR 胜负胶着,但我方略处下风。最值得争取的六项是 SB、QS、WHIP、ERA、R、K(以及 OBP)。下游的 mlb-lineup-optimizer 使用 win_prob = 0.612 将我方归类为优势方 → 降低方差。

工作流

复制此清单并跟踪进度:

Matchup Win Probability Simulation Progress:
- [ ] Step 1: Validate inputs and cat_list coverage
- [ ] Step 2: Choose sim_mode (monte_carlo or poisson_binomial)
- [ ] Step 3: Apply inverse-cat handling
- [ ] Step 4: Run simulation with seeded RNG
- [ ] Step 5: Compute per-cat and overall win probabilities
- [ ] Step 6: Emit outputs with variance and optional sim_trace

步骤 1:验证输入

确认 cat_list 中的每个类别都同时存在于 our_per_cat_projection 和 opp_per_cat_projection 中,且各自都包含 {mean, stddev}。确认 cat_win_threshold <= len(cat_list)。确认 cat_inverse_list ⊆ cat_list。请参阅 resources/template.md。

  • cat_list 中的每个类别都有双方的预测值
  • 所有类别的 stddev > 0(标准差为 0 会妨碍正确模拟;若未知,请使用较小的下限值)
  • cat_win_threshold 位于 [1, len(cat_list)] 范围内
  • cat_inverse_list 中的所有条目都是有效的类别名称
  • 如果 sim_mode == "monte_carlo",则 n_simulations >= 1000(默认 10k;置信度要求较高时使用 100k)

步骤 2:选择 sim_mode

对于实际决策,默认使用 monte_carlo(可获得类别获胜数的完整分布)。当需要确定性且耗时不到 1 毫秒的结果,并且愿意假设各类别相互独立时,使用 poisson_binomial。请参阅 resources/methodology.md。

  • monte_carlo:需要 sim_trace 以供审计、分布非正态,或传入各类别间的相关性时使用
  • poisson_binomial:需要快速的闭式近似,或在内部优化循环中调用此技能时使用

步骤 3:处理逆向类别

对于 cat_inverse_list 中的每个类别,反转比较方向:我方队伍的抽样值小于对手队伍的抽样值时,我方赢得该类别(ERA 3.50 优于 ERA 4.20)。最简洁的实现方式是在统计胜负之前,对逆向类别取反边际值 (our_draw - opp_draw) → (opp_draw - our_draw)。请参阅 resources/methodology.md。

  • 根据 cat_inverse_list 识别逆向类别
  • 按类别取反边际值(或反转比较方向)
  • 验证已知逆向类别的单类别获胜概率符合直觉

步骤 4:运行模拟

设置 random_seed 后,根据配置的分布(默认正态分布)抽取成对结果(每次模拟中每个类别各为双方抽取一个值),并对每次模拟计分。

  • 根据 random_seed 确定性地设置 RNG 种子
  • 对 n_simulations 中的每次模拟:
    • 为每个类别抽取 our_draw[cat] ~ Normal(our_mean, our_stddev)
    • 为每个类别抽取 opp_draw[cat] ~ Normal(opp_mean, opp_stddev)
    • 为每个类别计算边际值(逆向类别取反)
    • 统计 cats_won = sum(margin > 0)(平局规则:精确平局计为 0.5 或 0;参见护栏 #4)
    • 记录 matchup_win = (cats_won >= cat_win_threshold)

若使用 Poisson-binomial 模式,则改为:解析计算每个类别的获胜概率 p_i = Φ(margin_mean_i / combined_stddev_i)(逆向类别的边际值取反),然后应用 PB 递推计算 P(sum >= threshold)。

步骤 5:计算输出

  • matchup_win_probability = 各次模拟中 matchup_win 的平均值(MC),或 PB 的闭式结果。
  • per_cat_win_probability[cat] = 每个类别中 margin > 0 的比例均值(MC),或每个类别的 Φ(...)(PB)。
  • expected_cats_won = cats_won 的平均值(MC),或 Σ p_i(PB)。
  • variance_estimate = 各次模拟中 cats_won 的方差(MC),或 Σ p_i(1-p_i)(PB,因为类别按相互独立的伯努利变量建模)。

推导过程请参阅 resources/methodology.md。

步骤 6:输出结果并提供审计轨迹

返回完整的输出字典。如果 return_sim_trace=true,则将前 100 次模拟作为 sim_trace 返回,供调用方审计(展示每个类别的抽样值及最终的 cats_won 向量)。

  • 包含所有输出:matchup_win_probability、per_cat_win_probability、expected_cats_won、variance_estimate
  • 可选:sim_trace(仅包含前 100 次模拟,以控制负载大小)
  • 注明所用的 random_seed,以便调用方复现
  • 使用 resources/evaluators/rubric_matchup_win_probability_sim.json 验证。最低标准:平均分达到 3.5 分或以上。

常见模式

模式 1:MLB Yahoo 5x5(10 项数据)

  • cat_list:[R, HR, RBI, SB, OBP, K, ERA, WHIP, QS, SV]
  • cat_win_threshold:6
  • cat_inverse_list:[ERA, WHIP]
  • 需要按数量加权的比率类数据:OBP(按 PA 加权)、ERA(按 IP 加权)、WHIP(按 IP 加权)。调用方应预先计算能反映数量影响的标准差——半周内投出 20 IP 时,比率的方差会大于整周投出 55 IP 时的方差。
  • 典型运行时间:纯 Python 中运行 10k 次模拟用时不到 200ms

模式 2:NBA 9 项数据 H2H

  • cat_list:[PTS, REB, AST, STL, BLK, 3PM, FG%, FT%, TO]
  • cat_win_threshold:5
  • cat_inverse_list:[TO](失误——越低越好)
  • 比率类数据:FG%、FT%(分别按 FGA、FTA 加权)
  • 特别说明:NBA 各项数据之间的相关性高于 MLB(球队使用模式会关联 PTS-AST-3PM);如果有相关矩阵,请传入

模式 3:NHL 10 项数据或类似情况

  • cat_list 示例:[G, A, +/-, PIM, PPP, SOG, W, GAA, SV%, SO]
  • cat_win_threshold:6
  • cat_inverse_list:[GAA](场均失球数)
  • 比率类数据:SV%(按 SA 加权)、GAA(按已进行的比赛场次加权)

模式 4:周中实时对阵(部分比赛周已过去)

  • 调用方应传入反映本周剩余产出加当前累计总量的 {mean, stddev}。也就是说,mean = running_total + expected_remaining;剩余时间越少,stddev 越小。
  • mlb-category-state-analyzer 的 cat_position 可直接传入:已锁定的数据项应具有接近零的标准差,且均值应远离对手的分布。

注意事项

  1. 可复现性需要种子。如果不提供 random_seed,即使输入完全相同,两次调用返回的概率也会略有不同(蒙特卡洛误差)。对于审计日志和单元测试,务必传入种子。无论如何,Poisson-binomial 模式都是确定性的。

  2. 蒙特卡洛标准误。当 n_simulations = N 且真实概率为 p 时,标准误为 sqrt(p(1-p)/N)。当 N=10000 且 p=0.5 时,SE ≈ 0.005。如果调用方需要精确到小数点后三位,请使用 N >= 100000。

  3. 反向类别:取负的是差值,而不是均值。一种常见错误是在输入时对 mean 取负,这会导致 Poisson-binomial 的 Φ 计算符号翻转,却破坏标准差的解释。建议:输入保持自然单位(ERA = 3.85 就保持为 3.85),在比较时对计算出的差值取负。参见 resources/methodology.md。

  4. 必须说明平局判定规则。如果某次模拟中某项类别的 our_draw == opp_draw,规则可以是双方各自 cats_won += 0.5(H2H Cats 中“平局计作半场胜利”的方式),也可以是 cats_won += 0(严格多数制)。默认值:tie_rule = "half",与 Yahoo H2H 行为一致。请记录当前采用的规则。

  5. 正态分布假设不适用于极端计数类别。Saves 和 Home Runs 是低计数的离散变量;正态近似会给负值分配不可忽略的概率质量。对于均值较低的计数类别(mean < 5),调用方可以针对每个类别指定 distribution_family = "poisson";蒙特卡洛支持这种做法,Poisson-binomial 则不支持(因为 PB 需要基于 Φ 计算每个类别的概率——请使用带连续性校正的 Poisson-normal 近似来计算)。

  6. 比率类别需要按样本量加权。OBP、ERA、WHIP 是比率(对打席数或投球局数进行加权汇总)。比率的标准差取决于观测量:打席数少 → 标准差大。调用方需负责提供经过样本量调整的标准差(公式见 methodology:stddev_ratio ≈ σ_per_obs / sqrt(n_obs))。此技能将传入的标准差视为真实值。

  7. 独立性假设是一种简化。OBP 和 R 存在相关性(上垒的跑者会创造得分)。默认蒙特卡洛假设各类别之间相互独立。如果调用方传入 cat_correlation_matrix(正半定矩阵,维度等于 len(cat_list)),蒙特卡洛会通过对组合协方差矩阵进行 Cholesky 分解来使用它。Poisson-binomial 不支持相关性(PB 的核心就是独立的 Bernoulli 变量)。

  8. 阈值必须与联盟赛制一致。10-cat MLB(严格多数制)的 cat_win_threshold = 6,9-cat NBA 的阈值为 5,依此类推。传入错误的阈值会悄无声息地得到看似合理但实际错误的 matchup_win_probability。务必确认联盟对整体对决的平局判定规则(有些联盟会在汇总计数中将平局计作半场胜利)。

  9. 不要汇总不同的对决。单次调用的输出回答的是“本周对阵这位对手”的问题。根据每周胜率计算整个赛季的季后赛概率,属于下游调用方的工作(mlb-playoff-planner)。

  10. 说明方差估计的含义。variance_estimate 是获胜类别数(范围 0..N)的方差,并非 matchup_win_probability 的方差。后者是蒙特卡洛标准误的方差 p(1-p)/N。两者都很有用;如果同时返回,请明确标注。

快速参考

核心公式:

Monte Carlo (per sim):
  For each cat c:
    our_draw[c]  ~ Normal(our_mean[c],  our_stddev[c])
    opp_draw[c]  ~ Normal(opp_mean[c],  opp_stddev[c])
    margin[c]    = our_draw[c] - opp_draw[c]
    if c in cat_inverse_list: margin[c] *= -1
    cat_won[c]   = (margin[c] > 0)     # or 0.5 if exact tie and tie_rule="half"
  cats_won       = sum(cat_won across cats)
  matchup_won    = (cats_won >= cat_win_threshold)

Monte Carlo aggregate (over N sims):
  matchup_win_probability    = mean(matchup_won)
  per_cat_win_probability[c] = mean(cat_won[c])
  expected_cats_won          = mean(cats_won)
  variance_estimate          = var(cats_won)

Poisson-Binomial (closed form):
  combined_stddev[c] = sqrt(our_stddev[c]^2 + opp_stddev[c]^2)
  margin_mean[c]     = our_mean[c] - opp_mean[c]    # negated for inverse cats
  per_cat_win_prob[c] = Φ(margin_mean[c] / combined_stddev[c])
  P(exactly k of N wins) via PB recurrence:
    P_0(0) = 1
    P_i(k) = P_{i-1}(k) * (1 - p_i) + P_{i-1}(k-1) * p_i
  matchup_win_probability = Σ_{k >= threshold} P_N(k)
  expected_cats_won       = Σ p_i
  variance_estimate       = Σ p_i (1 - p_i)

模式选择指南:

需求使用
获取猫类别获胜次数的完整分布、审计追踪monte_carlo
亚毫秒级、确定性、精确的 PB 结果poisson_binomial
猫类别之间的相关性(例如,OBP-R)monte_carlo(搭配相关性矩阵)
低均值计数猫类别(短周期内的 SV、HR)monte_carlo,并设置 distribution_family="poisson"
在内部优化循环中(数千次调用)poisson_binomial
每周策略的默认模式monte_carlo,并设置 n_simulations=10000

所需输入:

  • our_per_cat_projection:dict[cat, {mean: float, stddev: float}]
  • opp_per_cat_projection:dict[cat, {mean: float, stddev: float}]
  • cat_list:list[str] — 按规范顺序排列的类别名称
  • cat_win_threshold:int(10 猫类别时为 6,9 猫类别时为 5)
  • cat_inverse_list:list[str] — 数值越低越好的猫类别
  • n_simulations:int(默认值为 10000)
  • random_seed:int(可选,但建议提供)
  • sim_mode:"monte_carlo"(默认值)或 "poisson_binomial"
  • tie_rule:"half"(默认值)或 "strict"
  • cat_correlation_matrix:可选的 float[N][N]
  • distribution_family:可选的按猫类别划分的 dict[cat, "normal"|"poisson"]
  • return_sim_trace:bool(默认值为 false)

生成的输出:

  • matchup_win_probability:float,范围为 [0, 1]
  • per_cat_win_probability:dict[cat, float]
  • expected_cats_won:float
  • variance_estimate:float(猫类别获胜次数的方差)
  • sim_trace:可选的 list[dict](前 100 次模拟;仅当 return_sim_trace=true 时提供)
  • meta:用于审计的 {sim_mode, n_simulations, random_seed, tie_rule}

关键资源:

上游调用方(示例):

  • mlb-category-state-analyzer — 传入按猫类别划分的剩余周预测(参见 frameworks/game-theory-principles.md 中的原则 #1、#5、#6)
  • NBA/NHL 中任何对应的 fantasy *-category-state-analyzer
  • 任何具备按猫类别划分的 {mean, stddev}、并需要对阵级获胜概率的调用方

评论

支持 Markdown