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 倍になるように目盛りが取られています。

レーティング差勝率解釈
050.0%互角
5057.1%わずかに優位
10064.0%明確な優位
20076.0%大きな差
40090.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 だけでは足りないこと

区間推定まで進めても、エンジンテストで必要な判断には届きません。

  1. 仮説検定ではない:「差がある」とは言えても、「その差が統計的に有意か」は判定できない
  2. 点推定値にサンプルサイズが現れない:10 局の +100 Elo と 1000 局の +100 Elo が同じ数値として並ぶ
  3. 打ち切りの基準がない:何局指せば十分かを事前に決められない

これらを扱うのが SPRT(逐次確率比検定) です。

実装リファレンス

ファイルクラス/関数役割
_core/contexts/game_session/application/elo_rating_service.pyEloRatingServiceレーティング計算の本体
_core/shared/kernel/statistics/btd_rating.pyBTDEstimator複数エンジンの強さ推定
_core/shared/kernel/statistics/pentanomial.pycompute_pentanomial()対局ペアの集計

参考文献

1

Arpad E. Elo (1978). The Rating of Chessplayers, Past and Present. Arco Publishing.

次に読む