LoginSignup
8
9

More than 5 years have passed since last update.

Jリーグの試合予想をしてみた(データ分析)

Last updated at Posted at 2017-04-10

概要

Jリーグの試合予想を過去データを元にしてみた
勝ち、負け、引き分けを55%の確率で予想できた
(学習データ2573試合、テストデータ200試合)

免責

記事内容の利用による責任を一切負いません

きっかけとこれまでの取り組み

Googleが2014年頃にワールドカップの勝敗予想をした
"Googleがビッグデータを解析してW杯を予測すると全試合的中、準々決勝も当ててしまうのか?"
この記事を見てJリーグの予想もしてみようと思った。
Googleの取り組みで気になった点は
OPTAというサッカーデータによって選手、ボールの位置すべての情報がわかること。
(データ探したけど個人では取得はムリっぽい)
それをモンテカルロ法で1試合まるごとシミュレーションすることなどだ。

データ収集

Jリーグに関しては結構いろいろなサイトがある。
ご迷惑がかからないようにひっそりじっくりデータを集めた。

<入力データ>

試合状況
・・・天候、観客数、曜日、祝日かどうか、キックオフ時刻、など

ホーム、アウェーチームの過去6試合の戦歴
・・・1試合につき得点はもちろん、シュート数、パス数、パス成功率などの変数を多数入れた。平均化はせずにそのままつなげて入力。

スタメン参加選手すべてのデータ
・・・それぞれの個人のポジション、身長、体重、出身地、過去数試合の得点数

(全学習変数は754個になった)

<正解データ>

勝ち、負け、引き分けのどれかで0,1,2のラベルにした

データ処理、成型

今回はhtmlからデータを抜き出すのにはじめて本格的にbeautifulsoupを使った。
便利すぎる。もっと早く使えばよかった。
あと0〜1への正規化はしたほうがいい。np.maxとか使って2行くらいで簡単にできる。

学習ソースコード

かなり普通のscikit learnのコード

import numpy as np
from sklearn.metrics import accuracy_score
from sklearn.model_selection import GridSearchCV
from sklearn.metrics import classification_report
from sklearn.svm import SVC

all_input_np = np.load('input.npy')
all_label_np = np.load('label.npy')
train_input = all_input_np[:-200]
test_input = all_input_np[-200:]
train_result = all_label_np[:-200]
test_result = all_label_np[-200:]

tuned_parameters = [{'kernel': ['linear'], 'C': [1, 10, 100, 1000]}]

clf = GridSearchCV(SVC(), tuned_parameters, n_jobs=4, scoring="accuracy")

print(">>>START")
clf.fit(train_input, train_result)
print("Best parameters set found on development set: %s" % clf.best_params_)

print("Grid scores on development set:")
means = clf.cv_results_['mean_test_score']
stds = clf.cv_results_['std_test_score']
for mean, std, params in zip(means, stds, clf.cv_results_['params']):
        print("%0.3f (+/-%0.03f) for %r" % (mean, std * 2, params))

print("The scores are computed on the full evaluation set.")
y_true, y_pred = test_result, clf.predict(test_input)
print(classification_report(y_true, y_pred))
print(accuracy_score(y_true, y_pred))

結果

             precision    recall  f1-score   support

        0.0       0.61      0.56      0.59        87
        1.0       0.51      0.78      0.62        78
        2.0       0.00      0.00      0.00        35
avg / total       0.46      0.55      0.50       200

0.55

55%が正解率
ラベルは0が負け1が勝ち2が引き分け

ここで、ひとつ工夫点。
サッカーの試合は引き分けになることは全体の20%程度らしい
そこで、全体の正解率を上げるため、学習は引き分けは勝ちとして予測を行い
勝ち、負けのみを予測させるようにした。(逆に言うと引き分けは予測できない)

ニューラルネットワークを使った結果

正解率50%程度だった
多層パーセプトロン(3層、elu、dropout率0.5みたいな感じ)

感想

やはり限られたデータにしかアクセスできないのは厳しい。
今回集めたデータでは数理モデルを限界まで高めてもせいぜい60%くらいの正答率かと思う。
Googleがやったような1試合まるごとのシミュレーションについてはいいアイディアだと思うと同時に
サッカーをただパス成功率とかの数字だけで再現できるかは懐疑的ではある。
やっぱり試合の何らかの画像のデータをリンクさせることで人間には気づけなかった、あるいは、
人間では膨大で負うことのできない分析処理ができるのではないか、ということが1点。
もうひとつはデータ分析の過程を可視化できれば
モデルと入力データの改善の方向が見えてくるかと思う。

8
9
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
8
9