[R] Bradley-Terry model を用いてプレイヤー間の勝敗予測を行う

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

リーグ戦の勝敗表からチームの”強さ”を導きたい

野球やサッカーチームなどの複数のプレイヤーの勝敗表をもとにプレイヤーの「強さ」を表す一次元的な量を測りたい場合があります。

例えば以下の様な動物のチーム対戦表があったとしましょう

  トカゲ カエル
NA 6 8
トカゲ 10 NA 14
カエル 8 2 NA

トカゲが亀に10勝6敗, カエルが亀に8勝8敗といった具合です。

この時トカゲが亀に勝つオッズは 10 / 6 = 1.66..., カエルが亀に勝つオッズは 8 / 8 = 0.5 となります。

トカゲの強さ、亀の強さ、カエルの強さを表すような量があると仮定しましょう。その上でその強さの比からオッズを計算できるとしたら過去の勝敗表をみなくても単純な計算のみでどちらが勝つかが瞬時に判断できるようになり、都合がよさそうです。

勝敗表から計算されたオッズをプレイヤーの強さの比で記述できると仮定したモデルを Bradley-Terry のモデルといいます

Bradley-Terry model

ここからは数式による説明になります。

K 人のプレイヤーがいるようなコンテスト(リーグ戦)で、プレイヤー 1,...,K の「強さ」がそれぞれ

btm-fig.1

であるとします。その上で、Bradley-Terryモデルは各プレイヤー間での勝敗のオッズが次のようになると仮定します。

btm-fig.2

ここで左辺はプレイヤー i がプレイヤー j に勝つオッズを示します。

オッズと確率pの間には関係式

btm-fig.3

が成り立ちますが、これとロジット関数

btm-fig.4

を用いれば、

btm-fig.5

とできます。ここで

btm-fig.6

です。ロジット関数はロジスティクシグモイド関数の逆関数ですから、確率自体は

btm-fig.7

とできます。

今、強さの対数である各 λ_i が各プレイヤーiの説明変数 x_ri の線形和とエラー項 U_i に依存していると仮定しましょう

btm-fig.8

すると、確率を説明変数の関数として捉えて、下記のような形式で書き表せます。

btm-fig.9

n は i, j のいずれかをとり、w_ir = β_r, w_jr = -β_r, w_ij0 は U_i - U_j を示しています。

これは一般化線形モデルとして知られる形式のモデルで、Rの標準的な組み込み関数であるglmを用いてパラメータを算出できます。

算出されたパラメータを使えば λ_i, λ_j が得られ、元の仮定された強さである α_i ( = exp(λ_i) ) も求められるという仕組みになっています。

λ に対する線形和 + U の仮定は別の形式で置くことで、より一般化されたモデル(一般化非線形混合モデル)で解くことが可能とのことです、本記事ではとくに扱いませんが、気になる方はExtended’ Bradley-Terry models for pair comparisonのスライドを御覧ください。

BradleyTerry2 パッケージを使う

RではBradleyTerry2パッケージを用いればBradley-Terryモデルを使って勝敗表から強さを求められます。

まずライブラリのインポートです。

install.packages("BradleyTerry2", dependencies = TRUE)
library("BradleyTerry2")

実行するとCRANのサイトからパッケージのダウンロードが行われます。

BradleyTerry2パッケージにはあらかじめ1987年の東部アメリカにおける野球チームの試合結果が用意されており、これは以下のようにbaseball変数に束縛できます。

data("baseball", package = "BradleyTerry2")

変数の中身を上から見てみましょう。

head(baseball)

出力結果です

  home.team away.team home.wins away.wins
1 Milwaukee   Detroit         4         3
2 Milwaukee   Toronto         4         2
3 Milwaukee  New York         4         3
4 Milwaukee    Boston         6         1
5 Milwaukee Cleveland         4         2
6 Milwaukee Baltimore         6         0

各カラムの表す意味はそのままの意味で、左から順にホームチーム、アウェーチーム、ホームチーム勝数、アウェーチーム勝数です

Rのhead関数は第二引数になにも指定しないと上から6つの中身を取り出します。

用意されたbaseballのデータを用いて強さを算出してみましょう

baseballModel <- BTm(
  outcome = cbind(home.wins, away.wins), 
  player1 = home.team, player2 = away.team, 
  data = baseball, id = "team")
baseballModel

BTm関数はBradleyTerryモデルにもとづいてモデルを構築します:

  • outcome引数 二項の応答データ(ここではチームの勝数)をいれます。失敗、成功を数値を表すベクトルを入れたり、またはNx2の行列をいれたりします。
  • player1, player2引数 データに対する各プレイヤーを示した因子、またはプレイヤーを示す因子を含んだデータフレームを入れます。データフレームの場合、id引数に渡した名前を因子は含まなければなりません。
  • data引数 モデルの構築に必要なデータを指定します。
  • id引数 player引数に渡した引数がデータフレームである場合に指定するidの名前です。

また、BTabilities関数はモデルを受け取って強さを出力する関数です。

この出力結果です。

Bradley Terry model fit by glm.fit 

Call:  BTm(outcome = cbind(home.wins, away.wins), player1 = home.team, 
    player2 = away.team, id = "team", data = baseball)

Coefficients:
   teamBoston  teamCleveland    teamDetroit  teamMilwaukee   teamNew York    teamToronto  
       1.1077         0.6839         1.4364         1.5814         1.2476         1.2945  

Degrees of Freedom: 42 Total (i.e. Null);  36 Residual
Null Deviance:      78.02 
Residual Deviance: 44.05    AIC: 140.5

出力結果のうちCoefficiants:の次にある二行はteamBaltimoreのλを1としたときの各チームの λ の値を示しています。

また、最後のAIC(赤池情報量基準)はモデルの予測の良さを表す数値で、この値が小さければ小さいほどいい予測の得られるモデルと言えます。(当てはまりが良いという意味ではないです。)

また、次のようにモデルを引数にとるBTabilities関数を用いて、各チームの λ 比のみを出力できます。

BTabilities(baseballModel)
            ability      s.e.
Baltimore 0.0000000 0.0000000
Boston    1.1076977 0.3338779
Cleveland 0.6838528 0.3318764
Detroit   1.4364084 0.3395682
Milwaukee 1.5813559 0.3432557
New York  1.2476178 0.3358606
Toronto   1.2944851 0.3366691

バイアス補正

プレイヤーの強さを表すモデルには、一種のバイアスがかかっていることがあります。

先ほどの野球チーム例ではホームグラウンドで行われたかどうかかどうかで勝敗の確率が変わるかもしれません。

先ほどのBradley-Terry modelの節で説明した式

btm-fig.7

について、あらたバイアス因子 δz (バイアスによって有利なら+1, 不利なら-1) を加え、

btm-fig.10

これを新たなモデルとして計算を行うことができます。

先ほどのbaseballのデータに新しくat.homeの因子を付け加えます。

baseball$home.team <- data.frame(team = baseball$home.team, at.home = 1)
baseball$away.team <- data.frame(team = baseball$away.team, at.home = 0)

ホームグラウンドの方がより強さが大きくなるという効果を出すために新たに at.home という因子を加えています。

先ほどと同様に強さを算出してみましょう。

baseballModel2 <- BTm(cbind(home.wins, away.wins), home.team, away.team, data = baseball, id = "team", formula = ~ team + at.home) 
baseballModel2

ここで新しくBTm関数にformula引数を指定していることに注目してください。

formula引数に渡すモデル式 ~ team + at.home はチームの説明変数の線形和に at.home 因子を足していることを示し、これは先ほど示した新しいモデル p = σ(λ_i - λ_j + δz) に対応しています。

出力結果です。

Bradley Terry model fit by glm.fit 

Call:  BTm(outcome = cbind(home.wins, away.wins), player1 = home.team, 
    player2 = away.team, formula = ~team + at.home, id = "team", 
    data = baseball)

Coefficients:
   teamBoston  teamCleveland    teamDetroit  teamMilwaukee   teamNew York    teamToronto        at.home  
       1.1438         0.7047         1.4754         1.6196         1.2813         1.3271         0.3023  

Degrees of Freedom: 42 Total (i.e. Null);  35 Residual
Null Deviance:      78.02 
Residual Deviance: 38.64    AIC: 137.1

先ほどと異なる点として Coefficients: の次の二行に at.home に関する係数が新たに追加されています。これはホームグラウンドであればチームの「強さ」に exp(0.3023) = 1.35 のバイアスがかかることを物語っています。(ここで示されているのは各チームのログ強さを示す λ_i = log(α_i))

また、AICが137.1と小さくなっており、こちらの方がより良い予測を行うモデルといえることが伺えます。

注意点

Bradley-Terryのモデルは各プレイヤーの強さが一次元的に表現できることを仮定しているため、プレイヤーの強さについての3すくみ、つまり三人のプレイヤーA,B,Cの強さ α_A, α_B, α_C について

btm-fig.11

が成り立つような関係に対しては仮定に含まれません。

参考