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自チームの平均自チームの標準偏差相手の平均相手の標準偏差逆指標?
R428387いいえ
HR123.5144いいえ
RBI409418いいえ
SB62.542いいえ
OBP0.3350.0150.3280.014いいえ
K5510509いいえ
ERA3.850.454.100.50はい
WHIP1.220.081.280.09はい
QS41.531.4いいえ
SV21.251.5いいえ

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)の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 をそのまま渡します。確定済みのカテゴリーは、標準偏差をほぼゼロにし、平均値を相手の分布から大きく離してください。

ガードレール

  1. 再現性にはシードが必要です。random_seed を指定しない場合、同じ入力で呼び出しても確率はわずかに異なります(モンテカルロ誤差)。監査ログやユニットテストでは、必ずシードを渡してください。ポアソン二項モードは、いずれの場合も決定論的です。

  2. モンテカルロ標準誤差。n_simulations = N、真の確率が p のとき、標準誤差は sqrt(p(1-p)/N) です。N=10000、p=0.5 の場合、標準誤差は約 0.005 です。小数第 3 位までの精度が必要な場合は、N >= 100000 を使用してください。

  3. 逆カテゴリでは平均ではなくマージンを反転します。よくあるバグは、入力時に mean を反転することです。これにより、ポアソン二項の Φ 計算の符号は反転しますが、標準偏差の解釈が崩れます。推奨方法は、入力を本来の単位のまま保持し(ERA = 3.85 は 3.85 のまま)、比較時に計算済みのマージンを反転することです。resources/methodology.md を参照してください。

  4. タイブレークの規則を明記する必要があります。あるシミュレーションで特定のカテゴリの our_draw == opp_draw の場合、両サイドについて cats_won += 0.5(H2H Cats の「引き分けは 0.5 勝として数える」方式)、または cats_won += 0(過半数のみを勝ちとする方式)とします。デフォルトは Yahoo H2H の動作に合わせた tie_rule = "half" です。どちらの規則が適用されるかを記録してください。

  5. 正規分布の仮定は、値が極端なカウント系カテゴリでは成り立ちません。セーブ数や本塁打数は、値の小さい離散量です。正規近似では、負の値にも無視できない確率質量が割り当てられます。平均が低いカウント系カテゴリ(mean < 5)では、呼び出し側がカテゴリごとに distribution_family = "poisson" を指定できます。モンテカルロではこれを処理できますが、ポアソン二項では処理できません(PB ではカテゴリごとの確率に基づく Φ が必要です。連続性補正を用いたポアソン正規近似から算出してください)。

  6. 比率カテゴリにはボリュームによる重み付けが必要です。OBP、ERA、WHIP は PA または IP にわたる加重集計である比率です。比率の標準偏差は観測数に依存します。PA が少ないほど、標準偏差は大きくなります。呼び出し側は、観測数を調整した標準偏差を指定する必要があります(計算式は methodology の stddev_ratio ≈ σ_per_obs / sqrt(n_obs) を参照してください)。このスキルでは、指定された標準偏差を正しい値として扱います。

  7. 独立性の仮定は単純化したものです。OBP と R には相関があります(出塁した走者は得点につながります)。デフォルトのモンテカルロでは、カテゴリ間の独立性を仮定します。呼び出し側が cat_correlation_matrix(正半定値で、次元は len(cat_list) と一致)を渡すと、モンテカルロでは結合共分散のコレスキー分解を用いて処理します。ポアソン二項では相関を受け付けません(PB の要点は独立したベルヌーイ試行です)。

  8. しきい値はリーグ形式に合わせる必要があります。10-cat MLB(過半数のみを勝ちとする方式)では cat_win_threshold = 6、9-cat NBA では 5 などです。誤ったしきい値を渡すと、意味のある値ではあるものの誤った matchup_win_probability が黙って生成されます。対戦全体についても、リーグのタイブレーク規則を必ず確認してください(リーグによっては、合計数が同数の場合に引き分けを半勝として扱います)。

  9. 異なる対戦を集計しないでください。1 回の呼び出しの出力は「今週、この対戦相手と対戦した場合」に答えるものです。週ごとの勝率からシーズン全体のプレーオフ進出確率を重み付けする処理は、下流の呼び出し側(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)

各モードの使い分け:

必要なもの使用するモード
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] の範囲の float
  • per_cat_win_probability: dict[cat, float]
  • expected_cats_won: float
  • variance_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} があり、対戦単位の勝率を求める呼び出し元

コメント