セイバーメトリクス

Rによるセイバーメトリクス入門 をじっくり学ぶ 得点期待値について②

さて、前回、得点期待値を求めるところまでできました。

得点期待値行列は、チームが残りの3アウトまでの攻撃で得点する平均点数を教えてくれます。

0アウト1アウト2アウト
ランナー無0.520.270.1
10.920.540.23
21.150.70.33
31.380.950.38
121.540.920.45
131.761.130.49
232.131.40.59
満塁2.461.690.83

得点価値について

それに伴い、打席の結果、ランナーとアウトカウントは変化します。つまり得点期待値は変化します。その変化は得点価値と呼ばれる打席の価値となります。

得点価値 = (打席による得点期待値) ー (打席前の得点期待値) + 得点

例えば、ある打者が、ワンアウトランナー1塁からヒットを放ち、ワンアウトランナー1塁2塁となると、得点期待値は0.54 から 0.92になります。つまり 0.92 - 0.54 で 0.38の得点価値があったこととなります。

一方、ワンアウトランナー1塁から三振し、ツーアウトランナー2塁となったら、得点期待値は0.54 から 0.23になります。つまり、0.23 - 0.53 で -0.30 となります。

打撃プレーの価値の把握

それでは、Rを使って得点価値を求めて行きましょう。 前回も使用したデータを使って行きます。

もとのデータフレームdata2021に、各打席時点の得点期待値を結合します。

data2021%>%
 left_join(select(RUNS,-Outs), by ="STATE")->data2021  

名前を変更

data2021%>%
 rename(Runs.State = Mean)->data2021

NEW.STATEを結合します。

data2021%>%
  left_join(select(RUNS,-Outs),
  by = c("NEW.STATE" = "STATE"))->data2021
data2021%>%
  replace_na(list(Runs.New.State =0))->data2021 

得点価値(Run Value)を算出します。

data2021%>%
 mutate(run_value = Runs.New.State - Runs.State + RUNS.SCORED)->data2021

アルトゥーベの打撃価値について

得点価値の理解のために、ここからは打者のデータを利用します。

Masterデータベースから、アルトゥーベのIDを抽出し利用します。

Master %>%      
 filter(nameFirst == "Jose", nameLast == "Altuve")%>%
         pull(retroID)->altuve.id 

data2021からバッターがアルトゥーベの打席を抽出し、altuveとします。

data2021%>%
  filter(BAT_ID == altuve.id,
        BAT_EVENT_FL == TRUE)->altuve 

そうするとアルトゥーベのすべての打席での得点価値が導き出せます。

そしてこの、得点価値の合計をRE24と呼びます。

altuve %>%
 summarize(RE24 = sum(RUNS))

結果、アルトゥーベのRE24は 22.41 であると導かれました。

全バッターの打撃会とパフォーマンス

結局、RE24が22.41であると、それが良いというのはわかりますが、どれほど良いのかはよくわかりません。

なので、全バッターのRE24を算出してみようと思います。

まず、打撃イベントで有効なものを抽出します。

data2021%>%filter(BAT_EVENT_FL == TRUE)->data2021b

ここで、RE24の比較について、打席に立ったときの得点期待値を元に見てみたいと思います。

チャンスで良く回ってくる選手にとっては、得点価値を上げるチャンスが多いです。(もちろんチャンスで凡退を多くしていては得点価値を上げることはできないですが。。。)

まず、バッターのIDでグループ化し、RE24を算出します(つまり、得点価値を合計します)

そして、打席数PAを算出します。これは打席数が少ない選手を除外するためです。

そして、打席に立った時点での得点期待値の合計も算出します。

data2021b%>%      
 group_by(BAT_ID)%>%
 summarize(RE24 = sum(run_value),
 PA = length(run_value),
 Runs.Start = sum(Runs.State))->runs 

打席数が400以上の選手を抽出します。

runs%>%
 filter(PA >=400)->runs400

このデータをグラフ化します。

y=0 は得点期待値と実際に生み出した価値が同じ

ggplot(runs400, aes(Runs.Start, RE24))+  
  geom_point()+       
  geom_smooth()+      
  geom_hline(yintercept = 0)->plot1 

最後に、RE24が40を超える選手は名前を表示させます。

runs400%>%
  inner_join(Master, by = c("BAT_ID" = "retroID"))->runs400
plot1+
      geom_text_repel(data = filter(runs400, RE24>=40),
                              aes(label = nameLast)) 

素晴らしいグラフができましたね!!!

このグラフからRE24において最高のバッターはソト、ゲレーロJr、大谷、ハーパーということがわかります。

-セイバーメトリクス