Elo レーティング
前提知識:確率と統計の基礎(期待値、対数、ロジスティック関数)
このページの要点
- Elo レーティングは勝率をログスケールに変換したもの。400 点差で勝率 10:1
- 期待スコアはロジスティック関数で計算し、K ファクターで更新速度を制御する
- 信頼区間を計算すると、レーティングの不確かさを定量的に示せる
- Elo 単体では「差がある」ことしかわからない。「差が統計的に有意か」を判定するには SPRT が必要
Elo レーティングとは
Elo レーティングは、ハンガリー系アメリカ人の物理学者アルパッド・エロ(Arpad Elo)が 1960 年代にチェスのために考案したレーティングシステムです。1 現在では将棋、囲碁、テニス、サッカーなど幅広い競技で使用されています。
このシステムは、2 者間の勝率をレーティング差という単一のスカラー値で表現します。 勝率そのものは対戦相手ごとに決まる量ですが、各プレイヤーに一つの数値を割り当て、その差から勝率を復元する形にすれば、多数のプレイヤーを一本の尺度に並べられます。
勝率とレーティング差の関係
レーティング差 \(\Delta R = R_A - R_B\) から、プレイヤー A の期待スコア(勝率)を求める式:
\[ E_A = \frac{1}{1 + 10^{-\Delta R / 400}} \]
これはロジスティック関数(シグモイド関数)の一種で、レーティング差が 400 増えるごとに勝敗のオッズが 10 倍になるように目盛りが取られています。
| レーティング差 | 勝率 | 解釈 |
|---|---|---|
| 0 | 50.0% | 互角 |
| 50 | 57.1% | わずかに優位 |
| 100 | 64.0% | 明確な優位 |
| 200 | 76.0% | 大きな差 |
| 400 | 90.9% | 圧倒的 |
逆変換:勝率から Elo 差へ
観測された勝率 \(p\) から Elo 差を逆算する式:
\[ \Delta R = -400 \cdot \log_{10}\left(\frac{1}{p} - 1\right) \]
ShogiArena の実装では、\(p\) を \([0.001, 0.999]\) にクランプして数値的安定性を確保しています。
def _win_rate_to_elo(self, win_rate: float) -> float:
win_rate = max(0.001, min(0.999, win_rate))
return -400.0 * math.log10(1.0 / win_rate - 1.0)
レーティングの更新
対局結果に基づいてレーティングを更新する標準的な Elo 更新式:
\[ R'_A = R_A + K \cdot (S_A - E_A) \]
ここで:
| 記号 | 意味 |
|---|---|
| \(R_A\) | 現在のレーティング |
| \(R'_A\) | 更新後のレーティング |
| \(K\) | K ファクター(更新の重み) |
| \(S_A\) | 実際のスコア(勝ち=1.0, 引き分け=0.5, 負け=0.0) |
| \(E_A\) | 期待スコア |
K ファクターの意味
K ファクターは、1 局の結果がレーティングをどれだけ動かすかを決めるパラメータです。
- K が大きい:少ない対局でレーティングが大きく変動する(応答が速いが不安定)
- K が小さい:レーティングが安定する代わりに、真の強さに追いつくまでに多くの対局を要する
ShogiArena のデフォルトは \(K = 16\) で、これはチェスの FIDE レーティングで一般的な値です。
引き分けの扱い
将棋エンジンの対局では、引き分け(千日手、持将棋、256 手制限など)は 0.5 点として扱います。
# 実際のスコア計算
if result.is_black_win():
black_score = 1.0
elif result.is_draw():
black_score = 0.5 # 引き分けは半分のスコア
else:
black_score = 0.0
white_score = 1.0 - black_score
信頼区間
レーティングは点推定値であり、観測された対局数が少ないほど不確かさが大きくなります。 信頼区間を計算すると、真のレーティング差がどの範囲に収まるかを定量的に示せます。
Elo 差の標準誤差
\[ \text{SE} = \frac{400}{\ln 10} \cdot \sqrt{\frac{1}{n \cdot p \cdot (1 - p)}} \]
ここで \(n\) は対局数、\(p\) は勝率です。
95% 信頼区間
\[ \Delta R \pm z_{0.975} \cdot \text{SE} \]
\(z_{0.975} = 1.96\) は標準正規分布の 97.5 パーセンタイルです。
具体例
100 局で勝率 60%(\(p = 0.6\))の場合:
\[ \text{SE} = \frac{400}{\ln 10} \cdot \sqrt{\frac{1}{100 \cdot 0.6 \cdot 0.4}} = 173.7 \cdot 0.204 = 35.5 \]
\[ \Delta R = -400 \cdot \log_{10}(1/0.6 - 1) = 70.4 \]
95% 信頼区間は \(70.4 \pm 1.96 \cdot 35.5 = [0.8, 140.0]\) です。
点推定は +70.4 Elo でも、この結果から言えるのは「Elo 差は 0.8 から 140.0 の間にある」までです。 下限が 0 のすぐ上にあるので、100 局では優位性の大きさを絞り込めません。
Elo だけでは足りないこと
区間推定まで進めても、エンジンテストで必要な判断には届きません。
- 仮説検定ではない:「差がある」とは言えても、「その差が統計的に有意か」は判定できない
- 点推定値にサンプルサイズが現れない:10 局の +100 Elo と 1000 局の +100 Elo が同じ数値として並ぶ
- 打ち切りの基準がない:何局指せば十分かを事前に決められない
これらを扱うのが SPRT(逐次確率比検定) です。
実装リファレンス
| ファイル | クラス/関数 | 役割 |
|---|---|---|
_core/contexts/game_session/application/elo_rating_service.py | EloRatingService | レーティング計算の本体 |
_core/shared/kernel/statistics/btd_rating.py | BTDEstimator | 複数エンジンの強さ推定 |
_core/shared/kernel/statistics/pentanomial.py | compute_pentanomial() | 対局ペアの集計 |
参考文献
Arpad E. Elo (1978). The Rating of Chessplayers, Past and Present. Arco Publishing.
次に読む
- BayesElo と引き分けモデル:引き分け率を独立したパラメータとして扱う Elo の拡張と LOS
- 正規化 Elo(nElo):引き分け率に依存しない強さの指標