五項分布モデル
前提知識:SPRT、対数尤度比(LLR)
このページの要点
- 五項分布(pentanomial)は、ペアゲーム(同じ局面で先後を入れ替えた 2 局)の結果を 5 カテゴリに分類するモデル
- 先後の非対称性(先手有利)を統計的にキャンセルし、推定精度を向上させる
- 5 カテゴリのスコアは 0.0, 0.5, 1.0, 1.5, 2.0 で、ペアの合計勝ち数に対応する
- 標準的な三項分布(勝ち、引き分け、負け)と比較して、所要対局数を削減できる
ペアゲームとは
エンジンテストでは、先手の有利性が結果に大きなバイアスを与えます。 このバイアスを除去するため、同じ開始局面(SFEN)で先後を入れ替えた 2 局をペアとして扱います。
ペアゲーム(同一SFEN)
┌─────────────────────────────┐
│ Game 1: Engine A (先手) vs B (後手) │
│ Game 2: Engine A (後手) vs B (先手) │
└─────────────────────────────┘
各ペアにおける Engine A の合計スコア(勝ち=1.0, 引き分け=0.5, 負け=0.0)を計算します。
5 つのカテゴリ
ペアの合計スコアは 5 つの値のいずれかになります。
| スコア | Game 1 | Game 2 | 解釈 |
|---|---|---|---|
| 2.0 | 勝ち | 勝ち | 両局とも勝利。圧倒的な強さの証拠 |
| 1.5 | 勝ち | 引分 or 引分/勝ち | 1 勝 1 引き分け。明確な優位 |
| 1.0 | 勝ち/負け or 引分/引分 | 負け/勝ち or 引分/引分 | 互角 |
| 0.5 | 負け | 引分 or 引分/負け | 1 敗 1 引き分け。明確な劣位 |
| 0.0 | 負け | 負け | 両局とも敗北。圧倒的な弱さ |
先後バイアスと分散の削減
先後バイアスの除去
三項分布モデル(各局を独立に扱う)では、先手の勝率バイアスが推定を歪めます。
三項分布: 各ゲームが独立
→ 先手有利が混入し、推定 Elo 差にバイアス
五項分布: ペアで先後をキャンセル
→ 先後バイアスが相殺され、純粋な実力差を推定
分散の削減
ペアゲームは**共通ランダム数(CRN)**の原理に基づいています。 同じ開始局面を使うことで、局面固有のランダム性を相殺し、推定の分散を大幅に削減します。
実装
ShogiArena では、五項分布を compute_pentanomial() 関数で計算しています。
ステップ 1:対局のグループ化
対局を(エンジンペア, SFEN)でグループ化し、先後を入れ替えたペアを形成します。
# エンジン e1 が先手の対局と後手の対局に分離
g_e1_black = [g for g in games if str(g["black_player"]) == e1]
g_e1_white = [g for g in games if str(g["white_player"]) == e1]
ステップ 2:ペアの形成とスコア計算
for i in range(min(len(g_e1_black), len(g_e1_white))):
g1 = g_e1_black[i] # e1 が先手
g2 = g_e1_white[i] # e1 が後手
score = 0.0
# Game 1: e1 が先手で勝ったら +1.0, 引き分けなら +0.5
if g1.result.is_black_win():
score += 1.0
elif g1.result.is_draw():
score += 0.5
# Game 2: e1 が後手で勝ったら +1.0, 引き分けなら +0.5
if g2.result.is_white_win():
score += 1.0
elif g2.result.is_draw():
score += 0.5
bins[f"{score:.1f}"] += 1
ステップ 3:分布の集計
出力は 5 つのビン(0.0, 0.5, 1.0, 1.5, 2.0)のカウントです。
# 結果例
{
"2.0": 45, # 両方で勝利
"1.5": 120, # 1勝1引分
"1.0": 250, # 互角
"0.5": 65, # 1敗1引分
"0.0": 20, # 両方で敗北
}
Fishtest での実例
Fishtest(Stockfish のテストフレームワーク)のテスト結果を例に、五項分布の実践的な読み方を説明します。
SPRT: elo0: -1.75 alpha: 0.05 elo1: 0.25 beta: 0.05 (normalized)
Pentanomial: [55, 11390, 30659, 11490, 70]
LLR: 2.94 [-2.94, 2.94] (accepted)
この結果は次のように読みます。
Pentanomialの 5 つの数値は \([n_{0.0}, n_{0.5}, n_{1.0}, n_{1.5}, n_{2.0}]\) に対応する- 総ペア数は 55 + 11390 + 30659 + 11490 + 70 = 53,664 ペア
- 総対局数はその 2 倍で 53,664 × 2 = 107,328 局
- \(n_{1.5}\)(1 勝 1 引分)が \(n_{0.5}\)(1 敗 1 引分)よりわずかに多く、テストエンジンがわずかに優位
- \(n_{2.0}\)(両勝)と \(n_{0.0}\)(両敗)はともに少なく、実力差が小さいことを示す
- LLR が上限 2.94 に到達したため
(accepted)となり、改善ありと判定された
総対局数の算出
五項分布から総対局数を求めるには、全カテゴリの合計(= ペア数)を 2 倍します。
\[ \text{総対局数} = 2 \times \sum_{k} n_k \]
三項分布との結果の違い
同じ対局データでも、三項分布(各局を独立に集計)と五項分布(ペアで集計)では表現力が異なります。
例えば、先手有利な定跡を使った場合に「両者とも先手で勝利」するケースを考えます。
- 三項分布:勝ち 1 と負け 1 として記録され、互角に見える
- 五項分布:スコア 1.0(\(n_{1.0}\) のうち「負勝」の組み合わせ)として記録され、定跡バイアスの影響を区別できる
一方、\(n_{2.0}\)(両勝)や \(n_{1.5}\)(勝+引分)のカテゴリは定跡の影響によらない純粋な実力差を反映しやすく、五項分布はこうした情報を保存できます。
統計的解釈
分布からの指標計算
五項分布からは、次の統計量を導出できます。
正規化ペアスコア(0.5 が互角):
\[ \bar{s} = \frac{\sum_{k} k \cdot n_k}{2 \cdot \sum_{k} n_k} \]
ここで \(n_k\) はスコア \(k\) のカウント、分母の 2 は最大スコアで割って 1 局あたりのスケールに揃えるための係数です。 この \(\bar{s}\) が 0.5 を超えていれば Engine A が優位です。 正規化せずペアスコアのまま扱う場合(後述の \(\hat{s}\))は、互角の基準が 1.0 になります。
三項分布との比較
| 特性 | 三項分布 | 五項分布 |
|---|---|---|
| 単位 | 1 局 | 1 ペア(2 局) |
| カテゴリ数 | 3(勝ち、引き分け、負け) | 5(0.0〜2.0) |
| 先後バイアス | 混入する | 相殺される |
| 分散 | 大きい | 小さい |
| 必要対局数 | 多い | 少ない |
五項分布を用いた LLR 計算
五項分布は LLR の計算にも適用できます。 各ペアの結果に対する尤度比を、5 カテゴリに基づいて計算します。
従来の SPRT: 1 ゲームごとに LLR 更新(3 値: 勝/引/負)
五項 SPRT: 1 ペアごとに LLR 更新(5 値: 0.0/0.5/1.0/1.5/2.0)
GSPRT-LLR の五項分布版
五項頻度 \([n_0, n_1, n_2, n_3, n_4]\) に対する LLR 計算は、三項分布と同一の GSPRT フレームワークで行えます。 違いはカテゴリ数とスコアの値域だけです。
| 三項分布 | 五項分布 | |
|---|---|---|
| カテゴリ数 | 3 | 5 |
| スコア値 | 0, 0.5, 1.0 | 0, 0.5, 1.0, 1.5, 2.0 |
| 互角のスコア | 0.5 | 1.0 |
| サンプル単位 | 1 局 | 1 ペア |
近似 LLR 公式(五項分布)
\[ \text{LLR} \approx \frac{N_{\text{pairs}} \cdot (s_1 - s_0)(2\hat{s} - s_0 - s_1)}{2 \hat{\sigma}^2} \]
ここで \(\hat{s}\) はペアスコアの期待値、\(\hat{\sigma}^2\) はその分散、\(N_{\text{pairs}}\) はペア数です。 五項分布では \(s_0, s_1\) もペアスコアのスケールに変換する必要があります。
数値例
五項頻度 \([20, 65, 250, 120, 45]\)(500 ペア = 1000 局)の場合は次のようになります。
\[ \hat{s} = \frac{0 \cdot 20 + 0.5 \cdot 65 + 1.0 \cdot 250 + 1.5 \cdot 120 + 2.0 \cdot 45}{500} = 1.01 \]
ペアスコアの期待値が 1.01(> 1.0 = 互角)であり、Engine A がわずかに優位であることを示唆します。
効率性の向上
五項 SPRT は従来の SPRT と比べて、同じ精度の判定を 20-40% 少ない対局数で達成できることが知られています。1
シミュレーション結果(Elo 差 10, elo0=0, elo1=5, α=β=0.05)を示します。
| モデル | パス確率 | 期待対局数 | 節約率 |
|---|---|---|---|
| 三項分布 | 96.8% | ~2,191 | 基準 |
| 五項分布 | 95.0% | ~1,809 | 17.4% |
この差は、ペアゲーム内の相関をモデルに取り込み、同じ対局数から取り出せる情報を増やすことで生じます。2
開局集バイアスの推定
五項分布と三項分布の結果を比較すると、開局集(定跡ファイル)に含まれるバイアスの RMS 値を推定できます。
アカウンティング恒等式
五項頻度と三項頻度の間には、恒等式(accounting identity)が成り立ちます。3 三項分布から推定したスコアと五項分布から推定したスコアは一致する一方、分散は一致しません。 この分散の差が、開局集のバイアスに対応します。
Var_trinomial = Var_pentanomial + Var_bias
→ Var_bias = Var_trinomial - Var_pentanomial
→ RMS_bias = sqrt(Var_bias)
開局集の各局面は、一方のエンジンに有利という固有の偏りを持ちます。 ペアゲームでは先後を入れ替えるため、この偏りは相殺されます。 三項分布は偏りを含んだ分散を計算し、五項分布は偏りが相殺された後の分散を計算するので、その差が開局集バイアスの推定量になります。
実装リファレンス
| ファイル | 関数 | 役割 |
|---|---|---|
_core/shared/kernel/statistics/pentanomial.py | compute_pentanomial() | 五項分布の計算 |
Fishtest stats/LLRcalc.py | LLR_logistic() | 三項/五項の自動選択 LLR |
Fishtest stats/LLRcalc.py | results_to_pdf() | 頻度 → 確率分布の変換 |
| vdbergh/pentanomial | SPRT_pentanomial.py | 五項 SPRT の参照実装 |
参考文献
Michel Van den Bergh, "Pentanomial statistics" — 五項分布モデルの理論的基盤と効率性の分析
Games in a game pair are highly correlated — ペアゲーム内の相関の実証的分析
Michel Van den Bergh, "Accounting Identity" — 五項分布と三項分布の関係と開局集バイアスの推定
次に読む
- SPSA(同時摂動確率近似法):エンジンパラメータの最適化手法