初めに
2022 FIFA WC予選もあと2試合を残す飲みですが、今回、Optunaを用いて、日本のWC予選突破条件を探索してみます。
今後の試合予定
参照:2022 FIFAワールドカップ、日本がワールドカップに出場できる確率(2022年2月2日時点)
2022年3月24日 第一試合、オーストラリア 対 日本
2022年3月24日 第二試合、中国 対 サウジアラビア
2022年3月24日 第三試合、ベトナム 対 オマーン
2022年3月29日 第一試合、日本 対 ベトナム
2022年3月29日 第二試合、サウジアラビア 対 オーストラリア
2022年3月29日 第三試合、オマーン 対 中国
#Optunaとは
Optunaは自動ハイパーパラメータ最適化ソフトウェアフレームワークです。使い方はマニュアルを参照してください。
https://optuna.readthedocs.io/en/stable/index.html
import optuna
各試合での勝ち点からの検索
日本が勝ち点で3位になるケース(アジアプレーオフに回る場合)について検索します。
def objective1(trial):
# point for home team
m1 = trial.suggest_categorical('m1', [0,1,3]) # 2022年3月24日 第一試合、オーストラリア 対 日本
m2 = trial.suggest_categorical('m2', [0,1,3]) # 2022年3月24日 第二試合、中国 対 サウジアラビア
m3 = trial.suggest_categorical('m3', [0,1,3]) # 2022年3月24日 第三試合、ベトナム 対 オマーン
m4 = trial.suggest_categorical('m4', [0,1,3]) # 2022年3月29日 第一試合、日本 対 ベトナム
m5 = trial.suggest_categorical('m5', [0,1,3]) # 2022年3月29日 第二試合、サウジアラビア 対 オーストラリア
m6 = trial.suggest_categorical('m6', [0,1,3]) # 2022年3月29日 第三試合、オマーン 対 中国
mpg={0:3,1:1,3:0} # point for away team
# Total Victory Point
jp=18+mpg[m1]+m4
sa=19+mpg[m2]+m5
au=15+m1+mpg[m5]
om=8+mpg[m3]+m6
cn=5+m2+mpg[m6]
vn=3+m3+mpg[m4]
MV=[m1,m2,m3,m4,m5,m6]
VP=[sa,jp,au,om,cn,vn]
VPs=sorted(VP)[::-1]
jp_rank=VPs.index(jp)+1 # 勝ち点での日本の順位
#検索条件設定、条件に適合する場合にプリント
if jp_rank==3: # 日本が勝ち点で3位になるケース
print(VP,MV)
return jp_rank
# 検索目的に応じて、maximize、 minimize、設定なし、を使い分けます。
study1 = optuna.create_study(direction=None)
study1.optimize(objective1, n_trials=100)
探索の過程で、日本が勝ち点で3位になるケースがあれば、プリントします。
# 日本2敗で、サウジがオーストラリアと引き分ける場合、1位サウジ、2位オーストラリア、3位日本
[23, 18, 19, 9, 6, 9] [3, 0, 3, 0, 1, 1]
[20, 18, 19, 12, 8, 7] [3, 3, 1, 0, 1, 3]
# 日本2敗で、サウジがオーストラリアに負け、中国と引き分ける場合、1位オーストラリア、2位サウジ、3位日本
[20, 18, 21, 8, 9, 9] [3, 1, 3, 0, 0, 0]
# 日本2敗で、サウジがオーストラリアに負け、中国にも負ける場合、1位オーストラリア、2位サウジ、3位日本
[19, 18, 21, 11, 8, 9] [3, 3, 3, 0, 0, 3]
各試合での得点を考慮した検索
ここでは、日本が、オーストラリアまたはサウジと勝ち点で2位で並ぶ条件について検索します。各チームの得点範囲は0から4の範囲に設定しています。設定は試合毎に自由に変更出来ます。
def objective2(trial):
# goals in each game
m1_au = trial.suggest_int('m1_au', 0, 4) # 2022年3月24日 第一試合、オーストラリア 対 日本
m1_jp = trial.suggest_int('m1_jp', 0, 4) # 2022年3月24日 第一試合、オーストラリア 対 日本
m2_cn = trial.suggest_int('m2_cn', 0, 4) # 2022年3月24日 第二試合、中国 対 サウジアラビア
m2_sa = trial.suggest_int('m2_sa', 0, 4) # 2022年3月24日 第二試合、中国 対 サウジアラビア
m3_vn = trial.suggest_int('m3_vn', 0, 4) # 2022年3月24日 第三試合、ベトナム 対 オマーン
m3_om = trial.suggest_int('m3_om', 0, 4) # 2022年3月24日 第三試合、ベトナム 対 オマーン
m4_jp = trial.suggest_int('m4_jp', 0, 4) # 2022年3月29日 第一試合、日本 対 ベトナム
m4_vn = trial.suggest_int('m4_vn', 0, 4) # 2022年3月29日 第一試合、日本 対 ベトナム
m5_sa = trial.suggest_int('m5_sa', 0, 4) # 2022年3月29日 第二試合、サウジアラビア 対 オーストラリア
m5_au = trial.suggest_int('m5_au', 0, 4) # 2022年3月29日 第二試合、サウジアラビア 対 オーストラリア
m6_om = trial.suggest_int('m6_om', 0, 4) # 2022年3月29日 第三試合、オマーン 対 中国
m6_cn = trial.suggest_int('m6_cn', 0, 4) # 2022年3月29日 第三試合、オマーン 対 中国
def home_away_goal(x,y):
if x==y:
home_vp=1
away_vp=1
elif x>y:
home_vp=3
away_vp=0
elif x<y:
home_vp=0
away_vp=3
home_df=x-y
away_df=y-x
home_tp=x
away_tp=y
return home_vp,away_vp,home_df,away_df,home_tp,away_tp
m1_home_vp,m1_away_vp,m1_home_df,m1_away_df,m1_home_tp,m1_away_tp=home_away_goal(m1_au,m1_jp)
m2_home_vp,m2_away_vp,m2_home_df,m2_away_df,m2_home_tp,m2_away_tp=home_away_goal(m2_cn,m2_sa)
m3_home_vp,m3_away_vp,m3_home_df,m3_away_df,m3_home_tp,m3_away_tp=home_away_goal(m3_vn,m3_om)
m4_home_vp,m4_away_vp,m4_home_df,m4_away_df,m4_home_tp,m4_away_tp=home_away_goal(m4_jp,m4_vn)
m5_home_vp,m5_away_vp,m5_home_df,m5_away_df,m5_home_tp,m5_away_tp=home_away_goal(m5_sa,m5_au)
m6_home_vp,m6_away_vp,m6_home_df,m6_away_df,m6_home_tp,m6_away_tp=home_away_goal(m6_om,m6_cn)
vp_sa=19+m2_away_vp+m5_home_vp
vp_jp=18+m1_away_vp+m4_home_vp
vp_au=15+m1_home_vp+m5_away_vp
vp_om=8+m3_away_vp+m6_home_vp
vp_cn=5+m2_home_vp+m6_away_vp
vp_vn=3+m3_home_vp+m4_away_vp
df_sa=5+m2_away_df+m5_home_df
df_jp=6+m1_away_df+m4_home_df
df_au=9+m1_home_df+m5_away_df
df_om=-2+m3_away_df+m6_home_df
df_cn=-8+m2_home_df+m6_away_df
df_vn=-10+m3_home_df+m4_away_df
tp_sa=10+m2_away_tp+m5_home_tp
tp_jp=9+m1_away_tp+m4_home_tp
tp_au=15+m1_home_tp+m5_away_tp
tp_om=8+m3_away_tp+m6_home_tp
tp_cn=8+m2_home_tp+m6_away_tp
tp_vn=7+m3_home_tp+m4_away_tp
VP=[vp_sa,vp_jp,vp_au,vp_om,vp_cn,vp_vn]
DF=[df_sa,df_jp,df_au,df_om,df_cn,df_vn]
TP=[tp_sa,tp_jp,tp_au,tp_om,tp_cn,tp_vn]
GL=[m1_au,m1_jp,m2_cn,m2_sa,m3_vn,m3_om,m4_jp,m4_vn,m5_sa,m5_au,m6_om,m6_cn]
VPs=sorted(VP)[::-1]
jp_vp_rank=VPs.index(vp_jp)+1 # 勝ち点での日本の順位
au_vp_rank=VPs.index(vp_au)+1 # 勝ち点でのオーストラリアの順位
sa_vp_rank=VPs.index(vp_sa)+1 # 勝ち点でのサウジの順位
DFs=sorted(DF)[::-1]
jp_df_rank=DFs.index(df_jp)+1 # 得失点差での日本の順位
au_df_rank=DFs.index(df_au)+1 # 得失点差でのオーストラリアの順位
sa_df_rank=DFs.index(df_sa)+1 # 得失点差でのサウジの順位
TPs=sorted(TP)[::-1]
jp_tp_rank=TPs.index(tp_jp)+1 # 得点での日本の順位
au_tp_rank=TPs.index(tp_au)+1 # 得点でのオーストラリアの順位
sa_tp_rank=TPs.index(tp_sa)+1 # 得点でのサウジの順位
#日本が、オーストラリアまたはサウジと勝ち点で並ぶ場合はprintする
if jp_vp_rank==sa_vp_rank==2 or jp_vp_rank==au_vp_rank==2 :
print(VP,DF,TP,GL)
return jp_df_rank
# 検索目的に応じて、maximize、 minimize、None、を使い分ける
study2 = optuna.create_study(direction='minimize')
study2.optimize(objective2, n_trials=100)
このプログラムでは日本の得失点差のランキングが上位になるように探索して行きます。その過程で、条件に合った結果がプリントされます。勝ち点が同じ場合でも、得失点差、総得点の結果から、総合順位が決定します。
# 日本が、オーストラリアまたはサウジと勝ち点で並ぶ場合
# 勝ち点2位でオーストラリアと並ぶ場合
[22, 21, 21, 8, 8, 6] [6, 6, 13, -6, -9, -10] [15, 13, 21, 11, 13, 11] [3, 1, 1, 4, 3, 1, 3, 1, 1, 3, 2, 4]
# 2022年3月24日 第一試合、オーストラリア 対 日本 = 3:1
# 2022年3月24日 第二試合、中国 対 サウジアラビア = 1:4
# 2022年3月24日 第三試合、ベトナム 対 オマーン = 3:1
# 2022年3月29日 第一試合、日本 対 ベトナム = 3:1
# 2022年3月29日 第二試合、サウジアラビア 対 オーストラリア = 1:3
# 2022年3月29日 第三試合、オマーン 対 中国 = 2:4
その他
[20, 19, 19, 11, 11, 4] [2, 5, 10, -2, -4, -11] [15, 12, 23, 10, 13, 8] [4, 3, 4, 1, 1, 2, 0, 0, 4, 4, 0, 1]
[23, 19, 19, 9, 8, 5] [8, 5, 10, -3, -10, -10] [15, 14, 20, 13, 13, 11] [4, 3, 1, 4, 2, 2, 2, 2, 1, 1, 3, 4]
[25, 18, 18, 8, 8, 9] [9, 3, 9, -6, -7, -8] [17, 11, 19, 11, 14, 12] [3, 1, 2, 4, 3, 2, 1, 2, 3, 1, 1, 4]
いずれも得失点差でオーストラリアに負け、総合3位確定
#勝ち点2位でサウジと並ぶ場合
[19, 19, 21, 14, 8, 4] [0, 4, 12, 2, -7, -11] [11, 9, 19, 13, 12, 8] [2, 0, 4, 0, 1, 2, 0, 0, 1, 2, 3, 0]
得失点差でサウジに勝ち、総合2位確定
全てのケースを網羅しているわけではないので、一度の実行で、条件に合致するケースが見つからない場合もあり得ます。
終わりに
よりマニアックな設定を考えてみて、動かしてみると楽しいと思います。Optunaの使い方に慣れる意味でも、いい題材かと思います。Optunaは、高速に条件に合うケースを見つけてくれますので、モデルのパラメータtuningだけでなく、工夫次第で色々な場面で使えそうな気がします。
参考
2022 FIFAワールドカップ、日本がワールドカップに出場できる確率(2022年2月2日時点)
【Optuna】ハイパーパラメータの自動最適化ライブラリの使い方例