matchup-win-probability-sim について
両チームの予測値と不確実性から、ファンタジースポーツのカテゴリ対戦の勝率を推定するワークフロー用スキルです。モンテカルロ法とポアソン二項計算を備え、逆方向カテゴリや再現可能な実行にも対応します。
主な機能
- 01モンテカルロ対戦シミュレーション
- 02ポアソン二項計算
- 03逆方向カテゴリの比較
- 04カテゴリ別・全体の勝率
- 05分散推定と監査トレース
活用シーン
- 01ファンタジー対戦の勝率推定
- 02カテゴリごとの強みと弱みの比較
- 03最適化ループ内での高速な決定論的推定
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ lyndonkl/ claude --skill matchup-win-probability-simインストール後、Claude Code で/matchup-win-probability-simを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
resources/methodology.mdtemplate.mdresources/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 | 自チームの平均 | 自チームの標準偏差 | 相手の平均 | 相手の標準偏差 | 逆指標? |
|---|---|---|---|---|---|
| R | 42 | 8 | 38 | 7 | いいえ |
| HR | 12 | 3.5 | 14 | 4 | いいえ |
| RBI | 40 | 9 | 41 | 8 | いいえ |
| SB | 6 | 2.5 | 4 | 2 | いいえ |
| OBP | 0.335 | 0.015 | 0.328 | 0.014 | いいえ |
| K | 55 | 10 | 50 | 9 | いいえ |
| ERA | 3.85 | 0.45 | 4.10 | 0.50 | はい |
| WHIP | 1.22 | 0.08 | 1.28 | 0.09 | はい |
| QS | 4 | 1.5 | 3 | 1.4 | いいえ |
| SV | 2 | 1.2 | 5 | 1.5 | いいえ |
random_seed=42、cat_win_threshold=6、n_simulations=10000で両方のモードを実行します。
モンテカルロ出力:
matchup_win_probability= 0.612expected_cats_won= 6.18variance_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.605expected_cats_won= 6.18(正確な値 — カテゴリー別確率の合計)variance_estimate= 2.11(独立したベルヌーイ変数の合計の分散)
解釈:自チームはやや優勢です(約61%)。SVは完全に捨てているカテゴリーです(勝率8%)。HRは競っていますが、負ける見込みです。最も勝ち筋が堅いのはSB、QS、WHIP、ERA、R、K(およびOBP)の6カテゴリーです。後続の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である(stddev が 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 を使用します(勝利した猫の数の分布全体を得られます)。決定論的なサブミリ秒の結果が必要で、猫ごとの独立性を仮定できる場合は poisson_binomial を使用します。resources/methodology.md を参照してください。
- 監査用の
sim_traceが必要な場合、分布が正規分布でない場合、または猫ごとの相関が渡される場合はmonte_carlo - 高速な閉形式の近似が必要な場合、またはこのスキルを内部最適化ループ内で呼び出す場合は
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 を設定したうえで、設定された分布(デフォルトは正規分布)からペアの結果(シミュレーションごとに各チーム・各猫につき 1 つ)を抽出し、各シミュレーションを採点します。
-
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 の 1 週間と比べて比率の分散が大きくなります。
- 一般的な実行時間: 純粋な 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をそのまま渡します。確定済みのカテゴリーは、標準偏差をほぼゼロにし、平均値を相手の分布から大きく離してください。
ガードレール
-
再現性にはシードが必要です。
random_seedを指定しない場合、同じ入力で呼び出しても確率はわずかに異なります(モンテカルロ誤差)。監査ログやユニットテストでは、必ずシードを渡してください。ポアソン二項モードは、いずれの場合も決定論的です。 -
モンテカルロ標準誤差。
n_simulations = N、真の確率がpのとき、標準誤差はsqrt(p(1-p)/N)です。N=10000、p=0.5の場合、標準誤差は約 0.005 です。小数第 3 位までの精度が必要な場合は、N >= 100000を使用してください。 -
逆カテゴリでは平均ではなくマージンを反転します。よくあるバグは、入力時に
meanを反転することです。これにより、ポアソン二項のΦ計算の符号は反転しますが、標準偏差の解釈が崩れます。推奨方法は、入力を本来の単位のまま保持し(ERA = 3.85 は 3.85 のまま)、比較時に計算済みのマージンを反転することです。resources/methodology.md を参照してください。 -
タイブレークの規則を明記する必要があります。あるシミュレーションで特定のカテゴリの
our_draw == opp_drawの場合、両サイドについてcats_won += 0.5(H2H Cats の「引き分けは 0.5 勝として数える」方式)、またはcats_won += 0(過半数のみを勝ちとする方式)とします。デフォルトは Yahoo H2H の動作に合わせたtie_rule = "half"です。どちらの規則が適用されるかを記録してください。 -
正規分布の仮定は、値が極端なカウント系カテゴリでは成り立ちません。セーブ数や本塁打数は、値の小さい離散量です。正規近似では、負の値にも無視できない確率質量が割り当てられます。平均が低いカウント系カテゴリ(
mean < 5)では、呼び出し側がカテゴリごとにdistribution_family = "poisson"を指定できます。モンテカルロではこれを処理できますが、ポアソン二項では処理できません(PB ではカテゴリごとの確率に基づくΦが必要です。連続性補正を用いたポアソン正規近似から算出してください)。 -
比率カテゴリにはボリュームによる重み付けが必要です。OBP、ERA、WHIP は PA または IP にわたる加重集計である比率です。比率の標準偏差は観測数に依存します。PA が少ないほど、標準偏差は大きくなります。呼び出し側は、観測数を調整した標準偏差を指定する必要があります(計算式は methodology の
stddev_ratio ≈ σ_per_obs / sqrt(n_obs)を参照してください)。このスキルでは、指定された標準偏差を正しい値として扱います。 -
独立性の仮定は単純化したものです。OBP と R には相関があります(出塁した走者は得点につながります)。デフォルトのモンテカルロでは、カテゴリ間の独立性を仮定します。呼び出し側が
cat_correlation_matrix(正半定値で、次元はlen(cat_list)と一致)を渡すと、モンテカルロでは結合共分散のコレスキー分解を用いて処理します。ポアソン二項では相関を受け付けません(PB の要点は独立したベルヌーイ試行です)。 -
しきい値はリーグ形式に合わせる必要があります。10-cat MLB(過半数のみを勝ちとする方式)では
cat_win_threshold = 6、9-cat NBA では5などです。誤ったしきい値を渡すと、意味のある値ではあるものの誤ったmatchup_win_probabilityが黙って生成されます。対戦全体についても、リーグのタイブレーク規則を必ず確認してください(リーグによっては、合計数が同数の場合に引き分けを半勝として扱います)。 -
異なる対戦を集計しないでください。1 回の呼び出しの出力は「今週、この対戦相手と対戦した場合」に答えるものです。週ごとの勝率からシーズン全体のプレーオフ進出確率を重み付けする処理は、下流の呼び出し側(
mlb-playoff-planner)の役割です。 -
分散推定値の意味を記録してください。
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)
各モードの使い分け:
| 必要なもの | 使用するモード |
|---|---|
| cats-won の完全な分布、監査証跡 | monte_carlo |
| 1 ミリ秒未満の実行時間、決定論的で正確な 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:[0, 1]の範囲のfloatper_cat_win_probability:dict[cat, float]expected_cats_won:floatvariance_estimate:float(cats-won 数の分散)sim_trace: 任意のlist[dict](最初の 100 回のシミュレーション。return_sim_trace=trueの場合のみ含まれます)meta: 監査用の{sim_mode, n_simulations, random_seed, tie_rule}
主なリソース:
- resources/template.md:入力スキーマ、出力スキーマ、両方のモードを使った MLB の 5x5 の実例
- resources/methodology.md:モンテカルロ法の定式化、ポアソン二項分布の漸化式、分散の導出、逆方向および比率カテゴリーの処理、モード選択基準
- resources/evaluators/rubric_matchup_win_probability_sim.json:入力仕様の正確性、MC の精度、PB の精度、逆方向カテゴリーの処理、比率カテゴリーのボリューム加重、しきい値の適用、再現性、出力の完全性、分散の推定、引用に関する 10 項目の基準
上流の呼び出し元(例):
mlb-category-state-analyzer— カテゴリーごとの残り週の予測値を渡します(frameworks/game-theory-principles.mdの原則 #1、#5、#6)- NBA/NHL 向けの同等のファンタジー系
*-category-state-analyzer - カテゴリーごとの
{mean, stddev}があり、対戦単位の勝率を求める呼び出し元