はじめに
2月になり、プロ野球のキャンプが始まりました。
昨シーズンの2024年シーズンのパ・リーグのデータを使用して主成分分析(PCA)によるチーム力の可視化と分析を行います。
特に、打撃、投手、守備の各側面からチームの特徴を多角的に検討し、データサイエンスの手法を用いて解析していきます。
👇2023年シーズンの分析記事はこちら
データ引用元
NPBの公式サイトからパリーグの以下のデータを使用します。
・チーム打撃成績
・チーム投手成績
・チーム守備成績
1. データの概要
1.1 使用データ
分析には2024年シーズンのパ・リーグ6チームの以下のデータを使用しました。
打撃成績
- 打率
- 長打率
- 出塁率
投手成績
- 防御率
守備成績
- 守備率
1.2 データの構造
データは以下の3つのCSVファイルに分割して保存しています:
analyze/
├── data/
│ ├── 2024_PacificLeague_batting_stats.csv
│ ├── 2024_PacificLeague_fielding_stats.csv
│ └── 2024_PacificLeague_pitching_stats.csv
└── sample.py
各ファイルの構造は以下の通りです:
# 打撃成績の例
batting_data = {
'チーム': ['ソフトバンク', 'ロッテ', '日本ハム', '楽天', 'オリックス', '西武'],
'打率': [0.259, 0.248, 0.245, 0.242, 0.238, 0.212],
'長打率': [0.394, 0.346, 0.367, 0.339, 0.331, 0.301],
'出塁率': [0.327, 0.312, 0.301, 0.303, 0.297, 0.274]
}
2. 分析手法
2.1 主成分分析(PCA)の適用
チームの総合力を評価するために、以下のステップで主成分分析を実施しました。
-
データの前処理
- 各指標の標準化
- 防御率は値が小さいほど良いため、-1を乗じて調整
- これにより、防御率が低い(良い)チームが高いスコアを得られるように変換
-
特徴量の選択
- 打撃指標:打率、長打率、出塁率
- 投手指標:防御率
- 守備指標:守備率
-
PCAの実行と解釈
- 5つの指標から主成分を抽出
- 各主成分の寄与率と特徴量の寄与度を分析
2.2 実装のポイント
def perform_pca_analysis():
# データの読み込み
batting_df, pitching_df, fielding_df = load_data()
# 分析用の特徴量を選択
features = ['打率', '長打率', '出塁率', '防御率', '守備率']
X = team_stats[features]
# 防御率の調整(-1を乗じる)
X['防御率'] = -X['防御率']
# データの標準化
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
# PCAの実行
pca = PCA()
pca_result = pca.fit_transform(X_scaled)
3. 分析結果
3.1 主成分の解釈
各主成分の特徴と意味を詳しく見ていきます。
第1主成分(PC1)- 攻撃力指標
- 寄与率:66.5%(チーム特性の2/3を説明)
- 第2主成分との累積寄与率:85.7%
- 2つの主成分でチーム特性の大部分を説明可能
- 主な寄与度:
- 打率: 0.52
- 出塁率: 0.53
- 長打率: 0.53
- 解釈:チームの攻撃力を総合的に表現する指標
第2主成分(PC2)- 投手力指標
- 主な寄与度:
- 防御率: -0.91
- 解釈:投手力の強さを表現する指標
- 防御率の影響が強く、防御率が低い(良い)チームほど高いスコアを示す
第3主成分(PC3)- 守備力指標
- 主な寄与度:
- 守備率: 0.84
- 解釈:守備力の高さを表現する指標
- 正の大きな値は、守備率が高いほどこの主成分の値が高くなることを示す
3.2 チーム特性の視覚化
チーム別の特徴を詳しく見ていきます。
ソフトバンク
- 第1主成分で最も高いスコア → 打撃力が突出
- 防御率2.53(リーグ1位)を反映し、第2主成分でも良好なスコア
- 総合的なチーム力の高さを示している
オリックス
- 第2主成分で最も高いスコア → 投手力の高さを示す
- 防御率2.82(リーグ2位)が反映
- 打撃面では改善の余地あり
日本ハム
- 第2主成分で高いスコア → 良好な投手力
- 防御率2.94(リーグ3位)を反映
- バランスの取れたチーム特性
西武
- 第1主成分が低い → 攻撃面での課題
- 防御率は中位(3.02)を反映し、第2主成分も中程度
ロッテ・楽天
- 第2主成分が低い → 投手力面での課題
- 特に楽天は防御率3.73(リーグ最下位)を反映し、最も低いスコア
4. 実装の詳細
4.1 環境設定
必要なライブラリのインストール:
pip install pandas numpy scikit-learn matplotlib seaborn japanize-matplotlib
4.2 データ処理とPCA実装
完全なコード実装は以下の通りです:
import pandas as pd
import numpy as np
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA
import matplotlib.pyplot as plt
import seaborn as sns
import japanize_matplotlib
def load_data():
"""CSVファイルからデータを読み込む"""
batting_df = pd.read_csv('data/2024_PacificLeague_batting_stats.csv')
pitching_df = pd.read_csv('data/2024_PacificLeague_pitching_stats.csv')
fielding_df = pd.read_csv('data/2024_PacificLeague_fielding_stats.csv')
return batting_df, pitching_df, fielding_df
def perform_pca_analysis():
"""主成分分析を実行する"""
batting_df, pitching_df, fielding_df = load_data()
# データの結合と特徴量選択
team_stats = pd.merge(
pd.merge(batting_df, pitching_df, on='チーム'),
fielding_df, on='チーム'
)
features = ['打率', '長打率', '出塁率', '防御率', '守備率']
X = team_stats[features]
X['防御率'] = -X['防御率']
# 標準化とPCA
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
pca = PCA()
pca_result = pca.fit_transform(X_scaled)
return team_stats, pca_result, pca.explained_variance_ratio_, pd.DataFrame(
pca.components_.T,
columns=[f'PC{i+1}' for i in range(len(features))],
index=features
)
4.3 可視化の実装
結果の可視化には以下のコードを使用しました:
def plot_results(team_stats, pca_result, explained_variance_ratio, loadings):
"""分析結果を可視化する"""
plt.style.use('seaborn')
# チームの主成分空間でのプロット
team_scores = pd.DataFrame(
pca_result[:, :2],
columns=['PC1', 'PC2'],
index=team_stats['チーム']
)
# 第2主成分の符号を反転(投手力の解釈を直感的に)
team_scores['PC2'] = -team_scores['PC2']
plt.figure(figsize=(12, 8))
plt.scatter(team_scores['PC1'], team_scores['PC2'], s=100)
for team in team_scores.index:
plt.annotate(
team,
(team_scores.loc[team, 'PC1'], team_scores.loc[team, 'PC2']),
xytext=(5, 5),
textcoords='offset points',
fontsize=12
)
plt.xlabel(f'第1主成分 (寄与率: {explained_variance_ratio[0]:.3f})')
plt.ylabel(f'第2主成分 (寄与率: {explained_variance_ratio[1]:.3f})')
plt.title('NPBパリーグ チーム総合力の主成分分析')
plt.grid(True)
plt.tight_layout()
5. 分析結果の詳細解釈
5.1 チーム別の特徴分析
各チームの特徴を主成分分析の結果から詳しく解釈します:
ソフトバンク
- 第1主成分が最も高い → 攻撃力が突出
- 実データでも打率(.259)、長打率(.394)、出塁率(.327)すべてでリーグトップ
- バランスの取れた強さを示す位置にプロット
楽天
- 第2主成分が最も低い → 投手力面での深刻な課題
- 防御率3.73(リーグ最下位)を反映
- 守備率(.988)は高水準を維持
ロッテ
- 第2主成分が低い方 → 投手力面での課題
- 防御率3.17(リーグ5位)を反映
- 守備率(.987)は高水準を維持
日本ハム
- 中間的な位置にプロット
- 長打率(.367)が比較的高い
- 総合的にバランスの取れたチーム特性
オリックス
- 投手力(防御率2.82)が特徴
- 第2主成分での位置が示唆的
- 守備面での課題(守備率.985)
西武
- 第1主成分が最も低い → 攻撃面での課題
- 打率(.212)がリーグ最低
- 改善ポイントが明確に示されている
5.2 チーム強化への示唆
1. 打撃力の評価
- 第1主成分により、チームの攻撃力を定量的に評価
- ソフトバンクの打撃の強さが明確に
- 西武の打撃面での課題が顕在化
2. 投手力の評価
- 第2主成分により、投手陣の実力を可視化
- オリックス、ソフトバンクの投手力の高さを確認
- 楽天、ロッテの投手陣強化の必要性を示唆
5.3 実践的な活用方法
この分析結果は以下のような場面で活用できます。
-
チーム強化の方向性検討
- 主成分スコアから弱点を特定
- 重点的な強化領域の決定
- トレード戦略への示唆
-
対戦戦略の立案
- 相手チームの特徴理解
- 効果的な戦術の選択
- 投手起用の最適化
-
スカウティング活動への応用
- チームに不足している要素の特定
- 補強ポイントの明確化
- 選手評価の定量的基準
6. 今後の展開と課題
6.1 分析の発展可能性
-
時系列での分析拡張
- シーズン中の変動分析
- 年度間比較
- トレンド予測
-
より詳細な指標の追加
- 投手指標の細分化
- 状況別成績の組み込み
- 選手個人の貢献度分析
-
機械学習モデルとの連携
- 勝敗予測モデルの構築
- 選手パフォーマンス予測
- リアルタイム分析システムの開発
6.2 実装上の課題と改善点
-
データ収集の自動化
- APIを活用したデータ取得
- リアルタイムデータの活用
- データクレンジングの効率化
-
分析精度の向上
- より多くの指標の統合
- 状況要因の考慮
- モデルの定期的な更新
-
可視化の改善
- インタラクティブな表示
- リアルタイムアップデート
- レポート自動生成
おわりに
本分析では、主成分分析を用いてNPBパリーグの各チームの特徴を多角的に評価しました。この手法により、単純な成績比較では見えにくいチームの特徴や課題を可視化することができました。
データサイエンスの手法を野球分析に適用することで、より客観的で深い洞察を得ることが可能です。今後は、さらなるデータの蓄積と分析手法の改善により、より精緻な分析が可能になることが期待されます。
なお、本記事の分析や解釈は、限られたデータと特定の分析手法に基づいています。実際のチーム評価にはより多くの要因が関係していることをご理解いただければ幸いです。より正確な情報については、公式統計やチーム発表の情報をご確認ください。
あとがき
下記に公開した野球のデータ分析の記事です。
パリーグ
- https://qiita.com/wooooo/items/4f59406f741818a3a7e6
- https://qiita.com/wooooo/items/2242befee721d728b070
- https://qiita.com/wooooo/items/36ff2f631b9e00ed624c
セリーグ