見出し画像

Statcastデータでバッティングのシミュレーション

Statcastデータを用いて、MLBのバッティングパフォーマンスをシミュレーションしました。Pythonでスクリプトを書いて、このあたりのコンテンツは全てQiitaに書きました。実装はQiitaを参照して下さい。

StatcastについてはWikipediaのリンクを貼っておきます。

モチベーション

まず、私はStatcastリリース後、つまりトラッキングデータがパブリックになってからの野球分析は本当につまらないコンテンツが増えた、と思っているタイプの人間です。野球と言うスポーツを捉える上で、トラッキングデータがあまりにも雄弁なコンテンツであったがために、トラッキングデータのプロットだけで半ば真実が見えてしまう、そんなスタンスの分析がマジョリティになっていることが、実につまらなかったのです。

私は07年に、父の書斎からかっぱらってきた「マネーボール」に大きな影響を受ける形で、セイバーメトリクスにも興味を覚えました。大人になってふりかえると、「マネーボール」無いしセイバーメトリクスにワクワクが止まらなかったのは、ビリー・ビーンやポール・デポデスタが、見えるはずの無いプレーヤーの未来を、ボックススコアから得られる情報の欠片をかき集めて見ようとする、無謀ながらもロマン溢れるアプローチに全力で取り組んでいたからです。

見えそうで見えない

と言う一文ほど、男をかきたてるパワーワードを私は知りません。

しかし、トラッキングデータは違います。ある瞬間のプレーの事実をデータとして正しく切り出した実像であり、ハッキリ言って丸見え。丸見えよりは、着衣の方がこうf(ry

とにかく、私は実データの可視化だけで半ば完結してしまう、そんな分析の山々に飽きており、どちらかと言えばオールドスクールな思考実験やシミュレーション、野球と言うスポーツのモデリングに、現代に生きるからこそ使うことが許されるトラッキングデータを組み込んでプライベートの分析に興じたいなー、と思っていました。

バッティングシミュレーションにした理由

バレルに代表される通り、トラッキングデータとパフォーマンスの紐付きがハッキリしている点で、分析対象としてイージーだなー、と思ったから。投手にとっての良いボールを定義するよりも、打者にとっての良い打球を定義する方がイージーなので、シミュレーションの道筋が立てやすく、入門としてバッティングのシミュレーションからスタートすることにしました。

もっと言うと、このシミュレーションをきっかけに、打者のフィジカル・スキル上の成長、無いし衰えに対しても言及が出来る材料を作りたかった、と言う点もモチベーションでした。打球の分布によって打者の実力を測れるだろう、とのアイデアは上述した「良い打球を定義しやすい」をベースに持ち上がっていたので、分布形の変化で実力の変化を測れれば、より未来の打者パフォーマンスも推定出来るかも、との期待もあって、テーマを決めました。

シミュレーション方式

Qiitaに実装と共に書いたのですが、ザックリ

・トラッキングデータのクリーニング
・打球速度と角度から打球種別を推定するSVMのモデルを作る
・打球種別からイベント(単打とか、ツーベースとか、、)を出す期待値表を作る
・トラッキングデータから打球速度・角度の分布を取得して、シミュレーションする
・シミュレーション結果からSVM、期待値表を駆使して、実パフォーマンスへシミュレーション結果を変換

2回のコンバージョンを挟んで実パフォーマンスへ落としている感じです。

シミュレーション結果

SVMと期待値表は2017〜2020年のデータで作成して、2018年シーズンのリーグ全体のトラッキングデータから分布を取得、ここからシミュレーションを回して2019年のリーグ平均のパフォーマンスを推定しました。

画像1

100回シミュレーション、BB%・K%はどのシミュレーションでも一定(それぞれ8%・18%)として推定。

2019年のリーグ平均OPSが.758で、OPSの平均(mean)や50%地点を見ると、大体.724〜.725なのでニアミスの範囲。割と良い具合なシミュレーションになりました!

めでたし!🎉

振り返り・今後のプラン

・推定精度はとりあえず満足、選手個人の分析に落とした場合も、このアプローチ自体は割とちゃんと機能してくれそう
・打球性質だけでシミュレーションしているので、リードオフマンタイプのパフォーマンスが過小評価されがちな点は注意(上記のOPSの下振れもそれが要因かも、とのイメージ)
・シーズン単位でのアップダウンも100回シミュレーションで再現出来たので、BABIPを超えた何かを作れると良いなー
・成長・衰えのシミュレーションも入っていきたい。分布の歪度・尖度、代表値あたりのdiffでそれを語れないかな、と思っています

この記事が気に入ったらサポートをしてみませんか?