目次
はじめに
こんにちは、こんばんは。
皆さん野球見てますか?日本プロ野球は大詰めを迎えています。贔屓チームの順位が決まっているチームもあれば、まだまだ優勝争いやCS争いをしているチームもあるでしょう。
本題です。最近野球見ていたり、SNSを見ているとよく思うことがあります。ボール飛ばない気がするです。なのでpythonを使って調べてみました。
調査の設計
まず、「飛ばなくなっている」をどう定義するかを決めます。
候補は以下の通りです。
候補 | 要素 | データ収取のしやすさ | 詳細 |
---|---|---|---|
No1 | 本塁打数(1試合平均のHR数の推移) | ◎ | NPB公式サイトの「年度別成績」やWikipediaの「年度別本塁打数一覧」から入手可能 |
No2 | OPSや長打率の推移 | 〇 | チーム・個人年度別成績はNPB公式や各種野球データサイトにある。OPSは「出塁率+長打率」なので自分で計算することも可能。 |
No3 | 打球速度・飛距離データ | △ | NPBでは公式に公開されていない。パ・リーグTVや一部の解析記事に断片的に出る程度。 |
No4 | フライボール割合、HR/FB比率 | × | NPB公式は打球結果の詳細(ゴロ/フライ/ライナー)を公開していない。 |
「年度ごとの1試合平均HR数」と「OPS/SLG推移」を軸にすれば、Pythonで分析しやすく、信頼できるデータを集めやすいと考えました。
用語解説
OPSとは出塁率と長打率を足し合わせた打撃指標です。
SLGとは長打率の略称で打者で1打数あたりに獲得する平均塁打数を表す指標です。
データ収集
次にデータ収集を行う。以下の項目データ収集を行った。
項目 | 詳細 |
---|---|
球団 | NPB球団12球団を対象(Giants,Tigers,BayStars,Carp,Swallows,Dragons,Hawks,Fighters,Marines,Buffaloes,Eagles,Lions) |
年度 | 2024年度~2020年度 |
本塁打数 | 各12球団の年間シーズン打撃成績を参考に |
試合数 | 2024~2021年度は143試合、2020年度は新型コロナウィルスの影響で短縮シーズン(120試合) |
長打率 | 野球で打者の「1打数あたりの平均塁打数」を示す指標 |
出塁率 | 打者が打数、四球、死球、犠飛の合計数に対し、安打、四球、死球で出塁する割合を示す野球の指標 |
セントラル・リーグ(6球団)
パシフィック・リーグ(6球団)
収集したデータ
収集したデータは以下の画像の通りです。
データ整形
以下のようにデータ整形を行います。
年度ごとのチーム成績を結合し、リーグ全体の平均を算出
コード
import pandas as pd
# データ読み込み
df = pd.read_csv("/content/drive/MyDrive/Colab Notebooks/studying_for_research/baseball/npb_2020_2024_hr.csv")
# OPSを追加
df["OPS"] = df["出塁率"] + df["長打率"]
# 年度ごとに集計
yearly = df.groupby("年度").agg({
"本塁打数": "sum",
"試合数": "sum",
"長打率": "mean",
"出塁率": "mean",
"OPS": "mean"
}).reset_index()
# 1試合平均HR数を計算
yearly["HR_per_game"] = yearly["本塁打数"] / yearly["試合数"]
# 結果を確認
display(yearly)
# CSVに保存
yearly.to_csv("npb_2020_2024_summary.csv", index=False)
出力結果
年度 本塁打数 試合数 長打率 出塁率 OPS HR_per_game
0 2020 1288 1440 0.383750 0.324500 0.708250 0.894444
1 2021 1449 1716 0.375083 0.315000 0.690083 0.844406
2 2022 1304 1716 0.364417 0.308417 0.672833 0.759907
3 2023 1250 1716 0.358167 0.307417 0.665583 0.728438
4 2024 975 1716 0.343583 0.303333 0.646917 0.568182
出力結果からわかること
このデータからは、2020年から2024年にかけてNPBの打撃成績が継続的に低下していることが分かります。特に2024年は、ホームラン数、長打率、出塁率、OPSが過去5年間で最も低い水準に達しました。これは、単にホームランが減っているだけでなく、リーグ全体として「投高打低」の傾向が強まっていることを示しています。急激な変化は、ボールの反発係数など、何らかの外部要因が影響している可能性が高いと推測されます。
可視化
次にデータの可視化を行います。
- 年度ごとの 1試合平均HR数 の推移グラフを作成
- 年度ごとの SLG推移グラフ を作成
- 3年移動平均を加え、トレンドを平滑化
年度ごとの 1試合平均HR数 の推移グラフを作成
コード
import matplotlib.pyplot as plt
import pandas as pd
# 整形済みデータを読み込み
yearly = pd.read_csv("npb_2020_2024_summary.csv")
# HR_per_game の推移
plt.plot(yearly["年度"], yearly["HR_per_game"], marker="o", color="red", label="HR per game")
plt.title("NPB Annual Average Home Runs Per Game")
plt.xlabel("fiscal year")
plt.ylabel("HR per game")
plt.legend()
plt.grid(True)
plt.show()
出力結果
縦軸はHR_per_game(1試合あたりHR数)を示す。横軸ではfiscal year(年度)を示す。
出力結果からわかること
このグラフは、2020年から2024年のNPBにおける1試合あたりのホームラン数が、継続的に減少していることを示しています。特に2024年は急激な落ち込みを見せ、過去5年間で最も少ない水準となりました。この急激な減少は、単なる選手個々の傾向ではなく、ボールの反発係数など、何らかの外部要因が影響している可能性が高いと考えられます。このことから、NPBではパワーヒッターよりも、確実なミートや走塁技術が重要視される「投高打低」の傾向が強まっていると分析できます。
年度ごとのSLG推移グラフを作成
コード
import matplotlib.pyplot as plt
import pandas as pd
import matplotlib as mpl
mpl.rcParams['font.family'] = 'DejaVu Sans'
# 整形済みデータを読み込み
yearly = pd.read_csv("npb_2020_2024_summary.csv")
# 長打率 (SLG) の推移
plt.plot(yearly["年度"], yearly["長打率"], marker="o", color="green", label="SLG")
plt.title("NPB Slugging Percentage (SLG) by Year")
plt.xlabel("fiscal year")
plt.ylabel("SLG")
plt.legend()
plt.grid(True)
plt.show()
出力結果
縦軸はSLG(長打率)を示す。横軸ではfiscal year(年度)を示す。
出力結果からわかること
日本のプロ野球におけるSLGは2020年から2024年にかけて一貫して下降傾向にあることがわかります。最も高かった2020年の値(0.385)から、2024年には最も低い値(0.344)まで、毎年着実に低下しており、この期間において打者の長打力が全体的に減少していることを示唆しています。
3年移動平均を加え、トレンドを平滑化
コード
import matplotlib.pyplot as plt
# 年度ごとに平均SLGを計算
slg_trend = df.groupby("年度")["長打率"].mean()
# 移動平均(3年)
slg_trend_ma = slg_trend.rolling(window=3, center=True).mean()
# グラフ描画
plt.figure(figsize=(8,5))
plt.plot(slg_trend.index, slg_trend.values, marker="o", label="平均SLG")
plt.plot(slg_trend_ma.index, slg_trend_ma.values, color="red", linewidth=2, label="移動平均(3年)")
plt.title("Annual Average SLG Trend (with Moving Average)")
plt.xlabel("Year")
plt.ylabel("Average SLG")
plt.legend()
plt.grid(True)
plt.show()
出力結果
縦軸はAverage SLG(平均長打率)を示す。横軸ではyear(年度)を示す。
出力結果からわかること
日本のプロ野球におけるSLGの年間平均値と、それを平滑化した3年移動平均の推移を示しています。元のSLG値は2020年から2024年にかけて継続して下降しているのに対し、3年移動平均線も同様に下降傾向を示しており、SLGの低下が短期的な変動ではなく、より長期的なトレンドであることを裏付けています。特に、3年移動平均線は、元のデータに見られる年ごとのわずかな変動を吸収し、全体として安定したSLGの減少トレンドを明確に示しています。
統計的分析
次に統計的分析を行います。
ANOVA(分散分析)
コード
import pandas as pd
from scipy import stats
# Load the yearly summarized data which contains the 'HR_per_game' column
yearly = pd.read_csv("npb_2020_2024_summary.csv")
# Group by year
groups = [yearly[yearly["年度"] == year]["HR_per_game"] for year in sorted(yearly["年度"].unique())]
# Perform one-way ANOVA
f_stat, p_val = stats.f_oneway(*groups)
print("ANOVA結果")
print("F値:", f_stat)
print("p値:", p_val)
出力結果
ANOVA結果
F値: 5.936972139783051
p値: 0.00048035907501589093
出力結果からわかること
ANOVA(分散分析)を実施した結果、F値は 5.94、p値は 0.00048 となりました。一般的に、p値が 0.05 未満であれば、帰無仮説(この場合は「年度間に差がない」)が棄却され、統計的に有意な差があると判断されます。今回の分析では、p値が 0.00048 と非常に小さいため、この基準を満たしています。この結果は、NPBの1試合平均本塁打数が、年度によって偶然ではない明らかな変動があったことを意味します。これは、SLG(長打率)の低下トレンドと同様に、「飛ばないボール」疑惑を裏付ける根拠の一つとなり得ます。
Tukey検定
コード
import pandas as pd
import statsmodels.api as sm
from statsmodels.stats.multicomp import pairwise_tukeyhsd
# Tukey HSD 検定
tukey = pairwise_tukeyhsd(endog=df["HR_per_game"], groups=df["年度"], alpha=0.05)
print(tukey)
# 結果を表形式で表示
tukey_result = pd.DataFrame(data=tukey.summary().data[1:], columns=tukey.summary().data[0])
print(tukey_result)
出力結果
Multiple Comparison of Means - Tukey HSD, FWER=0.05
====================================================
group1 group2 meandiff p-adj lower upper reject
----------------------------------------------------
2020 2021 -0.05 0.9585 -0.2554 0.1554 False
2020 2022 -0.1345 0.3578 -0.3399 0.0709 False
2020 2023 -0.166 0.1672 -0.3714 0.0394 False
2020 2024 -0.3263 0.0004 -0.5317 -0.1209 True
2021 2022 -0.0845 0.7736 -0.2899 0.1209 False
2021 2023 -0.116 0.5086 -0.3214 0.0894 False
2021 2024 -0.2762 0.0033 -0.4816 -0.0708 True
2022 2023 -0.0315 0.9925 -0.2369 0.1739 False
2022 2024 -0.1917 0.0783 -0.3971 0.0137 False
2023 2024 -0.1603 0.1949 -0.3657 0.0452 False
----------------------------------------------------
group1 group2 meandiff p-adj lower upper reject
0 2020 2021 -0.0500 0.9585 -0.2554 0.1554 False
1 2020 2022 -0.1345 0.3578 -0.3399 0.0709 False
2 2020 2023 -0.1660 0.1672 -0.3714 0.0394 False
3 2020 2024 -0.3263 0.0004 -0.5317 -0.1209 True
4 2021 2022 -0.0845 0.7736 -0.2899 0.1209 False
5 2021 2023 -0.1160 0.5086 -0.3214 0.0894 False
6 2021 2024 -0.2762 0.0033 -0.4816 -0.0708 True
7 2022 2023 -0.0315 0.9925 -0.2369 0.1739 False
8 2022 2024 -0.1917 0.0783 -0.3971 0.0137 False
9 2023 2024 -0.1603 0.1949 -0.3657 0.0452 False
出力結果からわかること
この検定結果によると、2020年対2024年および2021年対2024年の比較において、統計的に有意な差が確認されました。具体的には、2020年と2024年の比較ではp値が0.0004、2021年と2024年の比較ではp値が0.0033となり、いずれも有意水準0.05を下回っています。これは、2024年の1試合あたりの平均本塁打数が、2020年と2021年と比較して統計的に有意に減少していることを意味します。
一方で、2020年から2023年までの期間においては、どの年のペアを比較しても有意な差は見られませんでした。また、2022年と2024年、2023年と2024年の比較では、わずかにp値が0.05を超えているため、厳密な有意差は認められませんでした。
回帰分析
コード
import statsmodels.api as sm
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import matplotlib as mpl
try:
mpl.rcParams['font.family'] = 'IPAexGothic'
except:
print("IPAexGothic font not found. Using default font.")
mpl.rcParams['font.family'] = 'DejaVu Sans'
# 年度を数値に変換(カテゴリではなく数値でトレンドを見る)
df['year_num'] = df['年度'] - df['年度'].min()
# 回帰モデル作成
X = sm.add_constant(df['year_num']) # 切片を追加
y = df['HR_per_game']
model = sm.OLS(y, X).fit()
# 回帰結果の概要
print(model.summary())
# 可視化
plt.figure(figsize=(8,5))
sns.scatterplot(x='year_num', y='HR_per_game', data=df, s=80)
sns.regplot(x='year_num', y='HR_per_game', data=df, scatter=False, ci=None, color='red')
plt.xlabel("年度")
plt.ylabel("HR per Game")
plt.title("Trend of HR per Game (2020-2024)")
plt.show()
出力結果
OLS Regression Results
==============================================================================
Dep. Variable: HR_per_game R-squared: 0.283
Model: OLS Adj. R-squared: 0.270
Method: Least Squares F-statistic: 22.87
Date: Sat, 20 Sep 2025 Prob (F-statistic): 1.23e-05
Time: 11:59:45 Log-Likelihood: 20.100
No. Observations: 60 AIC: -36.20
Df Residuals: 58 BIC: -32.01
Df Model: 1
Covariance Type: nonrobust
==============================================================================
coef std err t P>|t| [0.025 0.975]
------------------------------------------------------------------------------
const 0.9128 0.039 23.187 0.000 0.834 0.992
year_num -0.0768 0.016 -4.782 0.000 -0.109 -0.045
==============================================================================
Omnibus: 3.859 Durbin-Watson: 2.704
Prob(Omnibus): 0.145 Jarque-Bera (JB): 2.891
Skew: 0.463 Prob(JB): 0.236
Kurtosis: 3.548 Cond. No. 4.74
==============================================================================
出力結果からわかること
この回帰分析は、2020年から2024年にかけてNPBの平均本塁打数が一貫して減少していることを統計的に裏付けるものです。これは、以前から議論されている「飛ばないボール疑惑」を支持する有力な材料の一つとなり得ます。ただし、モデルの説明力が約28%であることから、本塁打数の減少は年度だけが原因ではなく、他の様々な要因が複合的に作用している可能性も示唆されます
縦軸はHR_per_game(1試合あたりHR数)を示す。横軸ではfiscal year(年度)を示す。
OPS/SLGとHR_per_gameの相関
コード
import pandas as pd
# OPSを計算(まだ列がない場合)
df["OPS"] = df["出塁率"] + df["長打率"]
# 相関係数の確認
corr = df[["HR_per_game", "OPS", "長打率", "出塁率"]].corr()
print(corr)
出力結果
HR_per_game OPS 長打率 出塁率
HR_per_game 1.000000 0.854791 0.920500 0.550620
OPS 0.854791 1.000000 0.966285 0.861930
長打率 0.920500 0.966285 1.000000 0.702323
出塁率 0.550620 0.861930 0.702323 1.000000
出力結果からわかること
この相関行列を見ると、1試合あたりの本塁打数(HR_per_game)は、長打率(SLG)と0.92という非常に強い正の相関を示しています。これは、長打率が高くなると本塁打数も増加する傾向が非常に強いことを意味します。次に、OPSとは0.85の強い正の相関があり、OPSが上昇すれば本塁打数も増えることがわかります。一方、出塁率(OBP)との相関は0.55と中程度にとどまっています。
考察
今回の分析から、2020年から2024年にかけてNPBの打撃成績は明確に下降傾向を示していることが分かりました。特に2024年は本塁打数、長打率、OPSいずれの指標も過去5年間で最低水準となり、リーグ全体として「投高打低」の傾向が強まっています。
統計的検定の結果からも、2024年の本塁打数は2020年および2021年と比べて有意に低いことが確認されました。これは単なる偶然ではなく、リーグ全体に共通する外部要因が作用している可能性を示唆しています。
背景要因としては、以下の可能性が考えられます。
背景原因 | 詳細 |
---|---|
ボールの反発係数の変化 | 過去に統一球や加藤球など「飛ぶボール」「飛ばないボール」の議論があり、今回の急激な指標低下も同様のケースである可能性がある |
投手レベルの向上 | 投手の平均球速上昇、分業化(中継ぎ・抑えの強化)などにより、打者が長打を放ちにくくなっている可能性がある |
戦略面の変化 | セイバーメトリクス普及により、打撃戦よりも投手戦を前提としたチーム編成・戦略が浸透している可能性がある |
ただし、本分析は年度ごとの「打撃成績平均値」に基づいており、個人の打球速度や飛距離データ、球場ごとの環境要因(球場サイズ、風、ドーム・屋外差など)までは考慮できていません。より詳細に検証するためには、Statcastのような打球データや球場別成績の活用が必要です。
結論
2024年シーズンに見られる「打撃成績の急激な低下」は統計的にも裏付けられ、ボールや環境要因の変化が疑われる現象だと考えられます。今後も継続的にデータを収集し、2025年以降のトレンドが反発するのか、あるいは「飛ばない時代」が定着するのかを検証していきたいと思います。
まとめ
今回はpythonを用いて、日本プロ野球のボールが飛ばなくなっているのかpythonで分析してみました。2025シーズンのプロ野球成績がでたらまた分析していきたいと思います。ちなみに体感ですが、球宴以降ボールが飛んでいるような気がします。機能性かもしれませんが....
githubのリポジトリです。参考にしてください。