Masser’s Blog

データサイエンティスト/Kaggle/Python/ADHD/旅行/サンフレ 等語る予定。

今期のサンフレッチェ広島の観客動員数を機械学習で予測した

私は広島出身ということもあり、サンフレッチェ広島のサポーターでありますが、これを機械学習で生かせないか考えてみました。そこで2009年から2017年までの観客データやその日の天候、その他の要素から2018年の観客動員数を機械学習で予測してみました。ただ、Python学習してまだ2日であり、あくまで機械学習の勉強のために作成したので、結果としてはしょぼい結果となってしまいますがご了承のほどよろしくお願いします。

観客動員数の分布

2009年から2017年までの観客動員数の分布をグラフで表すとこんな感じとなりました。

import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
df = pd.read_csv("sanfdata1.csv", encoding="SHIFT_JIS")
y_Audi =df['Audience']
ax = sns.distplot(y_Audi)
plt.show()

上のソースコードで下記のグラフが表示できます。 f:id:masser199:20180205063114j:plain

予測のための要素

観客動員に影響する要素として以下の項目を考えました。

* 節数

ホーム開幕戦(1節、2節)、ホーム最終戦(33節、34節)、その他に分けて平均を算出しました。算出したソースコードは次のようになります。

from pandas import DataFrame
grouped = df.groupby('Setu')
grouped.mean().Audience

結果の平均はこのようになりました。ホーム開幕戦、ホーム最終戦は多い傾向があります。

対戦相手 動員数
ホーム開幕戦 19230.909091
ホーム最終戦 23149.000000
その他 14583.143939
* 対戦相手

対戦相手ごとの観客動員の平均を算出しました。算出したソースコードは次のようになります。

grouped = df.groupby('Team')
grouped.mean().Audience

結果の平均はこのようになりました。やはり浦和が一番多く、第二グループとして鹿島、F東京、横浜M、大阪の2チームでしょうか。面白いのは湘南が平均2位ですが、これは2013年、2015年と優勝が懸かったホーム最終戦と被ったためです。あと京都、福岡もホーム最終戦の影響で多いですね。

対戦相手 動員数
鹿島 15760
浦和 23658.777778
大宮 14724
千葉 11572
鹿島 13872.75
F東京 17636.25
川崎 13802
横浜M 15502.222222
湘南 21319.75
甲府 12737.833333
松本 7956
新潟 13785.444444
清水 14709.75
磐田 14162.857143
名古屋 14064.714286
京都 17748
G大阪 16970
C大阪 16996.428571
神戸 12691.625
徳島 11776
福岡 16413.5
鳥栖 15164.166667
大分 10829.5
* 順位

順位ごとの観客動員の平均を算出しました。算出したソースコードは次のようになります。

grouped = df.groupby('Place')
grouped.mean().Audience

結果は次のようになりました。1位が飛びぬけて多く、勝たないと客が来ない広島県民の気質が表れてますね。カープの観客動員数で集計するともっと顕著かもしれません。

順位 動員数
1位 21162.000000
2位ー9位 15093.833333
10位以下 12980.318182
* 天気

順位ごとの観客動員の平均を算出しました。算出したソースコードは次のようになります。

grouped = df.groupby('Weather')
grouped.mean().Audience

結果は次のようになりました。予想通り雨が降ると観客動員が減りますね。

天気 動員数
晴れ、曇り 15839.6875
13224.0000
* 気温

気温ごとの平均を算出しました。算出したソースコードは次のようになります。

grouped = df.groupby('Heat')
grouped.mean().Audience

結果は次のようになりました。寒いときに観客動員が多いのはホーム開幕戦、ホーム最終戦の影響があるかもしれません。

気温 動員数
10度以下 17890.923077
11度ー15度 17294.454545
16度ー20度 14713.500000
21度ー25度 14258.352941
26度以上 15699.647059
* 時間帯

時間帯ごとの観客動員の平均を算出しました。算出したソースコードは次のようになります。

grouped = df.groupby('Time')
grouped.mean().Audience

結果は次のようになりました。夜開催が少ないのは平日開催の影響が多いでしょうね。

天気 動員数
1200-1600 16375.242857
1700以降 14616.939024
* 平日、休日

平日開催、休日開催ごとの観客動員の平均を算出しました。算出したソースコードは次のようになります。

grouped = df.groupby('Time')
grouped.mean().Audience

結果は次のようになりました。明らかに平日開催のほうが少ないですね。

平日、休日 動員数
平日 10813.210526
休日  16085.751880
* カープ開催あり、なし

同日にカープの試合があるかどうかで観客動員の平均を算出しました。ただ同日でも時間帯が違う場合は別開催としています。算出したソースコードは次のようになります。

grouped = df.groupby('Carp')
grouped.mean().Audience

結果は次のようになりました。カープ開催なしのほうが観客動員多いです。やはりこの辺はなんとかならないですかね。

カープ開催あり、なし 動員数
なし 15868.693069
あり  14551.333333

ランダムフォレストを用いた機械学習による予測

ランダムフォレストを使いまして第1節札幌戦の予測をしてみました。(本当はxgboostとか試したかったがあまりいい結果がでなかった)

import pandas as pd
from sklearn.ensemble import RandomForestClassifier
test_df = pd.read_csv("sanftest.csv", encoding="SHIFT_JIS")
train_df = pd.read_csv("sanftrain.csv", encoding="SHIFT_JIS")
train_X = train_df[['Setu','Team','Place','Weather','Heat','Time','Holiday','Carp']]
test_X = test_df[['Setu','Team','Place','Weather','Heat','Time','Holiday','Carp']]
train_Y = train_df['Audience']
clf = RandomForestClassifier(random_state=0)
clf = clf.fit(train_X, train_Y)
clf.predict(test_X)

結果はこうなりました。天気予報が出たらまた改めて予測してみたいですね。また、もっと良さそうなアルゴリズムがあったら試したいです。

対戦相手 予想動員数
第1節 14671

考察

今回は天候、時間帯、対戦相手等表に出ているデータのみで算出しましたが、表に出ていない年パスの数、歩いて行ける範囲の駐車場数、直前のチケットの売り上げ枚数の要素を加えるともっと正確な数が予測できるのではないかと思います。おそらくクラブはやっているはずで、これを基にしてシャトルバスの本数とか予測してるでしょう。あともう少しデータがほしいですね。