初めましての方は初めまして。そうでない方はこんにちは。
今回はタイトルにある通り、来たるサッカーW杯の優勝国予想をニューラルネットワーク(Neural Network:以下NN)を用いて行った。
初めに言い訳をさせてください。
- プログラミング経験が浅く、コードが雑(変数のネーミングとかテキトーすぎワロタ)
- NN初学者ゆえ、理論については細かく書きません(サイエンス性少なすぎワロタ)
- ぶっちゃけ遊び
以上にご理解のうえ、最後まで読んでくださると幸いオブ幸い。
#経緯
研究室の先生「ラボ内ゼミでW杯優勝国予想を発表してみるのも面白いんじゃない?」
私「あ〜、アリですね」
こんな何気ない会話が今回の発端。(笑)
それに
- いつも通りたくさんの試合を見てキャッキャウフフしてるだけは勿体無えな
- 就活で溜まったストレスを何らかの形で発散してえな
- そういや最近NNを重力波解析に適用した論文読んだな
と思っていた頃だったので、ちょうどいいモチベーションになるかなと考えた。
そんなこんなで早速本題に入ろう。
#実装に向けて
さて、まずはどうやって優勝国を予想しようか。
→ team1 vs team2における互いの勝率を確率で記述し、その確率に基づいてシミュレーションを複数回行えばいいだろ
まあ、当たり前だね。
では、どうやって勝率を算出しようか。
難しいね。でもインターネットの海を航海していると、どうやら以下2つの手法が面白そうだ。
- Bradley-Terry Model
- NN
前者は結構昔からスポーツの勝敗を決定するために用いられてきた手法らしい。従来は各々の「強さ、スキル」を表す1つのパラメータを用いて「勝ち」か「負け」を推定するモデルだったが、最近は「引き分け」と、「ホームチームの優位性」という概念により拡張され、より一般化したモデルが存在する。
後者は各インプットを非線形変換することで、直感的にはわからない新たな説明変数を生成し、より本来の結果に近づいたアウトプットを出せるようになる的なアレ。
結論から言うと、後者のNNを選択した。
理由としては以下の2つ。
- MATLABで簡単に実装できる
- 後のアップデートを考慮したとき、柔軟性が高い(後述)
と言うわけで、次章で学習データについて述べる。
#学習
NNを学習させるために、どんな学習データを用いようか。
該当チームの「選手の強さ」「監督の采配」「調子」といった1チーム依存のパラメータ、該当チーム同士の「相性」などの2チーム依存のパラメータ、「気候」「観戦者数」「ピッチの良し悪し」といった環境依存のパラメータ、考えるだけで色々出てくるね。
しかしここで思い出してほしい。そう、これはただの遊びだと。
というわけで、今回は「チームの強さ」のみをインプットとして、NNに学習させる。
そして、W杯ゆえ開催国のロシアのみがホームチームの恩恵を受けれるものとする。
つまり、ホームチームの優位性を加味したNNと加味しないNNの2つを作成することになる。
次に、「チームの強さ」はどう定義するか。
→ 『FIFA18』というゲームで表されている、「ATT」「MF」「DEF」の3つを用いる。それぞれ該当チームのアタッカー陣の強さ、中盤の強さ、ディフェンス陣の強さに相当しているものだ。
↓ここで見れる。
次に、レコード(なんていうかわからん、試合のファクトデータみたいな)はどうするか。
これは非常に悩んだ。過去に行われたナショナルの試合を取ってきてもいいが、これには以下のような問題がある。
- 試合数が少ない
- 選手の流動性が激しい
そのため、他の試合データを用いるしかない。
いろいろ考えた(嘘、あんま考えてない)結果、プレミアリーグ所属チームの試合データを用いることにした。
具体的には、近年よくプレミアリーグにいる21チームを対象に、過去5シーズンの試合(一部、リーグ杯やFAを含む)を用いた。総数にして1739試合分。多いの?少ないの?
なんにせよ上記のように集めたデータはこんな感じ。
これはホームチームの優位性を加味したもので、左から、「ホームチームのATT」「ホームチームのMF」「ホームチームのDEF」「アウェイチームのATT」「アウェイチームのMF」「アウェイチームのDEF」「ホームチームの勝率」「ホームチームの引き分け率」「ホームチームの負け率」を表している。
ホームチームの優位性を加味しない場合に関しては、上記データにおいてホームとアウェイ両方の結果を合算することによって再現している。
#実装
実装のパートに移る。
先でも述べたが、ここではMATLABを用いる。また、NNをMATLAB上で実装するためのパッケージ(?)としてNeural Network Toolboxを用いる。
setdemorandstream(19941202) %ウェイトW_ijの初期値設定
net_hw = patternnet(10); %home-weighted用のNN
net_nw = patternnet(10); %non-weighted用のNN
[net_hw,tr_hw] = train(net_hw,param_data_hw,ans_data_hw); %NNの学習
nntraintool
[net_nw,tr_nw] = train(net_nw,param_data_nw,ans_data_nw); %NNの学習
nntraintool
NNの学習はざっと書くとこんな感じでできる。setdemorandstreamでは、NNのウェイト初期値を設定している。つまり、ここの値を変えると、学習におけるウェイトの初期値が変わるので、固定することで同じ学習結果を再現できる(?)。
浅いNNの構成はpatternnetで行うことができ、入力の値はNNのhidden layerのノード数を表す。
trainで学習を行う。入力はそれぞれ新規のnetwork(或いは既存のものでも)、学習データ(parameter)、学習データ(answer)である。学習データ(parameter)はFIFAにおける各パラメータの部分、学習データ(answer)はそれぞれの勝率、引き分け率、負け率である。
学習を終えると、以下のような画面が出てくる。
これを見ると、インプットが6つ(team1とteam2それぞれのATT、MF、DEF)、hidden layerが10、アウトプットが3つ(勝率、引き分け率、負け率)となってることがわかる。活性化関数は何が使われているんだろう。まあぶっちゃけどれでもいいと思うので、今回は無視。ちなみにplotperformとかを使えば、この学習のperformanceが見られる。
そんなこんなで、2チームのFIFAパラメータを突っ込めば勝率等が計算できるようになったわけだ。あとは、グループリーグをシミュレートするようなロジック、トーナメントをシミュレートするようなロジックをなんらかの方法で完成させれば終わり。今回は端折るが、要望があればコードをアップロードする予定。
ちなみに10000回シミュレートするのに3時間くらいかかりました。(研究室のPCで)
#結果
多分ここがみんな気になるのではなかろうか。早速結果を載せよう。それぞれ10000回W杯をシミュレートした時の優勝確率、準優勝確率、3位確率である。なお、単純に10000回のうち何回優勝、準優勝、3位になったかという回数を確率に変換しただけなので、条件付き確率は考慮していない。各自計算してくだされ。
うん、なんか予想通り感。ただ、ホームチームの優位性が効きすぎて、ロシアが結構頑張れてるイメージ。まあでも日韓W杯の時に韓国がベスト4入ったように。。。ゲフンゲフン。失礼。
結果の考察は各々で楽しんでくださいな。
ちなみに日本の優勝確率は0.03%だそうな。頑張れ日本、楽しませておくれ。
#終わりに
初めてのqiita投稿であり、何を書いたらいいのかわからんかったので、自由に書いた。
とりあえず自分なりの楽しみ方はできたのでその点は良かった。
今後としては学習データのアップデートを予定している。具体的にはインプットをもっと増やしたい。
各国の経済状況、サッカーに対する投資意欲、等々を数値化できれば、10年やもっと先のW杯も予想できるんじゃないかな。そんな「あったらいいな、できたらいいな」というドラえもん思想を自分の中で消化していきたい。
また何か面白いことやったら投稿します。ありがとうございました。