ブンデスリーガ勝敗予測 – LinearSVM
目的
ドイツ プロサッカーリーグのブンデスリーガの勝敗予測を行ってみる。
データはFootball-Data.co.ukのデータを利用する。
http://www.football-data.co.uk/germanym.php
各チームの勝敗予測を分類タスクととらえてSVMを利用して解く。
SVM(サポートベクターマシン)
Scikitlearnのチートシートに従って、LinearSVMを使ってみる。
https://scikit-learn.org/stable/tutorial/machine_learning_map/index.html
LinearSVMはSVM(サポートベクターマシン)の一種である。
SVMについてはWikipediaからの引用させていただく。
サポートベクターマシンは、線形入力素子を利用して 2 クラスのパターン識別器を構成する手法である。
wikipedia
コードは次のとおり。
from sklearn.svm import LinearSVC
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
# ブンデスリーガデータ読み込み
df = data_catalog.load('match_result')
# チーム名をダミー変数に変換
df_cat = None
for col in ['HomeTeam', 'AwayTeam']:
tmp = pd.get_dummies(df[col], prefix=col)
df_cat = pd.concat([df_cat, tmp], axis=1)
cat_col = df_cat.columns
df = pd.concat([df, df_cat], axis=1)
# 勝ち・負け・引き分けをコード値に変換
df['game_result'] = df['game_result'].astype('category')
df['game_result_cd'] = df['game_result'].cat.codes
display(dict(enumerate(df['game_result'].cat.categories)))
df_train, df_test = train_test_split(df, test_size=0.1, random_state=42)
X = df_train[cat_col]
y = df_train['game_result_cd']
X_test = df_test[cat_col]
y_test = df_test['game_result_cd']
clf = LinearSVC(random_state=0, tol=1e-5, max_iter=10000)
clf.fit(X, y)
print(f"accuracy: {accuracy_score( y_test, clf.predict(X_test))}")
"""accuracy: 0.4980392156862745"""
評価指標として、正解率 (Accuracy)を出してみたが、0.50であった。
これはランダムに勝敗予測するのと同じ結果になっている。
パラメタ最適化
LinearSVMには正則化パラメタ C がある。
これをグリッドサーチで最適化することで正解率が上がらないか試してみる。
from sklearn.model_selection import GridSearchCV
# ブンデスリーガデータ読み込み
df = data_catalog.load('match_result')
# チーム名をダミー変数に変換
df_cat = None
for col in ['HomeTeam', 'AwayTeam']:
tmp = pd.get_dummies(df[col], prefix=col)
df_cat = pd.concat([df_cat, tmp], axis=1)
cat_col = df_cat.columns
df = pd.concat([df, df_cat], axis=1)
# 勝ち・負け・引き分けをコード値に変換
df['game_result'] = df['game_result'].astype('category')
df['game_result_cd'] = df['game_result'].cat.codes
display(dict(enumerate(df['game_result'].cat.categories)))
df_train, df_test = train_test_split(df, test_size=0.1, random_state=42)
X = df_train[cat_col]
y = df_train['game_result_cd']
X_test = df_test[cat_col]
y_test = df_test['game_result_cd']
tuned_parameters = [{'C': [1e-2, 1e-1, 1, 10, 100, 1000]}]
clf = GridSearchCV(LinearSVC(random_state=0, tol=1e-5, max_iter=10000),
tuned_parameters,
cv=5,
scoring='accuracy')
clf.fit(X, y)
print(clf.best_params_)
"""{'C': 0.1}"""
print(clf.best_score_)
"""0.4951343500363108"""
print(f"accuracy: {accuracy_score(y_test, clf.predict(X_test))}")
"""accuracy: 0.5032679738562091"""
C を最適化してみたが、正解率は0.50より大きくならなかった。
考察
今回ブンデスリーガの試合結果予測をLinearSVMで試してみたが良い結果は得られなかった。
原因としては
- 特徴量がホーム・アウェイチーム名だけと少なかったこと
- LinearSVMが今回のタスクに適していなかった
が考えられる。
Scikitlearnのチートシートに従って、次はK近傍法を使っての分類を試してみる。
ディスカッション
コメント一覧
まだ、コメントがありません