Go to list of users who liked
はじめに
今回はメジャー挑戦1年目でワールドシリーズ優勝に貢献したドジャースの山本由伸投手の投球内容を分析します。シーズン中には怪我での離脱がありましたが、最終的にはレギュラーシーズン18試合、ポストシーズン4試合に先発してワールドシリーズ制覇に貢献したシーズンでした。今回はその22試合で投げた全1751球を対象として、全投球の傾向や怪我の前後での変化などを分析します。
投球データの分析
全投球データの取得と可視化
まずはpybaseballをインストールして、山本投手のレギュラーシーズンとポストシーズンの投球データを取得します。
# pybaseballのインストール!pipinstallpybaseballimportpybaseballaspb
# 山本投手のデータを取得yamamoto_data=pb.playerid_lookup('Yamamoto','Yoshinobu')# 投球のデータを取得player_id=yamamoto_data.iloc[0,2]# player_id = 808967start_date='2024-01-01'end_date='2024-12-31'yamamoto_pitch=pb.statcast_pitcher(start_date,end_date,player_id)# レギュラーシーズンとポストシーズンの投球データのみ抽出yamamoto_pitch=yamamoto_pitch.query("game_type !='S' and game_type !='E'").sort_values(by=['game_date','inning','outs_when_up'])yamamoto_pitch.head()
pitch_typegame_daterelease_speedrelease_pos_xrelease_pos_zplayer_namebatterpitchereventsdescription...n_thruorder_pitchern_priorpa_thisgame_player_at_batpitcher_days_since_prev_gamebatter_days_since_prev_gamepitcher_days_until_next_gamebatter_days_until_next_gameapi_break_z_with_gravityapi_break_x_armapi_break_x_batter_inarm_angle1731FF2024-03-2195.4-1.385.42Yamamoto, Yoshinobu673490808967sac_flyhit_into_play...10NaN1.09.07.01.110.740.74NaN1732FC2024-03-2189.6-1.255.46Yamamoto, Yoshinobu673490808967NaNball...10NaN1.09.07.02.08-0.40-0.40NaN1733FF2024-03-2194.7-1.245.60Yamamoto, Yoshinobu673490808967NaNball...10NaN1.09.07.01.261.321.32NaN1734FF2024-03-2196.1-1.275.40Yamamoto, Yoshinobu673490808967NaNcalled_strike...10NaN1.09.07.01.120.590.59NaN1735CU2024-03-2179.3-1.045.63Yamamoto, Yoshinobu673490808967NaNball...10NaN1.09.07.05.27-1.17-1.17NaN5 rows × 113 columns
表示されるデータ項目は以下の通りです。
今回の分析で扱う投球データは、以下のようにレギュラーシーズン(R)の1469球とポストシーズン(ディビジョンシリーズ(D)123球、リーグチャンピオンシップシリーズ(L)73球、ワールドシリーズ(W)86球)の282球の合計1751球となります。
yamamoto_pitch['game_type'].value_counts()
countgame_typeR1469D123W86L73dtype: int64
また、以下のように試合日でソートして、登板日と投球数を以下のようにまとめました。怪我で緊急降板となった試合の前の試合の106球が最大の球数で、怪我からの復帰後は最後の登板となったワールドシリーズでの86球が最大でした。
yamamoto_pitch['game_date'].value_counts().sort_index()
ここからは各投球データを可視化して、今季の全投球を分析します。まずは球種についてです。
importpandasaspdpd.crosstab(yamamoto_pitch['pitch_name'],yamamoto_pitch['type'],margins=True)
Bがボール、Sがストライク、Xがヒットやゴロなどを含めて打者がバットに当てたときを表しています。また、割合は以下のようになります。
importpandasaspdpd.crosstab(yamamoto_pitch['pitch_name'],yamamoto_pitch['type'],normalize='index')
フォーシームとカーブはストライク率が50%を超え、ボール率は共に30%程度となっています。スイーパーと判定されている1球を除けば、カーブはバットに当たっている割合が最も低く、ストライクを取るために特に安定して使うことができるボールであったと言えます。また、球種ごとの球速とコースを可視化すると以下のようになります。なお、コースは打者目線となっています。
importmatplotlib.pyplotaspltimportseabornassnsplt.figure(figsize=(8,4))sns.boxplot(x='pitch_name',y='release_speed',data=yamamoto_pitch)plt.show()
importmatplotlib.pyplotaspltimportseabornassnssns.scatterplot(x=yamamoto_pitch['plate_x'],y=yamamoto_pitch['plate_z'],hue=yamamoto_pitch['pitch_name'])plt.xlim(-3,6)plt.ylim(-2,6)# ストライクゾーンを描画x=[-0.83,0.83,0.83,-0.83]y=[1.5,1.5,3.5,3.5]plt.fill(x,y,color='k',alpha=0.3)plt.title('pitch course')plt.show()
各球種ごとの打席結果は以下のようになっています。
importpandasaspdpd.crosstab(yamamoto_pitch['pitch_name'],yamamoto_pitch['events'],margins=True)
eventsdoublefield_errorfield_outfielders_choiceforce_outgrounded_into_double_playhit_by_pitchhome_runsac_buntsac_flysinglestrikeouttripletruncated_pawalkAllpitch_name4-Seam Fastball8178012051225291118172Curveball6133121020092600384Cutter201602101015100029Sinker20600010002100012Slider117001000021500229Split-Finger403903112011248105117All23317918621014551202128443
この中で、ヒット(single, double, triple, home_run)となった結果を抽出して、コースを可視化してみます。
importpandasaspdhit=yamamoto_pitch.query('events=="single" or events=="double" or events=="triple" or events=="home_run"')pd.crosstab(hit['pitch_name'],hit['events'],margins=True)
以下のようにコースを可視化してみると、ほとんどがストライクゾーン内のボールであるため、どの球種でも甘いボールを逃してくれないという印象を受けます。
importmatplotlib.pyplotaspltimportseabornassnssns.scatterplot(x=hit['plate_x'],y=hit['plate_z'],hue=hit['pitch_name'])plt.xlim(-3,6)plt.ylim(-2,6)x=[-0.83,0.83,0.83,-0.83]y=[1.5,1.5,3.5,3.5]plt.fill(x,y,color='k',alpha=0.2)plt.title('opp hits')plt.show()
次に、三振を奪った球種についてです。
strikeout=yamamoto_pitch.query('events=="strikeout"')strikeout['pitch_name'].value_counts()
countpitch_nameSplit-Finger484-Seam Fastball29Curveball26Slider15Cutter1Sinker1
スプリットで多くの三振を奪っています。また、以下のように可視化してみると、ボール球となるスプリットを振らせて多くの三振を奪っていることがわかります。
importmatplotlib.pyplotaspltimportseabornassnssns.scatterplot(x=strikeout['plate_x'],y=strikeout['plate_z'],hue=strikeout['pitch_name'])plt.xlim(-3,6)plt.ylim(-2,6)x=[-0.83,0.83,0.83,-0.83]y=[1.5,1.5,3.5,3.5]plt.fill(x,y,color='k',alpha=0.2)plt.title('strikeout')plt.show()
最後にリリースポイントです。打者目線でどの位置で手からボールが離れたのか球種ごとに可視化します。
importmatplotlib.pyplotaspltimportseabornassnsplt.figure(figsize=(5,5))sns.scatterplot(x=yamamoto_pitch['release_pos_x'],y=yamamoto_pitch['release_pos_z'],hue=yamamoto_pitch['pitch_name'])plt.xlim(-4,0)plt.ylim(3,7)plt.title('Release point')plt.show()
参考までに、大谷翔平投手、ダルビッシュ有投手の2021年から3シーズン分のデータを以下に示します。グラフのスケールは同じなので、山本投手のリリースポイントが球種による差が少ないことがわかります。
怪我での離脱前後の比較
次に怪我での離脱前後で投球データがどのように変化していたのか分析をします。以下のように6月15日の試合で28球投げて降板した後、3ヶ月ほど怪我のために実戦から遠ざかっていました。
# 怪我の前後でデータを分割before=yamamoto_pitch.query('game_date <"2024-06-16"')after=yamamoto_pitch.query('game_date >"2024-06-16"')print(before['game_date'].value_counts().sort_index())print(after['game_date'].value_counts().sort_index())
game_date2024-03-21 432024-03-30 682024-04-06 802024-04-12 912024-04-19 992024-04-25 972024-05-01 942024-05-07 972024-05-13 842024-05-20 1002024-05-26 1002024-06-01 1012024-06-07 1062024-06-15 28Name: count, dtype: int64game_date2024-09-10 592024-09-16 722024-09-22 792024-09-28 712024-10-05 602024-10-11 632024-10-17 732024-10-26 86Name: count, dtype: int64
怪我の前後でヒット打たれた球種について比較します。
#怪我前のデータimportpandasaspdhit_before=before.query('events=="single" or events=="double" or events=="triple" or events=="home_run"')b1=before['pitch_name'].value_counts()b2=hit_before['pitch_name'].value_counts()opp_hit_before=pd.concat([b1,b2],axis=1)opp_hit_before.columns=['pitch_count','opp_hit']opp_hit_before['rate']=opp_hit_before['opp_hit']/opp_hit_before['pitch_count']opp_hit_before.sort_index()
# 怪我後のデータimportpandasaspdhit_after=after.query('events=="single" or events=="double" or events=="triple" or events=="home_run"')a1=after['pitch_name'].value_counts()a2=hit_after['pitch_name'].value_counts()opp_hit_after=pd.concat([a1,a2],axis=1)opp_hit_after.columns=['pitch_count','opp_hit']opp_hit_after['rate']=opp_hit_after['opp_hit']/opp_hit_after['pitch_count']opp_hit_after.sort_index()
中継の解説などで、怪我後はスライダーが良くなったというコメントを多数見かけましたが、実際には怪我の前後で投球数も打たれた数もほとんど差はありませんでした。また、各球種を比較すると、シンカーの数が極端に少なくなり、カットボールやスライダーの割合が高くなったことがわかりました。カットやスライダーといった斜めに曲がる球種を投げる割合が増加したものの、打たれた数に大きな差がなかったため、スライダーが良くなったというような印象を受けたのかもしれません。
最後にリリースポイントの変化を可視化してみます。
# 怪我の前後を示す'before_after'をデータ項目として追加before_after=yamamoto_pitch.copy()before_after['before_after']=before_after['game_date'].apply(lambdax:'before'ifx<'2024-06-16'else'after')
importmatplotlib.pyplotaspltimportseabornassnsplt.figure(figsize=(5,5))sns.scatterplot(x=before_after['release_pos_x'],y=before_after['release_pos_z'],hue=before_after['before_after'],alpha=0.07)plt.xlim(-4,0)plt.ylim(3,7)plt.title('Release point (before vs after injury)')plt.show()
怪我の後はボールを離す位置が斜め下方向に変わっていました。この傾向は以下のように各球種でも同様に確認できました。
importmatplotlib.pyplotaspltimportseabornassnsfour_seam=before_after.query('pitch_name=="4-Seam Fastball"')plt.figure(figsize=(5,5))sns.scatterplot(x=four_seam['release_pos_x'],y=four_seam['release_pos_z'],hue=four_seam['before_after'],alpha=0.15)plt.xlim(-4,0)plt.ylim(3,7)plt.title('Release point (4-seam, before vs after injury)')plt.show()
以下、コードは割愛しますが、他の球種についてもリリースポイントを可視化してみます。
各球種について、怪我の前後で同様の傾向が見られました。
分析結果の総括と所感
分析の結果、フォーシームやカーブで安定的にストライクが取れていたということや、ボール球のスプリットを振らせて多くの三振を奪っていたことがわかりました。また、怪我の前後でリリースポイントに変化が生じていることもわかりました。その変化を加味しても全体としてはリリースポイントが安定していて、打者目線では球種の判別がしにくいということになるため、山本投手の投球スタイルの1つの強みであると思います。
終わりに
今回は、昨シーズンの山本投手の投球データの分析を行いました。怪我の前後でリリースポイントに変化が生じており、これがいよいよ日本で開幕を迎える新シーズンでも継続していくのか、それとも怪我前の位置に戻っていくのか、シーズン終了後にまた比較分析を行いたいと思います。
Register as a new user and use Qiita more conveniently
- You get articles that match your needs
- You can efficiently read back useful information
- You can use dark theme