はじめに:機械学習に挑戦!
最近、機械学習を勉強しています。
そこで、実際にプレミアリーグのデータを使って機械学習を体験してみました。
プレミアリーグの試合データを利用!
今回使ったのは、昨シーズン(2024-2025)の試合結果データです。
こちらのサイトからダウンロードしてきました。
主な特徴量として、以下を選びました。
- シュート数(HS, AS)
- 枠内シュート数(HST, AST)
- ファウル数(HF, AF)
- カード数(HY, AY)
目的変数(ターゲット)は試合結果(勝ち・引き分け・負け)を指定します。
機械学習モデルを作ってみる
実際のコードがこちらです。
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import LabelEncoder
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score, classification_report
import joblib
# 1. データ読み込み
df = pd.read_csv('epl2024.csv')
# 2. 必要なカラムだけ抜き出し
features = ['HS', 'AS', 'HST', 'AST', 'HF', 'AF', 'HC', 'AC', 'HY', 'AY'] # シュート数、ファウル数、カード数など
target = 'FTR' # 試合結果(H/D/A)
# 3. 特徴量とターゲットのデータ作成
X = df[features]
y = df[target]
# 4. ラベルエンコーディング(目的変数を数字に変換)
le = LabelEncoder()
y_encoded = le.fit_transform(y) # H->0, D->1, A->2 などになる
# 5. 学習用とテスト用に分割
X_train, X_test, y_train, y_test = train_test_split(X, y_encoded, test_size=0.2, random_state=42)
# 6. モデル作成・学習
model = RandomForestClassifier(n_estimators=100, random_state=42)
model.fit(X_train, y_train)
# 7. 予測と評価
y_pred = model.predict(X_test)
print("Accuracy:", accuracy_score(y_test, y_pred))
print("\nClassification Report:\n", classification_report(y_test, y_pred, target_names=le.classes_))
# 8. 学習後にモデルとラベルエンコーダーを保存
joblib.dump(model, 'epl_rf_model.pkl')
joblib.dump(le, 'label_encoder.pkl')
予測結果と評価を見てみる
コードを実行したところ、以下の結果が出力されました。
Accuracy: 0.5921052631578947
Classification Report:
precision recall f1-score support
A 0.62 0.75 0.68 28
D 0.15 0.12 0.14 16
H 0.76 0.69 0.72 32
accuracy 0.59 76
macro avg 0.51 0.52 0.51 76
weighted avg 0.58 0.59 0.58 76
Accuracy(正解率)は、59%という結果になりました。
詳しく見ると、アウェイ勝ち(A)とホーム勝ち(H)は適合率、再現率がともに高いので、
ある程度正確に予測できているようです。
一方で引き分け(D)は予測が難しいということがわかりました。
実際に予測してみたら?
モデルの作成が完了したので、実際にこのモデルを使って予測してみます。
import pandas as pd
import numpy as np
import joblib
model = joblib.load('epl_rf_model.pkl')
le = joblib.load('label_encoder.pkl')
# 新しい試合データ(特徴量名付きでDataFrameにする)
new_match = pd.DataFrame(
[[15, 8, 1, 3, 10, 12, 5, 4, 2, 1]],
columns=['HS', 'AS', 'HST', 'AST', 'HF', 'AF', 'HC', 'AC', 'HY', 'AY']
)
predicted_num = model.predict(new_match)
predicted_label = le.inverse_transform(predicted_num)
print(f"予測結果: {predicted_label[0]}")
新しい試合の予測結果は?
出力結果は以下でした。
予測結果: A
この例では、ホームチームの枠内シュートが1本、アウェイチームの枠内シュートが3本なので
アウェイチームが勝つだろう、という予測みたいです。
まとめ
機械学習の知識がほぼないわたしですが、実際に手を動かしてみることで理解が深まりました。
今度は来シーズンの順位予測など、さらに高度な分析をしてみたいです
(推しのマンチェスターユナイテッドが1位になることを願って・・!)