1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Pythonを用いた日本プロ野球(NPB)データ解析:npb_scrapingの活用と実践

Posted at

目次

  1. はじめに
  2. インストール手順
  3. 基本的な使い方
  4. 出力データの形式
  5. データの保存・可視化
  6. 応用例
  7. まとめと今後の展望

1. はじめに

npb_scrapingは、日本プロ野球(NPB)の各年度における選手の成績データをスクレイピングによって取得し、Pandasのデータフレーム(DataFrame)として提供するPythonライブラリです (GitHub - kirikei4/npb_scraping: NPB data)。野手(打者)成績および投手成績のデータを取得でき、たとえばシーズンごとの打撃成績(安打数や本塁打数など)や投手成績(勝利数や防御率など)を含む統計データを入手できます。利用者は野手用ScrapingNPBBatterクラスと投手用ScrapingNPBPitcherクラスを使い、取得したいリーグ(セ・パ)、年度、チームを指定してデータを取得できます (GitHub - kirikei4/npb_scraping: NPB data)。データの出典はBaseball-Reference.com(米国の野球統計サイト)のNPBページであり (GitHub - kirikei4/npb_scraping: NPB data)、取得結果は分析しやすいようにPandasのDataFrame形式に整形されています。

2. インストール手順

npb_scrapingは執筆時点ではPyPIに公開されていないため(将来的にsetup.pyの整備が予定されています (GitHub - kirikei4/npb_scraping: NPB data))、Google Colabなどで利用する際はGitHubリポジトリから直接インストールする必要があります。Colab環境ではまず依存ライブラリをインストールし、その後npb_scraping本体をインストールします。依存関係としてPandas(データ解析用)、requestsまたはurllib(Web取得用)、BeautifulSoup4およびlxml(HTML解析用)などが必要です。Colabでは次のようなpipコマンドを使用します(!はColab上のセルで実行するコマンドを示します):

!pip install pandas requests beautifulsoup4 lxml
!pip install git+https://github.com/kirikei4/npb_scraping.git

上記ではまず必要ライブラリをインストールし、次にGitHub上のnpb_scrapingリポジトリから直接パッケージをインストールしています。インストール後、Pythonコード中で通常どおりimport文を使ってライブラリを読み込めます。例えば:

from npb_scraping import player  # モジュールをインポート

と記述すれば準備完了です。

3. 基本的な使い方

npb_scrapingを用いることで、特定の年度・チームに所属する選手の成績一覧を取得できます。野手の成績を取得する場合はScrapingNPBBatterクラスを、投手成績の場合はScrapingNPBPitcherクラスを使用します。それぞれに対し、取得年度(単年もしくは複数年のリスト)とチーム名(英語表記)を指定してスクレイピングオブジェクトを作成し、get_table()メソッドを呼ぶことで結果のDataFrameを得ます (GitHub - kirikei4/npb_scraping: NPB data) (GitHub - kirikei4/npb_scraping: NPB data)。以下に、例として2012年の横浜ベイスターズ(Yokohama Bay Stars)のデータを取得するコードを示します。なお、チーム名はBaseball-Referenceに登録されている英語名を指定します。

from npb_scraping import player

# 野手成績を取得する例(2012年 横浜ベイスターズ)
batter_scraper = player.ScrapingNPBBatter(year_list=[2012], team='Yokohama Bay Stars')
batter_df = batter_scraper.get_table()  # データを取得
print(batter_df.head())  # 取得したデータフレームの先頭部分を表示

# 投手成績を取得する例(2012年および2015年 横浜ベイスターズ)
pitcher_scraper = player.ScrapingNPBPitcher(year_list=[2012, 2015], team='Yokohama Bay Stars')
pitcher_df = pitcher_scraper.get_table()  # データを取得
print(pitcher_df.head())

上記のコードでは、まず2012年の横浜ベイスターズの打者成績を取得し、次に2012年と2015年の横浜ベイスターズの投手成績を取得しています (GitHub - kirikei4/npb_scraping: NPB data) (GitHub - kirikei4/npb_scraping: NPB data)。year_list引数には取得したい年をリストで指定し、複数年をまとめて取得することも可能です(この例では投手成績で2012年と2015年を同時に指定)。team引数にはチーム名を指定します。get_table()メソッドの戻り値はPandasのDataFrameであり、print()で表示すると選手ごとの成績が表形式で確認できます。

4. 出力データの形式

get_table()メソッドによって得られるDataFrameには、選手の年度別成績が行(レコード)として格納されています。データフレームはマルチインデックス(階層化インデックス)となっており、各行は「チーム名」「年」「選手名」で識別されます(例ではIndexとしてteamyearNameが設定されています)。列には選手の各種成績指標が含まれます (GitHub - kirikei4/npb_scraping: NPB data) (GitHub - kirikei4/npb_scraping: NPB data)。野手成績と投手成績で含まれる主なカラムは以下の通りです。

  • 野手データの主なカラム: 年齢(Age)、試合数(G)、打席数(PA)、打数(AB)、得点(R)、安打(H)、二塁打(2B)、三塁打(3B)、本塁打(HR)、打点(RBI)、盗塁(SB)、盗塁刺(CS)、四球(BB)、三振(SO)、打率(AVG)、出塁率(OBP)、長打率(SLG)、OPS(OPS)など。各選手のシーズン合計や率が含まれ、例えば安打数や本塁打数、打率といった基本的な打撃指標が網羅されています。

  • 投手データの主なカラム: 年齢(Age)、登板数(G)、先発数(GS)、勝利数(W)、敗戦数(L)、セーブ数(SV)、ホールド数(※データがある場合、HLD)、投球回(IP)、被安打(H)、失点(R)、自責点(ER)、奪三振(SO)、与四球(BB)、与死球(HBP)、防御率(ERA)など。投手についても勝敗やセーブ、防御率といった標準的な投手成績が含まれます(ホールド数など一部指標は年代によってはない場合があります)。

このように、npb_scrapingで取得できるデータにはシーズン単位の基本的な野球統計が一通り含まれており、データ解析や選手間の比較にすぐ利用できる形式となっています。各行は特定選手のある年の成績を表し、例えば野手データでは「2012年の筒香嘉智」のように個人シーズン成績を確認できます。

5. データの保存・可視化

取得した成績データは、Pandasの機能を使って自由に加工・保存できます。例えば、DataFrameをCSVファイルとして保存すれば、Excelなどで後から開いたり他のツールで利用したりできます。保存にはDataFrame.to_csv()メソッドを使用します。マルチインデックスを含むDataFrameをそのまま保存する場合、インデックス項目も出力される点に注意が必要です(インデックスを無視して保存したい場合は事前にreset_index()でインデックスを列に戻すこともできます)。以下は野手成績データをCSVに保存する例です。

# データフレームをCSVファイルとして保存(インデックスを含めない)
batter_df.reset_index().to_csv('baystars_2012_batter_stats.csv', index=False)

上記ではreset_index()によりチーム名・年・選手名のインデックスを通常の列に変換し、それも含めてCSVファイルに書き出しています。生成されたCSVファイルをダウンロードすれば、手元のPCで表計算ソフト等で閲覧・加工することも可能です。

また、取得したデータはPandasやMatplotlibを用いて可視化することも簡単に行えます。例えば、チーム内の本塁打数上位5選手を棒グラフで可視化するには次のようなコードになります。

import matplotlib.pyplot as plt

# 本塁打数上位5選手のデータ(2012年横浜ベイスターズ打者)
top5_hr = batter_df.reset_index().sort_values('HR', ascending=False).head(5)
top5_hr.plot(x='Name', y='HR', kind='bar')  # 選手名をX軸、本塁打数をY軸の棒グラフ
plt.xlabel('選手名')
plt.ylabel('本塁打数')
plt.title('2012年 横浜DeNAベイスターズ 本塁打数 上位5選手')
plt.show()

まずデータフレームから本塁打数(カラムHR)でソートし上位5人のレコードを抽出しています。DataFrame.plotメソッドを使って棒グラフ(bar chart)を作成し、Matplotlibで軸ラベルやタイトルを設定して表示しています。上記コードを実行すると、横浜ベイスターズの2012年シーズンにおける本塁打数トップ5選手の棒グラフが描画されます。これにより、チーム内で誰が最も本塁打を打ったかが一目で分かります。同様に、打率や防御率など他の指標についてもグラフ化することで、視覚的にデータを分析できます。

6. 応用例

npb_scrapingで取得したデータフレームを活用すれば、特定の条件でデータを絞り込んだり、複数年にわたる成績を比較分析したりすることも可能です。ここでは応用例として、(a) 特定の選手やチームの成績をフィルタリングする方法、(b) 選手の成績推移をグラフ化する方法を紹介します。

(a) データのフィルタリング: 例えば1シーズン分の全選手データ(リーグ全体)を取得し、その中から特定の選手やチームの成績だけを抜き出すことができます。npb_scrapingではteamを指定せずにleague引数でリーグを指定することで、そのリーグに所属する全チームの成績をまとめて取得できます(セ・リーグ= "Central League" 、パ・リーグ= "Pacific League" など)。以下は2020年セントラル・リーグ全体の打者成績を取得し、その中からヤクルトスワローズの山田哲人選手のデータ、および読売ジャイアンツのチームデータだけを抽出する例です。

# 2020年セ・リーグ全体の野手成績データを取得
all_cl2020 = player.ScrapingNPBBatter(year_list=[2020], league='Central League').get_table()
all_cl2020 = all_cl2020.reset_index()  # インデックスを列化

# 特定の選手の成績(例:山田哲人選手)
yamada = all_cl2020[all_cl2020['Name'] == 'Tetsuto Yamada']
print(yamada)

# 特定のチームの成績(例:読売ジャイアンツ)
giants_players = all_cl2020[all_cl2020['team'] == 'Yomiuri Giants']
print(giants_players.head())

上記のコードでは、league='Central League'とすることで2020年のセ・リーグ全6球団の打者成績を一度に取得しています。そのデータフレームから、まず選手名が「Tetsuto Yamada(山田哲人)」に一致する行を抽出することで、山田選手の2020年成績のみを取り出しています。次にチーム名が「Yomiuri Giants(読売ジャイアンツ)」に一致する行を抽出することで、巨人所属選手の2020年成績だけを一覧表示しています。このように、Pandasの条件指定(ブールインデックス)を用いることで関心のある選手やチームのデータに絞り込むことができます。

(b) 複数年の成績推移の分析: year_listに複数年を指定してデータを取得すれば、同一の選手について年度ごとの成績推移を分析することも可能です。例として、巨人の主力打者である坂本勇人選手の本塁打数が年々どのように変化しているかをグラフで見てみましょう。下記コードでは、2015年〜2020年の読売ジャイアンツの野手成績を取得し、その中から坂本選手の記録を抜き出して年度別の本塁打数を折れ線グラフでプロットしています。

# 2015〜2020年の巨人の野手成績を取得
giants_multi = player.ScrapingNPBBatter(year_list=list(range(2015, 2021)), team='Yomiuri Giants').get_table()
giants_multi = giants_multi.reset_index()

# 坂本勇人選手の年度別成績を抽出
sakamoto = giants_multi[giants_multi['Name'] == 'Hayato Sakamoto']

# 本塁打数の推移を折れ線グラフで可視化
plt.plot(sakamoto['year'], sakamoto['HR'], marker='o')
plt.xlabel('年度')
plt.ylabel('本塁打数')
plt.title('坂本勇人 (2015-2020) 本塁打数の推移')
plt.show()

まずyear_list=list(range(2015, 2021))とすることで2015年から2020年まで連続した6年分の巨人の打撃成績を取得しています。得られたデータフレームから坂本勇人(Hayato Sakamoto)選手の行のみを抽出すると、坂本選手の各年の成績(安打数や本塁打数など)が取り出せます。その中の本塁打数(HR列)を年度(year列)に対してプロットすることで、坂本選手の本塁打数が年度ごとにどう推移したかを示す折れ線グラフを描くことができます。プロットされたグラフから、坂本選手の本塁打数がある年に大きく伸びている、といった傾向を視覚的に読み取ることができます。このように、npb_scrapingで取得したデータを活用すれば、単年の成績比較だけでなく、複数年にまたがるトレンド分析や選手の成長・衰退の可視化など、より高度なデータ分析も行うことができます。

7. まとめと今後の展望

本稿では、npb_scrapingライブラリを用いてNPBの選手成績データを取得・活用する方法を紹介しました。npb_scrapingを使うことで、これまで入手が難しかった日本プロ野球の公式成績を自動的に収集し、自分好みの分析や可視化を行えるようになります。例えばチーム間で選手の成績を比較したり、長期にわたる記録の傾向を調べたりといったセイバーメトリクス的な分析にも手軽に取り組めるでしょう。特に、NPB公式サイトからは直接取得しづらい詳細な年度別成績を、一括でデータフレーム化して扱える点は大きな利点です。

一方で、Webスクレイピングに依存する以上、いくつかの課題も存在します。まず、データ取得元であるBaseball-Reference側のページレイアウト変更やURL変更が起きた場合、ライブラリが正常に動作しなくなる可能性があります。また取得できる統計項目はサイト上で公開されている範囲に限られるため、守備指標や高度な分析指標などが不足している点もあります(現状、守備に関するデータは未対応) (GitHub - kirikei4/npb_scraping: NPB data)。さらに現時点ではPyPIで配布されておらずインストールに一手間かかることも、小さな障壁と言えるでしょう。

こうした課題に対し、npb_scrapingの開発者は以下のような改良・拡張を今後の課題として挙げています (GitHub - kirikei4/npb_scraping: NPB data)。

  • パッケージ整備と依存関係の明示: requirements.txtsetup.pyを用意し、ライブラリのインストールをより簡単にする(PyPIへの公開も視野)。
  • 守備指標への対応: 失策数や守備率、UZRのような守備指標を取得対象に加える。
  • チーム成績の取得: 個人だけでなくチーム全体の成績(チーム打率やチーム防御率など)も取得できるようにする。
  • 球団名変更への対応: 球団合併や改名(例:大阪近鉄バファローズ→オリックス・バファローズなど)に伴う過去データの扱いを改善する。

これらが実現すれば、npb_scrapingの有用性はさらに高まるでしょう。類似の取り組みとしてメジャーリーグ向けにはpybaseballなどのオープンソースライブラリが存在しますが、NPB向けのツールは多くありません。npb_scrapingはそのギャップを埋める貴重な試みであり、今後の発展によっては日本のプロ野球データ分析コミュニティに大きく貢献できる可能性があります。今後は公式APIの公開やデータセット整備などが進むことも期待されますが、それまでは本ライブラリのようなスクレイピングツールが研究やファン分析を支える有力な手段となるでしょう。データ分析に興味のあるプロ野球ファンにとって、npb_scrapingは強力な武器となり得ます。本レポートをきっかけに、ぜひ様々な視点でNPBデータの分析・可視化に挑戦してみてください。 (GitHub - kirikei4/npb_scraping: NPB data)

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?