Lean Baseball

No Engineering, No Baseball.

野球好きとデータ好きのためのStatcastデータ入門 - スポーツデータ解析の第一歩

【2022/8/13更新】打球位置のプロット例を追加しました(解説ブログのリンクを含む)

プライベートの時間はウイニングポスト9*1で自家生産の馬を育てるか, 野球データと戦っている人です.

野球のデータは見れば見るほど面白いです, どれぐらい面白いかと言うと「10年見ても飽きない*2」それぐらい面白いです(個人の感想です).

それはさておき, 私はメジャーリーグのデータを使って調べ物をしたりなにかのテーマに取り組む時, 以下のデータセットを用いています.*3

  1. Lahman’s Baseball Database. 年度別のチーム・選手成績など, ある程度まとまった単位のデータ. GitHubから取得可能(https://github.com/chadwickbureau/baseballdatabank).
  2. Retrosheet. 試合・打席ごとの成績データ. GitHubから取得可能(https://github.com/chadwickbureau/retrosheet).
  3. Statcast Search. Baseball Savant内にある, Statcast(計測機器)による投球・打球のトラッキングデータ.

上記データの内, Lahman’s Baseball DatabaseRetrosheetについては「Rによるセイバーメトリクス入門」という名著で利用例を含めて紹介がされているのでそちらに解説を譲るとして.

今の野球データサイエンスのトレンドとなっている「打球速度」「ボール変化量」といった, 「投げたボールや打球の質を解析する」テーマにおいて, Statcast Searchのデータが必要(厳密に言うと, 私達ファンが唯一触れるデータでもある)なのと, そのデータ解説が思ったより無い*4ので, 日本語版という形で解説するのがこのエントリーの主旨となります.

TL;DR

  • 野球のプレーの一挙手一投足がわかっちゃうデータです
  • 座標系はXYZの三次元座標(X: 横幅, Y: 奥行き, Z: 高さ). YとZが微妙に混乱するので注意(後述).
  • 項目がめちゃくちゃ沢山あるので取捨選択した上で使いましょう.

目次

Statcastとは?

ものすごく雑かつシンプルに言うと,

野球選手の「投球」「打撃」「守備」の「一挙手一投足」を事細かに記録したデータをいい感じに可視化したりデータとしてダウンロードできる仕組み

です.

baseballsavant.mlb.com

上記のBaseball Savantというサイト(ちなみにMLB公式なのでガチの本物です)でデータをチェックしたり, グラフや動画で確認したり, そしてデータとしてダウンロードすることができます.

例えば, Statcast Searchで「大谷翔平(Ohtani, Shohei)はどこによく打球を飛ばしているのか?」と調べるとこういうグラフがすぐに出てきます(打者・オオタニサンで検索).

Statcastで検索したオオタニサンの打球傾向

(メジャーリーグのサイトなので)全編英語ですが, 気になる選手やデータがある方は探してみると楽しいと思います, 好きな人はこのサイトで一日時間を溶かせるのではと笑.

データの読み方のポイント

サイト上で検索してグラフを眺めたりダウンロードしたりして楽しむのも良いですが, Statcast SearchからCSVデータをダウンロードして, 手元で色々分析・解析するのがこのサイトの醍醐味だと確信しています.

baseballsavant.mlb.com

こちらの検索結果はCSVとしてダウンロードできるので, 手元でいろんな事ができます, かつこのページに仕様があります.

ただ, 初見だとこのデータの解釈は厳しいし使いにくい事この上ないので読み方・使い方を解説します(≒ここがこのエントリーの本題です).

なお, このデータは91個のカラムが存在します(が, 非推奨・非更新のカラムが7個あるので実質相手するのは84個です).

単位は原則feetとmile

アメリカ発祥のデータなので, 単位は原則feetとmileです!

距離・長さはfeet, 速度はmile表記となります.

  • ストライクゾーンなどの表示をcm表記にするときは30.48を掛ける, 打球距離などm表記の時は0.3048
  • 速度はmile/h表記なので, km/h表記にしたい場合は1.6を掛ける

といった単位の変換が必須となります.

なお, Baseball Savantのサイトそのものには変換する機能が無いため脳内で読み替える必要があります.

XYZ座標の読み方

データの中には座標を示すカラムがいくつか存在します.

ざっくり解説すると以下の表の通りとなります.

座標 意味
X 横幅を表す. 捕手(もしくは審判)から見た視点での座標系で, 0が真ん中, マイナスが右打者方向, プラスが左打者方向. ストライクゾーンのインコース・アウトコースを判断するにはX軸を使う.
Y 奥行きを表す. マウンドからホームベースの距離, ホームベースの入り口と出口, みたいな距離はY軸を使う.
Z 高さを表す. 高めのボール・低めのボールみたいな判断はZ軸.

よく見慣れたストラックアウト的な表現にするとこんな感じです.

Statcastデータの座標系イメージ

ストライクゾーンを横幅×高さで表現する時はそれぞれX座標とZ座標を使います(Y座標は登場しません*5).

また, 横座標は「捕手・審判から見た座標系」であることに注意が必要です, 真ん中がゼロ, 右打者方向ががマイナス, 左打者方向がプラスとなります*6.

ストライクゾーンの区画仕様

ストラックアウト同様, ゾーンごとに数字が振られています.

このゾーンの仕様は以下の通りです(こちらの絵を引用).

Zone仕様

ソートする際に使う項目

試合ごとのデータとして, 見やすい順番にソートしたい場合は以下のカラムでソートすると良いです.

カラム 昇順/降順 意味・補足
game_date 昇順 試合した日
game_pk 昇順 試合ごとにUnique ID
inning 昇順 イニング数
inning_topbot 降順 イニングの表裏. Top/Bot表記なので, 降順で並べないと上手く並ばない.
at_bat_number 昇順 打順の通し番号
pitch_number 昇順 投球の通し番号

CSVにせよ, データベースに入れてSQLで並べるにせよ, この順でソートするのがオススメです.

ちょっとした利用例 - オオタニサンの場合

データの解説ばかりだと眠いと思うので,

  • オオタニサンが10勝目を決めた現地時間2022/8/9の先発試合の投球データ
  • オオタニサンがどんな打球を放っているか?2022/8/9までの打球データ

これらをStatcastのデータを源泉に, PythonのPlotlyというライブラリで可視化した結果をお見せします.

10勝目を決めた日の投球

10勝目を決めた2022/8/9(日本時間2022/8/10)の全投球をプロットした結果がこちらとなります.

なお, 見やすいように, feetからcmに表記は訂正しています.

10勝目を決めた日の投球のプロット

球種(pitch_name)ごとにストライクゾーンに入ったかどうか, を表しています.

もちろん, 他の属性で見ることも可能です.

投球の結果で色付け・アイコン変更したもの

この日は三振が少なかったので, 意外と空振り(swinging_strike)少ないとかわかりますよね.

なお, ちょっと変わった視点だと, 「捕手から見たリリースポイント(ボールを離した手の位置)も可視化できます.

捕手・審判から見たオオタニサンのリリースポイント

球種毎にリリースポイント違うのねー, とか面白い発見もありますね.

これまでの打球の質と結果

オオタニサンを語る上で, 打者としてのパフォーマンスも無視できません.

  • 縦軸: 打球角度
  • 横軸: 打球速度

とした場合の打球の結果を可視化するとこんな感じになります.

打球の結果を元にした可視化

本塁打(home_run)を示す青い点がある一定の打球速度・打球角度から来てそう?というのが見えるかと思います.

これは「早い打球速度・程よい打球角度で飛んだ打球はホームランになりやすい」という「バレル・ゾーン」理論にある程度基づいていて,

打球種別毎にプロットし直した図

本塁打の打球の殆どが「Barrel」に該当しているので, 理論にしっかり基づいてるなとわかったりします.

...といった感じでStatcastのデータは使えます.

打球の到達位置

球場のどこにオオタニサンの打球が飛んだか?という可視化もこのデータで可能です.

オオタニサンの打球到達位置

こちらは座標の使い方・処理に癖があるので気になる方は別記事の解説を読んでいただけたらと思います.

shinyorke.hatenablog.com

結び

「野球好きとデータ好きのためのStatcastデータ入門」というテーマで改めて「 Statcast Search](https://baseballsavant.mlb.com/statcast_search)のデータをダウンロードして遊ぼう」というエントリーを書いてみました.

実はこのエントリー, 本年のPyCon JP 2022のこの発表

pretalx.com

この発表における解説の一部であると同時に, 自分が野球データのリハビリをするためにまとめたものになっています*7.

2年近く触ってないデータだったので仕様をほとんど忘れていたのと, これを機会に仕様を整理しようというモチベーションで書きました.

10月のPyCon JP 2022で面白い話ができるように, そして何より野球データの解釈・データ分析が進む事でもっと面白いことができるよう引き続き頑張っていきたいと思います.

そして, このニッチな仕様・解説が後に続くスポーツデータ分析・解析をされる方のお役に立てると何よりも嬉しいです.

最後までお読みいただきありがとうございました&Appendixとしてデータ仕様の完全版がこの後にあるので興味ある方は合わせてお読みいただけると幸いです.

Appendix - 各カラムの仕様

独自に編集している日本語版は以下のSpreadsheetで随時更新しています.

docs.google.com

2022/8/12時点の仕様はこちらです.

項目 解説 状況 投球の記録 打球の記録 備考
pitch_type Statcast が定義する投球タイプ。 Y
game_date 試合日
release_speed 投手のリリーススピードのことで所謂「球速」のこと。2016 年までは Pitch f/x、2017 年以降は Statcast で測定。 Y Pitch f/x と Statcast で測定基準が微妙に異なる。Pitch f/x は手が離れた(リリースした)リリースポイントが始点になるが、Statcast は手が離れたイベントそのものが始点となる。
release_pos_x 捕手始点から見たボールリリース時の水平座標、単位は feet Y いわゆるリリースポイント(の水平座標)
release_pos_z 捕手始点から見たボールリリース時の垂直座標、単位は feet Y いわゆるリリースポイント(の水平座標)
player_name イベントに関連する選手名 Y 例えば Statcast で打者基準の検索をした場合、player_name には batter ID に基づく選手の名前が入る。他のポジションも同じ。
batter 打者の MLB Player ID Y
pitcher 投手の MLB Player ID Y
events 投球イベントの結果 Y
description 投球イベントの結果説明 Y
spin_dir 非推奨データ、昔の計測システムの名残で残っているデータ おそらく Pitch f/x のこと
spin_rate_deprecated 非推奨データ、昔の計測システムの名残で残っているデータ おそらく Pitch f/x のこと、release_spin カラムを使うこと
break_angle_deprecated 非推奨データ、昔の計測システムの名残で残っているデータ おそらく Pitch f/x のこと
break_length_deprecated 非推奨データ、昔の計測システムの名残で残っているデータ おそらく Pitch f/x のこと
zone 捕手視点でのゾーン位置 Y 1-14 の数値(10 は欠番)で 1-9 がストライクゾーン、11-14 がゾーン外。参考: https://www.researchgate.net/figure/Game-Day-Zones-as-defined-by-Statcast-and-Baseball-Savant-The-strike-zone-is-presented_fig1_358572353
des プレーの詳細 Y テキスト実況と捉えて OK
game_type 試合タイプ E = エキシビション, S = 春季キャンプ, R = レギュラーシーズン, F = ワイルドカード, D = 地区シリーズ, L = リーグチャンピオンシリーズ, W = ワールドシリーズ Y
stand 打席の左右 Y R もしくは L、ちなみにスイッチは存在しない(打席に限った立ち位置なので)。
p_throws 投球の左右 Y R もしくは L
home_team ホームチーム略称 Y
away_team アウェイチーム略称 Y
type 投球結果, B = Ball, S = Strike, X = In Play Y X の In Play は「グラウンドに何かしらの打球が飛んだ」の意味でほぼ Batted Ball と捉えて OK。ヒット、ホームラン、エラー、ファールすべて X となる。
hit_location ボールに触った野手の位置 Y
bb_type 打球(Batted Ball)の種別 ground_ball = ゴロ, line_drive = ラインドライブ, fly_ball = フライボール, popup = ポップフライ Y スコアブックの結果と異なるので注意。例えば「鋭い当りのライトライナー」はスコアブックの結果は「ライトフライ」だが、bb_type の結果では「line_drive」になる。
balls 投球前のボールカウント Y
strikes 投球前のストライクカウント Y
game_year 試合年
pfx_x 捕手視点のボールの水平移動 Y 移動そのものを表す指標。座標じゃないので注意。
pfx_z 捕手視点のボールの垂直移動 Y 移動そのものを表す指標。座標じゃないので注意。
plate_x 捕手視点から見たホームベース到達時の水平座標 Y ホームベース上の到達地点として使う。捕手視点で真ん中が 0 で右打者側がマイナス、左打者側がプラス。
plate_z 捕手視点から見たホームベース到達時の垂直座標 Y ホームベース上の到達地点として使う。ゼロはほぼ地面、マイナスはワンバウンドと捉えて OK。
on_3b 三塁ランナーの MLB Player ID Y 投げる前の状態、ランナー無しの場合は空文字
on_2b 二塁ランナーの MLB Player ID Y 投げる前の状態、ランナー無しの場合は空文字
on_1b 一塁ランナーの MLB Player ID Y 投げる前の状態、ランナー無しの場合は空文字
outs_when_up 投球前のアウトカウント Y
inning 投球回 Y
inning_topbot 投球回の表と裏 Top = 表, Bot = 裏 Y
hc_x 打球到達位置の X 座標(横) Y
hc_y 打球到達位置の Y 座標(縦) Y
tfs_deprecated 非推奨データ、昔の計測システムの名残で残っているデータ おそらく Pitch f/x のこと
tfs_zulu_deprecated 非推奨データ、昔の計測システムの名残で残っているデータ おそらく Pitch f/x のこと
fielder_2 捕手の MLB Player ID Y
umpire 非推奨データ、昔の計測システムの名残で残っているデータ おそらく Pitch f/x のこと
sv_id 試合イベントの非 Unique ID Unique Key にはならないので注意。現実的には使わない(使えない)カラムかも。
vx0 y=50feet で決定される x 次元での投球速度(feet / sec)。 Y 投球の速度変化を見る時に使う
vy0 y=50feet で決定される y 次元での投球速度(feet / sec)。 Y 投球の速度変化を見る時に使う
vz0 y=50feet で決定される z 次元での投球速度(feet / sec)。 Y 投球の速度変化を見る時に使う
ax y=50feet で求めた投球の加速度(x 次元)を feet/sec で表したもの。 Y 投球の速度変化を見る時に使う
ay y=50feet で求めた投球の加速度(y 次元)を feet/sec で表したもの。 Y 投球の速度変化を見る時に使う
az y=50feet で求めた投球の加速度(z 次元)を feet/sec で表したもの。 Y 投球の速度変化を見る時に使う
sz_top ボールがプレートの半分まで来た時にオペレーターが設定した打者のストライクゾーンの上部。 Y ストライクゾーンの高め上限に使える。
sz_bot ボールがプレートの半分まで来た時にオペレーターが設定した打者のストライクゾーンの下部。 Y ストライクゾーンの低め下限に使える。
hit_distance 打球の飛距離(推定値、feet) Y あくまで推定値、実測値では無いことに注意(そもそも実測はできない)。
launch_speed 打球速度(mile / h) Y 実測値もあれば、推定値もある。
launch_angle 打球角度 Y 実測値もあれば、推定値もある。
effective_speed 投手のリリース位置を加味した上での球速(mile / h) Y これが事実上正確な球速として使える。
release_spin Statcast が計測したボール回転数 Y いわゆる「回転数」のこと。
release_extension Statcast が計測したボールのリリース位置(Extension) Y ピッチャープレートからボールをリリースした位置のこと。これが長いと「より打者の近くでボールを放っている」状態となる。
game_pk 試合ごとの Unique ID 試合ごとに Unique にまとめたいときはこのカラムを使う。
pitcher 投手の MLB Player ID Y
fielder_2 捕手の MLB Player ID Y
fielder_3 一塁手の MLB Player ID Y
fielder_4 二塁手の MLB Player ID Y
fielder_5 三塁手の MLB Player ID Y
fielder_6 遊撃手の MLB Player ID Y
fielder_7 左翼手の MLB Player ID Y
fielder_8 中堅手の MLB Player ID Y
fielder_9 右翼手の MLB Player ID Y
release_pos_y 捕手視点から見た投球のリリース位置 Y Extension とあわせ技で使う。release_pos_x と release_pos_z との組み合わせで「リリースした位置」の三次元座標を表現できる。
estimated_ba_using_speedangle 打球速度と打球角度に基づいた推定打率
estimated_woba_using_speedangle 打球速度と打球角度に基づいた推定 wOBA wOBA はこちらを参照 https://ja.wikipedia.org/wiki/WOBA
woba_value プレー結果に対する wOBA 値 Y
woba_denom プレー結果に対する wOBA の分母 Y
babip_value プレー結果に対する BABIP 値 Y BABIP はこちらを参照 https://ja.wikipedia.org/wiki/BABIP
iso_value プレー結果に対する ISO 値 Y ISO はこちらを参照 https://ja.wikipedia.org/wiki/IsoP
launch_speed_angle 打球角度と速度に基づいた打球種別ゾーン 1: 弱い, 2: トップ, 3: アンダー, 4: フレア/バーナー, 5: ソリッドコンタクト, 6: バレル Y バレルゾーンか否かを判定するためのフラグ
at_bat_number 試合内の通し打順 試合内で Unique に採番される、チームごとに採番ではないので注意。
pitch_number 打席内の投球数
pitch_name Statcast が判定した球種 Y
home_score 投球前のホームチームの得点 Y
away_score 投球前のアウェイチームの得点 Y
bat_score 攻撃側の得点 Y
fld_score 守備側の得点 Y
post_home_score 投球後のホームチームの得点 Y
post_away_score 投球後のアウェイチームの得点 Y
post_bat_score 投球後の攻撃側の得点 Y
if_fielding_alignment 投球時点での内野手位置 Y 内野の守備シフトの有無はここでわかる
of_fielding_alignment 投球時点での外野手位置 Y 外野の守備シフトの有無はここでわかる
spin_axis 2 次元 X-Z 平面上のスピン軸を 0 ~ 360 度で表したもの。180 度は純粋なバックスピンの速球、0 度は純粋なトップスピン(12-6)のカーブを表す。 Y 回転軸のこと
delta_home_win_exp 打席完了前と打席完了後の勝利期待値変化
delta_run_exp 投球の前と投球の後での得点期待値変化

*1:実は結構競馬好きなので...史実馬を自家生産馬でねじ伏せたりするのが楽しいです笑.

*2:メジャーリーグのソーシャルゲームの分析をし始めたのが10年前で, それからずっと眺めているので間違いないです.

*3:これらのデータはこのブログおよびPyCon JPの発表で何かしら使っているので私自身および私の発表をよく見てる方は記憶にあるかもしれません, ちなみに初心者向けで一番使いやすいのはLahman's Baseball Databaseです.

*4:Rによるセイバーメトリクス入門にも, 付録的な立ち位置で載ってはいるものの, 詳細な解説ではなく, 「ある程度野球と野球のデータを知っている人なら読める」レベルの情報量なのでこのブログで改めて書くことにしました.

*5:Y座標の使い所はボールの軌道など, 三次元で表現するときに登場します.

*6:TV中継みたいに投手視点での表現をやりたい場合はマイナスを掛ける(プラスマイナスを逆転させる)事で実現可能です.

*7:ちょっと細かい話をすると, 普通のセイバーメトリクスで使うデータならちょっと読めばわかるのですがStatcastのようなセンシングデータはちゃんと仕様とか意味がわからないと読めないのと, 何よりもStatcastのデータをずっと見てなかったのでそこで時間がかかりました...