今回は、得点と勝利の関係について
ピタゴラス勝率について解析してみます。
参考は例によって偉大なる著書
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点
であったということがわかりました。
これより、勝利・敗戦のときの得点数に着目すると
ピタゴラス勝率の、微妙な違いのおもしろさに気づくことができますね。