はじめに
まず、この記事を書く前に、2022年12月1日(現地時間)にカタール、ハリーファ国際スタジアム, ライヤーンで行われた、日本対スペイン戦、日本がスペインに、2対1で勝利したことにより、決勝トーナメントに進出できました。同時刻に行われた、コスタリカ対ドイツ戦でドイツがコスタリカにリードした時点で、日本が勝利したまま逃げ切らないといけない試合展開でハラハラドキドキしてしまいました。
このシリーズは、以前投稿した2022 FIFAワールドカップ、日本が決勝トーナメントに進出できる確率(2022年11月27日時点)はこちら、で終了する予定でしたが、このまま日本がワールドカップを優勝する確率を勝手に計算することにしました。
まずは、2022 FIFAワールドカップ、決勝トーナメントに進出した16チームのグループリーグでの成績を下記に示します。
2022 FIFAワールドカップ、決勝トーナメントに進出した16チームのグループリーグでの勝ち点表
試合数 | 勝ち数 | 引き分け数 | 負け数 | 得点数 | 失点数 | 得失点差 | 勝ち点 | |
---|---|---|---|---|---|---|---|---|
オランダ | 3 | 2 | 1 | 0 | 5 | 1 | +4 | 7 |
セネガル | 3 | 2 | 0 | 1 | 5 | 4 | +1 | 6 |
イングランド | 3 | 2 | 1 | 0 | 9 | 2 | +7 | 7 |
アメリカ合衆国 | 3 | 1 | 2 | 0 | 2 | 1 | +1 | 5 |
アルゼンチン | 3 | 2 | 0 | 1 | 5 | 2 | +3 | 6 |
ポーランド | 3 | 1 | 1 | 1 | 2 | 2 | ±0 | 4 |
フランス | 3 | 2 | 0 | 1 | 6 | 3 | +3 | 6 |
オーストラリア | 3 | 2 | 0 | 1 | 3 | 4 | -1 | 6 |
日本 | 3 | 2 | 0 | 1 | 4 | 3 | +1 | 6 |
スペイン | 3 | 1 | 1 | 1 | 9 | 3 | +6 | 4 |
モロッコ | 3 | 2 | 1 | 0 | 4 | 1 | +3 | 7 |
クロアチア | 3 | 1 | 2 | 0 | 4 | 1 | +3 | 5 |
ブラジル | 3 | 2 | 0 | 1 | 3 | 1 | +2 | 6 |
スイス | 3 | 2 | 0 | 1 | 4 | 3 | +1 | 6 |
ポルトガル | 3 | 2 | 0 | 1 | 6 | 4 | +2 | 6 |
韓国 | 3 | 1 | 1 | 1 | 4 | 4 | ±0 | 4 |
決勝トーナメントの全16試合をシミュレートするスクリプトを作成する
全16試合をシミュレートして、どのチームの優勝確率が高いか試してみます。
試合は、グループリーグでの勝ち点をチームの戦力値として使用します。
免責事項
その前に、このスクリプトの実行は自己責任でお願いします。本スクリプトを実行することにより生じるいかなる問題に関しましても、筆者は一切責任を負いません。予めご了承ください。
決勝トーナメントの全16試合をシミュレートするスクリプトをPythonで作成する
当初グループリーグでの勝敗を利用して、全16試合をシミュレートするスクリプトを作成しようとしたところ、組み合わせが、6の16乗=2821109907456通りと恐ろしいことになってしまい、家庭用のコンピュータではスクリプトが終了するまで324日かかるという計算結果になってしまったため、チームの戦力値から乱数を使って勝敗を決める方法を採用することにしました。
パターンを試すスクリプトを下記に掲載します。Brute force的な片っ端から試しているスクリプトなのでツッコミどころ満載ですが、ご愛嬌ということで、目を瞑っていただきたく、よろしくお願いします。
# -*- coding: utf-8 -*-
import random
# チーム名の登録
netherlands = 'オランダ'.center(7, ' ')
united_states = 'アメリカ合衆国'.center(7, ' ')
argentina = 'アルゼンチン'.center(7, ' ')
australia = 'オーストラリア'.center(7, ' ')
japan = '日本'.center(7, ' ')
croatia = 'クロアチア'.center(7, ' ')
brazil = 'ブラジル'.center(7, ' ')
south_korea = '韓国'.center(7, ' ')
england = 'イングランド'.center(7, ' ')
senegal = 'セネガル'.center(7, ' ')
france = 'フランス'.center(7, ' ')
poland = 'ポーランド'.center(7, ' ')
morocco = 'モロッコ'.center(7, ' ')
spain = 'スペイン'.center(7, ' ')
portugal = 'ポルトガル'.center(7, ' ')
switzerland = 'スイス'.center(7, ' ')
# グループリーグの勝ち点を戦力値として登録
TEAMS = {netherlands: 7,
united_states: 5,
argentina: 6,
australia: 6,
japan: 6,
croatia: 5,
brazil: 6,
south_korea: 4,
england: 7,
senegal: 6,
france: 6,
poland: 4,
morocco: 7,
spain: 4,
portugal: 6,
switzerland: 6}
# 優勝、準優勝、3位、ベスト4、ベスト8、初戦敗退の集計用インデックス
WINNER = 0
RUNNER_UP = 1
THIRD_PLACE = 2
BEST_4 = 3
BEST_8 = 4
BEST_16 = 5
# 優勝、準優勝、3位、ベスト4、ベスト8、初戦敗退の集計用
RESULTS = {netherlands: [0, 0, 0, 0, 0, 0],
united_states: [0, 0, 0, 0, 0, 0],
argentina: [0, 0, 0, 0, 0, 0],
australia: [0, 0, 0, 0, 0, 0],
japan: [0, 0, 0, 0, 0, 0],
croatia: [0, 0, 0, 0, 0, 0],
brazil: [0, 0, 0, 0, 0, 0],
south_korea: [0, 0, 0, 0, 0, 0],
england: [0, 0, 0, 0, 0, 0],
senegal: [0, 0, 0, 0, 0, 0],
france: [0, 0, 0, 0, 0, 0],
poland: [0, 0, 0, 0, 0, 0],
morocco: [0, 0, 0, 0, 0, 0],
spain: [0, 0, 0, 0, 0, 0],
portugal: [0, 0, 0, 0, 0, 0],
switzerland: [0, 0, 0, 0, 0, 0]}
# いつも結果が同じになるように乱数を初期化する
random.seed(0)
# 対戦関数
def match(team1, team2, round=None):
win = random.choices([team1, team2], weights=[TEAMS[team1], TEAMS[team2]])[0]
lose = team1 if win == team2 else team2
if round is not None:
RESULTS[lose][round] += 1
return win, lose
# 1000000回試す
TOTAL = 1000000
# 1000000回試す
for i in range(TOTAL):
# ラウンド16、全8試合の勝敗
best8_1, _ = match(netherlands, united_states, BEST_16)
best8_2, _ = match(argentina, australia, BEST_16)
best8_3, _ = match(japan, croatia, BEST_16)
best8_4, _ = match(brazil, south_korea, BEST_16)
best8_5, _ = match(england, senegal, BEST_16)
best8_6, _ = match(france, poland, BEST_16)
best8_7, _ = match(morocco, spain, BEST_16)
best8_8, _ = match(portugal, switzerland, BEST_16)
# 準々決勝、全4試合の勝敗
best4_1, _ = match(best8_1, best8_2, BEST_8)
RESULTS[best4_1][BEST_4] += 1
best4_2, _ = match(best8_3, best8_4, BEST_8)
RESULTS[best4_2][BEST_4] += 1
best4_3, _ = match(best8_5, best8_6, BEST_8)
RESULTS[best4_3][BEST_4] += 1
best4_4, _ = match(best8_7, best8_8, BEST_8)
RESULTS[best4_4][BEST_4] += 1
# 準決勝、全2試合の勝敗
final_1, play_off1 = match(best4_1, best4_2)
final_2, play_off2 = match(best4_3, best4_4)
# 3位決定戦の勝敗と集計結果用の辞書に3位のカウントを加算
third_place, _ = match(play_off1, play_off2)
RESULTS[third_place][THIRD_PLACE] += 1
# 決勝の勝敗と集計結果用の辞書に優勝と準優勝のカウントを加算
winner, runner_up = match(final_1, final_2)
RESULTS[winner][WINNER] += 1
RESULTS[runner_up][RUNNER_UP] += 1
print(f'{winner}: 優勝')
# 1000000回試した決勝トーナメント結果を、優勝回数の多い順でソートする
sorted1 = sorted(RESULTS.items(), key=lambda x:x[1][0], reverse=True)
# 結果をテキストファイル'bracket.txt'に出力する
with open('bracket.txt', 'w') as fw:
# 優勝、準優勝、3位、ベスト4、ベスト8、初戦敗退の集計結果を表示
for k, v in sorted1:
print(f'{k}: 優勝 {str(v[WINNER]).rjust(3)}回({v[WINNER]/TOTAL*100:6.2f}%)、'
f'準優勝 {str(v[RUNNER_UP]).rjust(3)}回({v[RUNNER_UP]/TOTAL*100:6.2f}%)、'
f'3位 {str(v[THIRD_PLACE]).rjust(3)}回({v[THIRD_PLACE]/TOTAL*100:6.2f}%)'
f'ベスト4 {str(v[BEST_4]).rjust(3)}回({v[BEST_4]/TOTAL*100:6.2f}%)'
f'ベスト8 {str(v[BEST_8]).rjust(3)}回({v[BEST_8]/TOTAL*100:6.2f}%)'
f'初戦敗退 {str(v[BEST_16]).rjust(3)}回({v[BEST_16]/TOTAL*100:6.2f}%)')
fw.write(f'{k}: 優勝 {str(v[WINNER]).rjust(3)}回({v[WINNER]/TOTAL*100:6.2f}%)、'
f'準優勝 {str(v[RUNNER_UP]).rjust(3)}回({v[RUNNER_UP]/TOTAL*100:6.2f}%)、'
f'3位 {str(v[THIRD_PLACE]).rjust(3)}回({v[THIRD_PLACE]/TOTAL*100:6.2f}%)'
f'ベスト4 {str(v[BEST_4]).rjust(3)}回({v[BEST_4]/TOTAL*100:6.2f}%)'
f'ベスト8 {str(v[BEST_8]).rjust(3)}回({v[BEST_8]/TOTAL*100:6.2f}%)'
f'初戦敗退 {str(v[BEST_16]).rjust(3)}回({v[BEST_16]/TOTAL*100:6.2f}%)\n')
スクリプトの説明
randomはPythonの標準モジュールです。6の16乗の勝敗を試せないので、今回は簡易的に乱数を使用して擬似的に優勝確率を求めることにしました。
import random
決勝トーナメントに進出した16チームを登録しています。後で見やすいように、最長文字列「アメリカ合衆国」の7文字で空白で埋めてセンタリングしています。
# チーム名の登録
netherlands = 'オランダ'.center(7, ' ')
united_states = 'アメリカ合衆国'.center(7, ' ')
argentina = 'アルゼンチン'.center(7, ' ')
australia = 'オーストラリア'.center(7, ' ')
japan = '日本'.center(7, ' ')
croatia = 'クロアチア'.center(7, ' ')
brazil = 'ブラジル'.center(7, ' ')
south_korea = '韓国'.center(7, ' ')
england = 'イングランド'.center(7, ' ')
senegal = 'セネガル'.center(7, ' ')
france = 'フランス'.center(7, ' ')
poland = 'ポーランド'.center(7, ' ')
morocco = 'モロッコ'.center(7, ' ')
spain = 'スペイン'.center(7, ' ')
portugal = 'ポルトガル'.center(7, ' ')
switzerland = 'スイス'.center(7, ' ')
グループリーグの勝ち点を戦力値として登録します。
# グループリーグの勝ち点を戦力値として登録
TEAMS = {netherlands: 7,
united_states: 5,
argentina: 6,
australia: 6,
japan: 6,
croatia: 5,
brazil: 6,
south_korea: 4,
england: 7,
senegal: 6,
france: 6,
poland: 4,
morocco: 7,
spain: 4,
portugal: 6,
switzerland: 6}
優勝、準優勝、3位、ベスト4、ベスト8、初戦敗退の集計用インデックスです。
# 優勝、準優勝、3位、ベスト4、ベスト8、初戦敗退の集計用インデックス
WINNER = 0
RUNNER_UP = 1
THIRD_PLACE = 2
BEST_4 = 3
BEST_8 = 4
BEST_16 = 5
優勝、準優勝、3位、ベスト4、ベスト8、初戦敗退の集計用辞書です。全て0で初期化しています。
# 優勝、準優勝、3位、ベスト4、ベスト8、初戦敗退の集計用
RESULTS = {netherlands: [0, 0, 0, 0, 0, 0],
united_states: [0, 0, 0, 0, 0, 0],
argentina: [0, 0, 0, 0, 0, 0],
australia: [0, 0, 0, 0, 0, 0],
japan: [0, 0, 0, 0, 0, 0],
croatia: [0, 0, 0, 0, 0, 0],
brazil: [0, 0, 0, 0, 0, 0],
south_korea: [0, 0, 0, 0, 0, 0],
england: [0, 0, 0, 0, 0, 0],
senegal: [0, 0, 0, 0, 0, 0],
france: [0, 0, 0, 0, 0, 0],
poland: [0, 0, 0, 0, 0, 0],
morocco: [0, 0, 0, 0, 0, 0],
spain: [0, 0, 0, 0, 0, 0],
portugal: [0, 0, 0, 0, 0, 0],
switzerland: [0, 0, 0, 0, 0, 0]}
いつも結果が同じになるように乱数を初期化しています。毎回違う結果にする場合は、seedを設定する必要はありません。
# いつも結果が同じになるように乱数を初期化する
random.seed(0)
チーム戦力値から、勝利チームと敗者チームを決める関数です。
- random.choices関数に対戦する、team1とteam2、team1とteam2の戦力値を渡し、勝利チームを決定します。勝利チームは配列で渡されるので、[0]番目を指定してあげます。
- pythonの三項演算子で、勝利チームではないチームを敗者チームとして登録します。
- roundが指定されていれば、その指定されたラウンドで敗退したというカウントを加算しています。
# 対戦関数
def match(team1, team2, round=None):
win = random.choices([team1, team2], weights=[TEAMS[team1], TEAMS[team2]])[0]
lose = team1 if win == team2 else team2
if round is not None:
RESULTS[lose][round] += 1
return win, lose
今回は1000000回試すことにしました。
# 1000000回試す
TOTAL = 1000000
# 1000000回試す
for i in range(TOTAL):
ラウンド16、全8試合の勝敗を試しています。
# ラウンド16、全8試合の勝敗
best8_1, _ = match(netherlands, united_states, BEST_16)
best8_2, _ = match(argentina, australia, BEST_16)
best8_3, _ = match(japan, croatia, BEST_16)
best8_4, _ = match(brazil, south_korea, BEST_16)
best8_5, _ = match(england, senegal, BEST_16)
best8_6, _ = match(france, poland, BEST_16)
best8_7, _ = match(morocco, spain, BEST_16)
best8_8, _ = match(portugal, switzerland, BEST_16)
準々決勝、全4試合の勝敗を試しています。この時点で、ベスト4が出揃うので、勝利チームにベスト4のカウントを加算しています。
# 準々決勝、全4試合の勝敗
best4_1, _ = match(best8_1, best8_2, BEST_8)
RESULTS[best4_1][BEST_4] += 1
best4_2, _ = match(best8_3, best8_4, BEST_8)
RESULTS[best4_2][BEST_4] += 1
best4_3, _ = match(best8_5, best8_6, BEST_8)
RESULTS[best4_3][BEST_4] += 1
best4_4, _ = match(best8_7, best8_8, BEST_8)
RESULTS[best4_4][BEST_4] += 1
準決勝、全2試合の勝敗を試しています。勝利チームは決勝戦へ、敗者チームは3位決定戦へまわります。
# 準決勝、全2試合の勝敗
final_1, play_off1 = match(best4_1, best4_2)
final_2, play_off2 = match(best4_3, best4_4)
3位決定戦の勝敗を試しています。勝利チームに3位のカウントを加算しています。
# 3位決定戦の勝敗と集計結果用の辞書に3位のカウントを加算
third_place, _ = match(play_off1, play_off2)
RESULTS[third_place][THIRD_PLACE] += 1
決勝の勝敗を試しています。勝利チームに優勝、敗者チームに準優勝のカウントを加算しています。
# 決勝の勝敗と集計結果用の辞書に優勝と準優勝のカウントを加算
winner, runner_up = match(final_1, final_2)
RESULTS[winner][WINNER] += 1
RESULTS[runner_up][RUNNER_UP] += 1
print(f'{winner}: 優勝')
1000000回試した決勝トーナメント結果を、優勝回数の多い順でソートしています。
# 1000000回試した決勝トーナメント結果を、優勝回数の多い順でソートする
sorted1 = sorted(RESULTS.items(), key=lambda x:x[1][0], reverse=True)
結果をテキストファイル'bracket.txt'として出力しています。
# 結果をテキストファイル'bracket.txt'に出力する
with open('bracket.txt', 'w') as fw:
最後に、決勝トーナメントに進出した16チームの優勝、準優勝、3位、ベスト4、ベスト8、初戦敗退の集計結果を表示しています。
# 優勝、準優勝、3位、ベスト4、ベスト8、初戦敗退の集計結果を表示
for k, v in sorted1:
print(f'{k}: 優勝 {str(v[WINNER]).rjust(3)}回({v[WINNER]/TOTAL*100:6.2f}%)、'
f'準優勝 {str(v[RUNNER_UP]).rjust(3)}回({v[RUNNER_UP]/TOTAL*100:6.2f}%)、'
f'3位 {str(v[THIRD_PLACE]).rjust(3)}回({v[THIRD_PLACE]/TOTAL*100:6.2f}%)'
f'ベスト4 {str(v[BEST_4]).rjust(3)}回({v[BEST_4]/TOTAL*100:6.2f}%)'
f'ベスト8 {str(v[BEST_8]).rjust(3)}回({v[BEST_8]/TOTAL*100:6.2f}%)'
f'初戦敗退 {str(v[BEST_16]).rjust(3)}回({v[BEST_16]/TOTAL*100:6.2f}%)')
fw.write(f'{k}: 優勝 {str(v[WINNER]).rjust(3)}回({v[WINNER]/TOTAL*100:6.2f}%)、'
f'準優勝 {str(v[RUNNER_UP]).rjust(3)}回({v[RUNNER_UP]/TOTAL*100:6.2f}%)、'
f'3位 {str(v[THIRD_PLACE]).rjust(3)}回({v[THIRD_PLACE]/TOTAL*100:6.2f}%)'
f'ベスト4 {str(v[BEST_4]).rjust(3)}回({v[BEST_4]/TOTAL*100:6.2f}%)'
f'ベスト8 {str(v[BEST_8]).rjust(3)}回({v[BEST_8]/TOTAL*100:6.2f}%)'
f'初戦敗退 {str(v[BEST_16]).rjust(3)}回({v[BEST_16]/TOTAL*100:6.2f}%)\n')
動作確認環境
• MacOS 13.0.1
• Python 3.9.6
スクリプトの実行結果
スクリプトの処理時間は、約90秒程度です。環境によって異なりますが、他所ごとをしていたら、アッと言う間です。実行結果は、下記の通りになりました。
モロッコ : 優勝 101543回( 10.15%)、準優勝 84309回( 8.43%)、3位 86883回( 8.69%)ベスト4 342907回( 34.29%)ベスト8 293628回( 29.36%)初戦敗退 363465回( 36.35%)
オランダ : 優勝 95150回( 9.52%)、準優勝 82074回( 8.21%)、3位 74749回( 7.47%)ベスト4 314510回( 31.45%)ベスト8 269615回( 26.96%)初戦敗退 415875回( 41.59%)
イングランド: 優勝 91347回( 9.13%)、準優勝 76120回( 7.61%)、3位 79246回( 7.92%)ベスト4 310659回( 31.07%)ベスト8 228174回( 22.82%)初戦敗退 461167回( 46.12%)
ブラジル : 優勝 77115回( 7.71%)、準優勝 78102回( 7.81%)、3位 79881回( 7.99%)ベスト4 312272回( 31.23%)ベスト8 286487回( 28.65%)初戦敗退 401241回( 40.12%)
フランス : 優勝 73715回( 7.37%)、準優勝 70534回( 7.05%)、3位 74254回( 7.43%)ベスト4 288029回( 28.80%)ベスト8 312595回( 31.26%)初戦敗退 399376回( 39.94%)
日本 : 優勝 73261回( 7.33%)、準優勝 73563回( 7.36%)、3位 75237回( 7.52%)ベスト4 295116回( 29.51%)ベスト8 250643回( 25.06%)初戦敗退 454241回( 45.42%)
スイス : 優勝 65677回( 6.57%)、準優勝 63440回( 6.34%)、3位 64913回( 6.49%)ベスト4 255668回( 25.57%)ベスト8 244193回( 24.42%)初戦敗退 500139回( 50.01%)
ポルトガル : 優勝 65465回( 6.55%)、準優勝 63345回( 6.33%)、3位 64973回( 6.50%)ベスト4 255720回( 25.57%)ベスト8 244419回( 24.44%)初戦敗退 499861回( 49.99%)
オーストラリア: 優勝 65019回( 6.50%)、準優勝 65484回( 6.55%)、3位 59606回( 5.96%)ベスト4 247894回( 24.79%)ベスト8 251883回( 25.19%)初戦敗退 500223回( 50.02%)
アルゼンチン: 優勝 65016回( 6.50%)、準優勝 65451回( 6.55%)、3位 59669回( 5.97%)ベスト4 248466回( 24.85%)ベスト8 251757回( 25.18%)初戦敗退 499777回( 49.98%)
セネガル : 優勝 63394回( 6.34%)、準優勝 61095回( 6.11%)、3位 64301回( 6.43%)ベスト4 248768回( 24.88%)ベスト8 212399回( 21.24%)初戦敗退 538833回( 53.88%)
クロアチア : 優勝 46075回( 4.61%)、準優勝 55700回( 5.57%)、3位 56328回( 5.63%)ベスト4 224079回( 22.41%)ベスト8 230162回( 23.02%)初戦敗退 545759回( 54.58%)
アメリカ合衆国: 優勝 41363回( 4.14%)、準優勝 49789回( 4.98%)、3位 45078回( 4.51%)ベスト4 189130回( 18.91%)ベスト8 226745回( 22.67%)初戦敗退 584125回( 58.41%)
韓国 : 優勝 26983回( 2.70%)、準優勝 39855回( 3.99%)、3位 41465回( 4.15%)ベスト4 168533回( 16.85%)ベスト8 232708回( 23.27%)初戦敗退 598759回( 59.88%)
ポーランド : 優勝 24832回( 2.48%)、準優勝 36199回( 3.62%)、3位 37689回( 3.77%)ベスト4 152544回( 15.25%)ベスト8 246832回( 24.68%)初戦敗退 600624回( 60.06%)
スペイン : 優勝 24045回( 2.40%)、準優勝 34940回( 3.49%)、3位 35728回( 3.57%)ベスト4 145705回( 14.57%)ベスト8 217760回( 21.78%)初戦敗退 636535回( 63.65%)
決勝トーナメントの擬似スクリプトを走らせた考察
グループリーグでの勝ち点をチームの戦力値としてスクリプトを走らせた結果、モロッコが優勝確率10.15%の1位となりました。モロッコが優勝確率1になった要因は、
- 今大会はグループリーグ3戦全勝のチームがいなかった為、2勝1引き分けで決勝トーナメントに進出した、オランダ、イングランド、モロッコの3チームが勝ち点7で、本スクリプトでの戦力値が1番高い。
- オランダの初戦の対戦相手はアメリカ合衆国で勝ち点5、イングランドの初戦の対戦相手はセネガルで勝ち点6に対し、モロッコの初戦の対戦相手はスペインで勝ち点4と他2チームより、初戦を突破する確率が1番高くなっている
ちなみにこのスクリプトでの日本がワールドカップで優勝する確率は6位で、同じ勝ち点6で並ぶ、ブラジル、フランスより低く、スイス、ポルトガルより高い結果となった。
グループリーグの勝ち点をチームの戦力値に置き換えるのは面白くない
グループリーグの勝ち点をチームの戦力値に置き換えるのは面白くないので、2022年10月6日時点のFIFAランキングでチームの戦力値を置き換えてみる。
# 2022年10月6日時点でのFIFAランキングを戦力値として登録
TEAMS = {netherlands: 8,
united_states: 16,
argentina: 3,
australia: 38,
japan: 24,
croatia: 12,
brazil: 1,
south_korea: 28,
england: 5,
senegal: 18,
france: 4,
poland: 26,
morocco: 22,
spain: 7,
portugal: 9,
switzerland: 15}
基準となるFIFAランキングとして、カタール=50位を採用する。
# カタールの2022年10月6日時点でのFIFAランキング
QATAR = 50
対戦関数をカスタマイズ。日本以外と対戦する場合は、カタールのFIFAランキングから、自国のランキングを引いた値を戦力値とする。
- ブラジルの戦力値 50-1=49
- オーストラリアの戦力値 50-38=12
日本は海外メディアから、ジャイアントキリングとかカムバックキングと言われているので、FIFAランキングの順位にカタールの順位50の数値の下駄を履かせた値を戦力値とする。
- ブラジルの戦力値 1+50=51
- 日本の戦力値 24+50=74
# 対戦関数
def match(team1, team2, round=None):
if japan not in [team1, team2]:
win = random.choices([team1, team2], weights=[QATAR - TEAMS[team1], QATAR - TEAMS[team2]])[0]
else:
win = random.choices([team1, team2], weights=[TEAMS[team1] + QATAR, TEAMS[team2] + QATAR])[0]
lose = team1 if win == team2 else team2
if round is not None:
RESULTS[lose][round] += 1
return win, lose
2022年10月6日時点でのFIFAランキングと日本用にカスタマイズしたスクリプトの実行結果
日本チームに都合の良いように、対戦関数をカスタマイズした結果、日本がワールドカップに優勝する確率が、9.39%で16チーム中4位となった。
アルゼンチン: 優勝 121607回( 12.16%)、準優勝 101528回( 10.15%)、3位 119956回( 12.00%)ベスト4 439175回( 43.92%)ベスト8 357164回( 35.72%)初戦敗退 203661回( 20.37%)
ブラジル : 優勝 101010回( 10.10%)、準優勝 80685回( 8.07%)、3位 84096回( 8.41%)ベスト4 330091回( 33.01%)ベスト8 358793回( 35.88%)初戦敗退 311116回( 31.11%)
フランス : 優勝 100194回( 10.02%)、準優勝 94924回( 9.49%)、3位 85119回( 8.51%)ベスト4 355841回( 35.58%)ベスト8 302093回( 30.21%)初戦敗退 342066回( 34.21%)
日本 : 優勝 93944回( 9.39%)、準優勝 76218回( 7.62%)、3位 73586回( 7.36%)ベスト4 304570回( 30.46%)ベスト8 239927回( 23.99%)初戦敗退 455503回( 45.55%)
イングランド: 優勝 88427回( 8.84%)、準優勝 85657回( 8.57%)、3位 76568回( 7.66%)ベスト4 320119回( 32.01%)ベスト8 264714回( 26.47%)初戦敗退 415167回( 41.52%)
スペイン : 優勝 83895回( 8.39%)、準優勝 83914回( 8.39%)、3位 79067回( 7.91%)ベスト4 321185回( 32.12%)ベスト8 284321回( 28.43%)初戦敗退 394494回( 39.45%)
オランダ : 優勝 75503回( 7.55%)、準優勝 70962回( 7.10%)、3位 78600回( 7.86%)ベスト4 295760回( 29.58%)ベスト8 257784回( 25.78%)初戦敗退 446456回( 44.65%)
ポルトガル : 優勝 72064回( 7.21%)、準優勝 74037回( 7.40%)、3位 70384回( 7.04%)ベスト4 285495回( 28.55%)ベスト8 253921回( 25.39%)初戦敗退 460584回( 46.06%)
クロアチア : 優勝 54612回( 5.46%)、準優勝 56310回( 5.63%)、3位 57649回( 5.76%)ベスト4 226043回( 22.60%)ベスト8 229460回( 22.95%)初戦敗退 544497回( 54.45%)
スイス : 優勝 50072回( 5.01%)、準優勝 57243回( 5.72%)、3位 56482回( 5.65%)ベスト4 226170回( 22.62%)ベスト8 234414回( 23.44%)初戦敗退 539416回( 53.94%)
アメリカ合衆国: 優勝 47174回( 4.72%)、準優勝 54374回( 5.44%)、3位 54523回( 5.45%)ベスト4 216437回( 21.64%)ベスト8 230019回( 23.00%)初戦敗退 553544回( 55.35%)
セネガル : 優勝 39593回( 3.96%)、準優勝 48980回( 4.90%)、3位 48341回( 4.83%)ベスト4 193117回( 19.31%)ベスト8 222050回( 22.20%)初戦敗退 584833回( 58.48%)
モロッコ : 優勝 29766回( 2.98%)、準優勝 40373回( 4.04%)、3位 42139回( 4.21%)ベスト4 167150回( 16.71%)ベスト8 227344回( 22.73%)初戦敗退 605506回( 60.55%)
ポーランド : 優勝 20208回( 2.02%)、準優勝 30653回( 3.07%)、3位 32356回( 3.24%)ベスト4 130923回( 13.09%)ベスト8 211143回( 21.11%)初戦敗退 657934回( 65.79%)
韓国 : 優勝 18124回( 1.81%)、準優勝 31659回( 3.17%)、3位 33252回( 3.33%)ベスト4 139296回( 13.93%)ベスト8 171820回( 17.18%)初戦敗退 688884回( 68.89%)
オーストラリア: 優勝 3807回( 0.38%)、準優勝 12483回( 1.25%)、3位 7882回( 0.79%)ベスト4 48628回( 4.86%)ベスト8 155033回( 15.50%)初戦敗退 796339回( 79.63%)
2022年10月6日時点でのFIFAランキングと日本用にカスタマイズした決勝トーナメントの擬似スクリプトを走らせた考察
概ねFIFAランキング通りの結果となった。FIFAランキング1位のブラジルが2位に甘んじている理由
- ブラジルが準々決勝で日本と対戦する確率が高い。
- フランスは決勝まで日本と対戦しない。
- 決勝まで日本と対戦しないチームの優勝確率が高くなっている。
最後に
元々、前回の2022 FIFAワールドカップ、日本が決勝トーナメントに進出できる確率(2022年11月27日時点)で、このシリーズは終了する予定だったが、日本がスペインに勝利し、決勝トーナメントに1位通過したことで、勢い余ってこのPythonスクリプトを作成して試してしまいました。
本日2022年12月3日から決勝トーナメントが始まります。負けは許されないノックアウトステージ。どのチームも健闘を讃えつつ、日本チームには初のベスト8に進出してもらいたいところです。
最後まで、この記事を読んでいただき、ありがとうございました。