セイバーメトリクス

Rによるセイバーメトリクス をじっくり学ぶ 得点と勝利の関係について②

今回は、得点と勝利の関係について 

ピタゴラス勝率について解析してみます。

 

参考は例によって偉大なる著書

Rによるセイバーメトリクス入門です。

 

得点と勝利の関係について

すべてのスポーツの目標は、試合に勝つことです。

 

野球において勝利とは、相手より多くの点を取ることに尽きます。

 

その中で、自チームが取った得点 と 自チームが取られた得点

は大きく勝敗に影響を与えると言われています。

 

そのあたりの解析を前回を行いました。

 

ピタゴラス勝率

セイバーメトリクスの父と呼ばれる

Bill Jamesはピタゴラス勝率を導出しました。

 

 勝率 = R^2 / R^2 + RA^2

この数式で勝率を予測することができます。

  

ちなみにBill Jamesの物語は

マネーボールという本に詳しく描かれていますので

ぜひ読んでみてください!

 

では、実際にピタゴラス勝率の数式を求めます。

my_teams <- my_teams%>%
 mutate(Wpct_pyt = R^2/(R^2 + RA^2))

実際の勝率 と

ピタゴラス勝率の差分を算出します。

my_teams<- my_teams%>%
 mutate(residuals_pyt = Wpct - Wpct_pyt)

差分の絶対値を求めます。

my_teams%>%
 summarize(rmsse = sqrt(mean(residuals_pyt^2)))

そうすると、、、

rmsse 0.02620188

 

ピタゴラス勝率が実際の勝率とほとんど一致することがわかりました!

 

ピタゴラスモデルの指数

Bill Jamesがピタゴラス勝率ということを考えましたが、

その後、さらに改良がなされました。

 

勝率 = R^k / R^k + RA^k

としてkを求めようと試みられました。

 

勝率 = 勝利 / 勝利+敗戦 = R^k / R^k + RA^k

ということから

 

式を変換すると、

勝利 / 敗戦 = R^k / RA^k

となります。

両辺を対数に取ると

log( 勝利 / 敗戦) = k × (R / RA)

となりました。

 

ここからRの出番です

my_teams<- my_teams%>%
 mutate(logWratio = log(W/L),
              logRratio = log(R/RA))

lm関数を使ってモデルを作成します。

pytFit <- lm(logWratio ~ 0+logRratio, data = my_teams)

> pytFit

Call:

lm(formula = logWratio ~ 0 + logRratio, data = my_teams)

Coefficients:

logRratio   1.842

 

結果としては

勝率 = R^1.842 / R^1.842 + RA^1.842

指数を 1.842とすると最も当てはまりが良くなります!

 

 

 

ピタゴラスモデルの良い予測と悪い予測

2011年シーズン ボストンレッドソックスは

875得点/737失点でした。

162試合 × 875^2/ (875^2 + 737^2)

95試合の勝利が予測されました。

 

しかし、実際には90勝にとどまり、

結果、ポストシーズンへの進出を逃しました

 

ということで、この原因について解析します。

2011年の全試合のデータについて読み込みます。

glheaders <- read_csv("data/game_log_header.csv")

gl2011<- read_csv("data/gl2011.txt",
  col_names= names(glheaders),
 
  na = character())

その中からレッドソックスの試合を抽出します。

 BOS2011 <- gl2011%>%
 filter(HomeTeam == "BOS"| VisitingTeam == "BOS")%>%
 select(VisitingTeam, HomeTeam,
 VisitorRunsScored, HomeRunsScore)

> head(BOS2011)

# A tibble: 6 × 4

VisitingTeam, HomeTeam, VisitorRunsScored, HomeRunsScore

1 BOS          TEX                      5             9

2 BOS          TEX                      5            12

3 BOS          TEX                      1             5

4 BOS          CLE                      1             3

5 BOS          CLE                      4             8

6 BOS          CLE                      0             1

 

このデータから、得失点差と勝敗を求めます。

 BOS2011 <- BOS2011%>%
 mutate(ScoreDiff = ifelse(HomeTeam == "BOS",
   HomeRunsScore - VisitorRunsScored,
   VisitorRunsScored- HomeRunsScore), 
   W = ScoreDiff>0)

head(BOS2011)

# A tibble: 6 × 6

VisitingTeam, HomeTeam, VisitorRunsScored, HomeRunsScore, ScoreDiff, W    

1 BOS          TEX                      5             9        -4 FALSE

2 BOS          TEX                      5            12        -7 FALSE

3 BOS          TEX                      1             5        -4 FALSE

4 BOS          CLE                      1             3        -2 FALSE

5 BOS          CLE                      4             8        -4 FALSE

6 BOS          CLE                      0             1        -1 FALSE

 

上から4点差負け、7点差負け・・・という感じです。

 

ここから要約統計量を算出します

library(skimr)

BOS2011%>%
 group_by(W)%>%
 skim(ScoreDiff)

── Data Summary ────────────────────────

                           Values    

Name                       Piped data

Number of rows             162       

Number of columns          6         

_______________________              

  skim_variable W     n_missing complete_rate  mean   sd  p0 p25 p50 p75 p100

1 ScoreDiff     FALSE         0             1 -3.46 2.56 -11  -4  -3  -1   -1

2 ScoreDiff     TRUE          0             1  4.3  3.28   1   2   4   6   14

 

ここから

勝利時には 平均4.30点

敗戦時には 平均-3.46点

であったということがわかりました。

 

これより、勝利・敗戦のときの得点数に着目すると

ピタゴラス勝率の、微妙な違いのおもしろさに気づくことができますね。

-セイバーメトリクス