2017年9月30日土曜日

MLBにおける各イニングごとの得点とかの話1

先週書いた失策の得点価値がどうのという記事で、得点価値の計算でnoncomplete half-inningを除いたのどうのということを書きました (注1)。基本的には、これはアウトカウントが少ない特殊なイニングであるためにそうするのだと思われますが、The Bookでは、さらに、9回以後のホーム側の攻撃では3アウトに達したイニングも、得点が入っていないというバイアスが発生しているために除いた、と説明されています。Marchi and Albertでも、noncomplete half-inningを除くことによって、得点が入ることにより完了しなかったイニングが除いたために、小さいバイアスを導入している、と説明されています。実際のところ、3アウトに達した9回の得点と、それを含めることによるバイアスの大きさはどれくらいでしょうか?

RetrosheetからMLB 00-16の9回表裏の各半イニングの得点とFIPの平均を、記録されたアウトカウントごとに集計しました。
図1. MLB 00-16の9回表裏の各半イニングの得点とFIPの平均
INN_CT: イニング
BAT_HOME_ID: 0 = "表", 1 = "裏"
Outs_CT: 記録されたアウト数
N: 総イニング数
Scores: 平均得点
FIP: FIPの平均 (注2; 注3)

9回裏 (BAT_HOME_ID = 1)では、アウトが3つでない場合、平均得点が1.5点以上となっています。一方、アウトが3つの場合、9回の表に比べてかなり低い得点になっています。FIPは9回表に比べて0.235しか低下しておらず、その影響 (0.235 / 9) は軽微です。これらの結果は、The BookやMarchi and Albertの説明通り、アウトが3つの時には得点が下がるバイアスが起こっている可能性を支持しています。

9回3アウトに達したイニングを得点価値計算に含めることの影響の大きさを調べるため、RetrosheetからMLB 00-16における、1回表から10回裏までの各半イニングのイニング数、得点、FIPを集計しました。

図2. MLB 00-16における各半イニングのイニング数、得点、FIP。
INN_CT: イニング
BAT_HOME_ID: 0 = "表", 1 = "裏"
Inning_CT: 総イニング数
Scores: 平均得点
FIP: FIPの平均

3アウトに達する9回裏自体が1表, 1裏...9回表の総イニング数の1/35程度しかない上に、得点の減少の程度も1/3程度 (図1, 9回表と裏の3アウトに達した場合での比較) のようなので、3点に達した9回裏を残した場合でもそれほど大きくは影響しないようです。個人的な好みとしては、得点価値を計算する場合はThe Bookの方法に従った方が良さそうな気がしますが、影響の大きさの観点では、あくまで好みのレベルの問題、という感じです (注4)。

ついでに、図2で得点の傾向について一部確認してみます。まず、1~8回までは裏の攻撃のほうが点が入りやすいことが確認できます。投手のFIP自体は表と裏であまり差は見られず、この得点の入りやすさの違いは投手のレベルの問題ではなく、いわゆるホームアドバンテージを見ていると考えられます。

ここで9回以後に注目すると、ホーム側の得点がビジター側よりも低い逆転現象が観察できます。8回裏→9回裏では、得点が大きく (0.094) 低下しています。この時、対戦投手のFIPは0.342しか低下しておらず、FIPによって説明される得点の減少は約0.038 (0.342 / 9) で、全体の低下のうち、約0.056が説明できていません。表の攻撃でも8→9回で得点が0.018低下していますが、こちらではFIPの変化を考慮に入れると (0.108 / 9) 、説明できない部分は0.006となります (注5)。表に比べて裏であまり説明できないという部分に関しては、要因の一つとして9回以後の裏の攻撃ではイニングが途中で切られることによって得点が低下している可能性が考えられます (注6)。

他にも色々傾向が ありますが、それらについては来週か再来週書きます。たぶん。

<注>
注1:
実際には記事ではimcomplete...と書いたのだがMarchi and Albertを見直したらnoncomplete... と書いていた。ニュアンスは違いそうな気もするのでこっそり修正。

注2:
イニング内で平均を取る時、Retrosheetの該当イニングの全ての行で平均を取っているが、これはイベントごとであって、同じPAでも複数の行で数えられることがある (SB, CS, WP, Balkなど、多分。) ので、PA平均とは多少一致しないはず (簡単にするため得点の集計と平均FIPの計算を同時にやっているので)。

注3:
FIPの計算はFGの方法に合わせた。FIP定数はFGのGuts!ページ
http://www.fangraphs.com/guts.aspx?type=cn
のデータを利用し、各年度ごとに定数とretrosheetのevent typeから全投手のFIPを計算し、対応する年度のResponsible pitcherごとに割り当てた。

注4:
結局、どの方法が本人にしっくりきて、それを他人に説明できるなら特に問題は無いというところでしょう。そもそも、non-complete inningを除かなくても多分あんまり変わらないですし。

注5:
8回表→9回表で残っている小さい値はただの誤差 (方法の問題 or ノイズ)、あるいはストライクゾーンが広がったとかでしょうか? イニングごとのストライクゾーンサイズを適当にググってみたんですが当たらなかった (間違いなく既に報告されていると思うけど情弱なので見つけられなかったという意味) ので、2016 (4/1以後; カウント 0-0; Balls in dirt無視) のPITCHf/xデータでざっくり、8回の表と9回の表のcalled strike確率50%の等高線プロットを書いてみました (データの取得にはpitchRxパッケージを利用した)。球種はわけていません。左が左打者、右が右打者の結果です。

他の条件はちゃんと見ていませんが、右打者では微妙に広くなっているかもしれません。左では広がっていない感じなので、もっとサンプルを増やさないと、全体として広がっているかどうかもよくわからないようです (イニングごとにわけているので一年分でも左打者だと2000球程度)。仮に広がっているとした場合に得点が量的にどれぐらい影響があるかを調べようとすると、データが利用可能な08-16の8回で、RHBとLFBに関して、各球種、各カウントでBall/Strikeをpredictionするモデルを作り、それらで9回のhandedness + 球種 + カウント + コースからpredictionを計算し、実際との差を求めて、得点価値に変換すれば概ね良さそうです (珍しいカウント、球種ではサンプルが足りなそうな気もする)。明らかにかなり面倒です。

注6:
実際には、説明できない部分がどれほどnoncomplete half-inningと関連しているかという証拠はどこにもなく、もっと直接調べなければならない、というところなので、一応かなり弱めの表現に留めています。

<参考>
Tango, Lichtman, and Dolphin, The Book , 2007, Potomac Books.
Marchi and Albert, Analyzing Baseball Data with R, 2013, CRC press.
http://www.fangraphs.com
http://retrosheet.org
https://www.mlb.com
http://pitchrx.cpsievert.me

2017年9月23日土曜日

失策の得点価値まわりの話

前の投稿で書いたあたりのことを確認している時に、wOBA計算時の係数について、The Bookと1.02で、失策出塁と単打の相対的な関係が結構違うことに気づきました。

The Bookで示されている係数はwikipediaで確認できます。
https://en.wikipedia.org/wiki/WOBA
1.02のものは例えばこちらにあります。
http://1point02.jp/op/gnav/glossary/intro04.aspx
一部をまとめると下のようになります。
図1. The Bookと1.02で示されているwOBAの一部のイベントの係数 (背景の緑のバーは係数の大きさを反映している)。

1.02のNPB版wOBAは、単打 (Single) に比べたときの失策出塁 (RBOE) の価値を、The Bookのものに比べてかなり高く評価しているようです。

公表されている得点価値から係数を計算してみると以下のようになります。

[係数] = ( [イベント得点価値] - [アウト得点価値] ) * [スケール補正に使用した数値]
なので、それぞれThe Bookの値を参照すると:

Single: (0.475 - (- 0.299)) * 1.15 = 0.8901
RBOE (注1): (0.508 - (- 0.299)) * 1.15 = 0.92805

出版に伴っていろいろ数値が丸められているせいか、少し元の数値と違いますが、概ね一致しています。

1.02もここにイベントごとの得点価値や出塁率へのスケール補正に使用した数値を示してくれています。
http://1point02.jp/op/gnav/column/bs/column.aspx?cid=53003
http://1point02.jp/op/gnav/glossary/intro04.aspx

1.02の単打: (0.437 - (- 0.257)) * 1.24 = 0.86056
1.02の失策出塁: (0.460 - (- 0.257)) * 1.24 = 0.88908

あれ....?


式はあってると思うんですけどね🤔

...まあ、エラーなんてそんなに頻度が高くないので全体では大した違いにはならないはずです。


<オマケ>

図2. MLB 00-16の安打と失策出塁 (打者がどの塁まで達したか別) のイベント発生回数 (N; 背景のピンクのバーはNのサイズを反映) とその得点価値。
RBOE0: 失策が記録されたが打者がアウトになったケース,
RBOE1: 打者の失策での 1塁への出塁 ...
RBOE5: 打者の失策での本塁への出塁 (注2).
(得点価値の計算はMarchi and Albertに従った (注3)。データはRetrosheetから。)

失策は安打に比べて十分に少なく、特に、打者が3塁より先に進むケースは極めてまれであることがわかります (図2のN)。3塁より先は17年分でもサンプルが少なすぎるため、得点価値の平均値は推定値としては信用できなさそうです。また、少なくともこの期間内においては、一塁への失策出塁と二塁への失策出塁は、それぞれ単打と二塁打とほぼ同等の得点価値があるようです (図2のRun_value; 注4)。

<注>
注1.
The Bookで各イベントの得点価値を示しているtable 7ではErrorと示されているがおそらくこれをRBOEとして使っていると考えて、その値を入れています。 RetrosheetのEvent type 18が"error"
http://www.retrosheet.org/datause.txt
なので、そのままの名前にしているためかと思ったんですが ... (注3) の後半に続く。
[ところでEvent type 18はごくごく稀にバッターが1塁でアウトになったケース (RBOEじゃないと思われる) も含むようですが (00-16年で n = 9)、ほとんど影響はないので気にしなくていいでしょう。]

注2.
RBOE4じゃなくて5にしたのは、Event type =  18 (error) の時のBatter destinationが 0, 1, 2, 3, 5だったため、なんとなくそれに合わせています。自責点かどうかなどで数値を変えているようです。
http://www.retrosheet.org/datause.txt

注3.
この方法ではimcomplete half-inning (要するにアウトが3つ記録されていない半イニング [= 表 or 裏]) 全てを切り捨てています。ちなみにThe Bookの方法では、imcomplete half-inningに加えて、9回裏以後のホーム側の攻撃をバッサリ切っている (実際のところ、結果的にはほとんど変わらないっぽいですが) 。

Marchi and Albertの方法でThe Bookが対象にしている年度 (99-02) での得点価値を求めると、Singleが0.472、Error (Event type 18; Bat event flagは全てTRUE)  が0.515になりました。単打はほぼThe Bookの結果と一致しましたが、Errorは結構差があります。原因はよくわかりません。

とりあえず安直にThe Bookと同様に9回裏以後のホーム側の攻撃を無視するように改変しても0.518なので、RBOEの定義が違うのかもしれません。 Event type 18には1つのプレーで複数のエラーを含んでいるものもあるので、イベント数ではなく、失策の総数を分母に使ってみた場合でも0.512🤔

注4.
Singleなどの安打系イベントには、打者走者が、エラーなどで先の塁に進んだケースも、アウトになったケースも含まれる。

<参考>
Tango, Lichtman, and Dolphin, The Book , 2007, Potomac Books.
Marchi and Albert, Analyzing Baseball Data with R, 2013, CRC press.
http://www.retrosheet.org

アプリの成績計算の補足

公開するより先に書いとけよ、という案件ですが (いくつかミスに気づけたはず)。

先週公開したshinyアプリにおける成績計算の補足です。

プロ野球個人成績 1, 2軍比較 with Shiny
https://snin-17.shinyapps.io/farm_stats_app/

ツイッターにも書きましたが、年度間の重み付け平均を取る時にwOBAとBABIP/DERの重み付けをミスっていたのを修正しました。結果的にはほとんど変わってないはずですが、反省します。

DERについて。
失策が考慮に入っていないのはデフォルトのページに書きましたが、記述が足りないようでした。データ取得 ~ 指標計算用のコードは結構昔に書いたものを流用していて、失策が入ってないのは覚えてたんですが、見直すと他にも書いといた方が良さそうなものがありました。
NPB公式の投手成績にはあまり細かい成績はありません。
http://npb.jp/bis/2017/stats/idp1_c.html
計算としては分母は対戦打者数から引けるだけ引いて、
  (H - HR) / (TBF - BB - IBB - HBP - K - HR)
見ての通り、失策だけでなく犠打などが考慮に入っていません。おそらく、このデータセットの中で選手間の相対的な比較をする分にははそれほど問題ないはずですが、少し投手タイプごとのバイアスも発生しているはずです。具体的には、GB率 (失策の発生しやすさと少し関連するはず) や、その投手がランナーを貯めやすいかどうか、あたりが原因になりうると思います。

wOBAについて。
投手成績と同じく、NPB公式には打撃成績
http://npb.jp/bis/2017/stats/idb1_c.html
にも失策出塁がありません。
wOBAの計算に関して、Refタブで引用していた1.02 http://1point02.jp/op/gnav/glossary/discription/dis_bs_woba.html
では失策出塁への係数も書かれていますが、当然それはこのアプリの計算では考慮していません。
FGの計算式
http://www.fangraphs.com/library/offense/woba/
では失策出塁は無視しても良さそうだったので (注1)、書かなくてもいいかと思ってたんですが、wOBAを導入したThe Book (pp. 30) を見直してみたら失策出塁も入っていました。確かに計算できるなら考慮した方が自然な気がします。

というわけで、DERは選手間で比較する分にはたぶんそんなに問題ない、wOBAは概ね整合しているぐらいの感じだと思います。個人の趣味でやっている事ということで、大目に見てやってください。

<注>
注1. ちゃんと考えると、この場合FGは失策を無視した後にスケールを合わせているので、失策を考慮してスケールを合わせている1.02から失策を除くのは全く違うことですが。

<参考>
Tango, Lichtman, and Dolphin, The Book , 2007, Potomac Books.

2017年9月16日土曜日

プロ野球個人成績 1, 2軍比較 with Shiny

NPB2012年以後の選手のいくつかの種類の通算個人成績を、1軍成績と2軍成績に関してプロットするShinyアプリを公開してみました。
https://snin-17.shinyapps.io/farm_stats_app/
プロットする対象の選手を決めるPA/TBFの閾値を変化させて、プロットがどう変わるかを見ることができます。ソースがNPB公式なので、わりと単純なstatsだけです。

Shinyの練習でつくったみたんですが、ウェブブラウザ上でRの関数の作図が動くのは結構おもしろい。

公開も非常に簡単だけど、無料だと月に25時間しか動かせない (default設定だと誰かがアクセスするとrunning状態になって、アクセスが切れると15分後にsleeping状態に移行)らしいので、ある程度ちゃんとやるなら金を払うか、自分でサーバ設定するとかしないと駄目のようです。

<参考>
https://www.shinyapps.io
http://d.hatena.ne.jp/hoxo_m/20151222/p1