友人が,World Cup の点数予想皆でしようではないかというということを持ちかけてきた.しかし,点数予想と言われてもさっぱり見当がつかない.そこで日曜研究家として,この点数予想のシミュレーションプログラムをモンテカルロ法で作ってみることにした.以前からモンテカルロ法のシミュレータには興味があり,同僚にいろいろ聞いていたのだが,特定の分布関数を模倣するタイプのものを作ったことがなかったため,これを機会に作ってみようと思ったのだ.
私の会社はモンテカルロ法(の一種)をシミュレーションするプログラムを作成して販売している.これは物理現象などのシミュレーションには使えるが,サッカーの予想にこれが使えるかと言えば,まあ,かなり難しいだろう.一時間かそこらしか時間をかけたくないこともある.ワールドカップファンであれば,別に計算しなくてもある程度わかるだろう.それに個々の試合の結果はまず予想できない.アシモフの銀河帝国興亡史のハリ・セルダンの社会心理学と同様,128試合の点数の平均点数とか分布とかはある程度予想できるが,個々の試合の結果はまったくわからないのである.しかし私にはまったくわからないので,それよりは多少ましというものでも良いのではないかと思った.この方法は株価の予想にも使われているという話である.
数学では仮定の範囲内でかなり正しい答えを導くことができる.仮定が重要だ.問題はどこまで仮定が実際の世界と比較して正しいのかである.私が簡単に計算できるものとして,この問題に対して次の仮定をした.
仮定1. 各試合でそれぞれのチームが取る点数は独立とする.
仮定2. 今回のワールドカップでの各試合での得点の分布は前回のものと同じとする.
まず,仮定1 であるが,これはとんでもない仮定である.独立ということは,相手のチームに得点が依存しないのである.どんな相手と戦ってもチームは同じ得点が得られる.無茶である.しかしはっきり言って,全然ワールドカップを知らない私には,「ワールドカップとなれば,たいがいのチームの実力は伯仲しているんじゃないかな」と単純に思ったわけである.それが仮定1である.これが無理な仮定であるというのは後で結果を見ればわかるだろう.仮定が間違っていればどんな数学も役立たず,という良い例になるかもしれない.
次に仮定2であるが,友人の点数予想の Web Page には去年のものしかないのでこうした.過去全てのワールドカップの統計をとったらいいとは思うし,プログラムには単にデータを入力すればいいので簡単に対応できるが,これは私のめんどくさがりからくる限界である.データは前回だけ,という恣意的な仮定というのもあまり現実としては役に立たないのだろうれども,開催回によってワールドカップには得点数に極端な差はないんじゃないか? もちろん私は知らないけれども...
さて,この二つの仮定に基いて点数予想をするプログラムを作ってみた.それが wc2010.rb である.このプログラムは去年の点数分布と似た分布になる点数分布を ruby の疑似乱数生成器によって生成する.問題は,疑似乱数生成器をいかに初期化するか(その乱数発生の種をいくつにするか),であるが,これは運である.私の誕生日にするとか,今のこの時間の秒数を年の初めから数えたものにするとか,いろいろあるが,単純に 42 にする.
前回 2006 年の得点数の分布は以下である.
WC2006 result distribution
Points
0 :************************************************
1 :************************************
2 :****************************
3 :***********
4 :****
5 :
6 :*
私の Monte-Carlo シミュレーション結果の予想の分布は以下である.
Points
0 :******************************************
1 :******************************************
2 :*******************************
3 :*******
4 :*****
5 :
6 :*
似ている分布になっていることがわかるであろう.前回 5 点をとった試合がなかったので,5点が今回の試合であったら既に手も足も出ない.また,7点以上もだめである.
さて,本プログラムの点数予想も載せておこう.今の所,第4試合,ARG:NGA の1-0しか当てていない.やはり点数は相手によらないという仮定に無理がありすぎたか.
Estimate Result
[1]: 2 1 1 1
[2]: 2 0 0 0
[3]: 2 1 2 0
[4]: 1 0 1 0 -> match ARG:NGA
[5]: 2 3 1 1
[6]: 1 2 0 1
[7]: 1 1 0 1
[8]: 2 3 4 0
[9]: 2 2 2 0
[10]: 0 0 1 0
[11]: 0 1 1 1
[12]: 0 2 1 1
[13]: 2 0 0 0
[14]: 0 0
[15]: 1 1
[16]: 0 0
[17]: 1 1
[18]: 0 4
[19]: 2 2
[20]: 1 2
[21]: 1 4
[22]: 0 6
[23]: 2 1
[24]: 1 0
[25]: 1 1
[26]: 0 1
[27]: 1 2
[28]: 1 3
[29]: 1 3
[30]: 0 2
[31]: 1 0
[32]: 0 1
[33]: 0 0
[34]: 0 2
[35]: 1 0
[36]: 3 3
[37]: 0 2
[38]: 1 0
[39]: 1 2
[40]: 2 1
[41]: 1 0
[42]: 4 0
[43]: 0 0
[44]: 1 1
[45]: 0 1
[46]: 2 0
[47]: 0 4
[48]: 0 1
[49]: 2 0
[50]: 1 2
[51]: 1 0
[52]: 2 0
[53]: 0 1
[54]: 1 2
[55]: 0 2
[56]: 0 0
[57]: 1 1
[58]: 2 4
[59]: 3 1
[60]: 0 2
[61]: 1 2
[62]: 1 2
[63]: 1 0
[64]: 0 2