u++の備忘録

PK戦の先行有利は新制度「ABBAルール」で是正されるかモンテカルロシミュレーションで検証してみた

先行有利のPK戦

 サッカーのトーナメント制の大会で同点となった場合など、勝敗をつけるために行われるPK戦。当然のように交互にボールを蹴り合っていた制度の変更が、欧州サッカー連盟によって現在議論されているそうです。

www.soccer-king.jp

その理由は、現在のPK戦は先行が有利であることにあります。イギリスの教育・研究機関ロンドン・スクール・オブ・エコノミクス(LSE)の研究によると、1970年から2000年にかけて行なわれた主要な大会のPK戦2,820件を分析した結果、最初に蹴ったチームの60%が勝利していると分かったそうです。

この結果について、研究を主導した教授のイグナシオ・パラシオス・ウエルタは「ポイントを先行されることからくる精神的なプレッシャーが、後に蹴るチームのパフォーマンスに明らかに影響をおよぼしている」と分析しています。定量化はしづらいですが、定性的には納得の行く話です。

新制度「ABBAルール」とは?

新制度「ABBAルール」では、一回蹴るごとに先攻と後攻が入れ替わります。AとBが戦う場合、以下のような順番でボールを蹴っていくことになります。

A→B→B→A→A→B→B→A→A→B

この最初の四つを取って「ABBAルール」と呼ばれているようです。

この制度は現在クロアチアで行われているU-17欧州選手権チェコで行われているU-17女子欧州選手権で試行されています。欧州サッカー連盟によると、今後も試行試験が続けられ、その結果次第で世界的に導入される可能性があるとのことです。

ABBAルール」の効果は?

今回はこの「ABBAルール」が「PK戦の先行有利」の是正に繋がるのか、シミュレータの作成を通じて議論してみたいと思います。具体的には、以下の作業を行いました。

  1. 現在のPK戦を再現するシミュレータの作成
  2. ↑のシミュレータにおいてボールを蹴る順番のみを変更し、先攻の勝率の変化を調査

以下では、それぞれの作業について説明します。

現在のPK戦を再現するシミュレータの作成

最初に、現在のPK戦を再現するシミュレータを作成しました。

# -*- coding: utf-8 -*-
import random
random.seed(1)
scores_0 = []
scores_1 = []
kicker_count = 0
winners = []
r = 0.1 #リードされている時の成功率の下がり幅
kicker = 0
rest_kick_0 = 5
rest_kick_1 = 5

def shoot():
    if (kicker == 0 and sum(scores_0) < sum(scores_1)) \
        or (kicker == 1 and sum(scores_1) < sum(scores_0)):
        goal_prob = 0.81 - r
    else:
        goal_prob = 0.81
    if goal_prob > random.random():
        if kicker == 0:
            scores_0.append(1)
        else:
            scores_1.append(1)
    else:
        if kicker == 0:
            scores_0.append(0)
        else:
            scores_1.append(0)

def isSettlement():
    if kicker_count <= 9:
        if sum(scores_0) + rest_kick_0 < sum(scores_1) \
            or sum(scores_1) + rest_kick_1 < sum(scores_0):
                return 1
    else:
        if kicker_count % 2 == 1:
            if scores_0[int((kicker_count - 1) / 2)] - scores_1[int((kicker_count - 1) / 2)] != 0:
                return 1
    return 0

for j in range(100000):
    for i in range(1000):
        shoot()
        if kicker_count <= 9:
            if kicker == 0:
                rest_kick_0 -= 1
            else:
                rest_kick_1 -= 1

        if isSettlement():
            break
        
        # キックチーム交代
        kicker = 1 - kicker

        kicker_count += 1

    if sum(scores_0) < sum(scores_1):
        winners.append(1)
    else:
        winners.append(0)
    scores_0 = []
    scores_1 = []
    kicker_count = 0
    kicker = 0
    rest_kick_0 = 5
    rest_kick_1 = 5

print("先攻の勝率:" + str(1 - sum(winners)/len(winners)))

全員が均一な人間として非常に多くの回数(ここでは10万回)PK戦を実施した時に、先攻が何回勝つかを調べるプログラムです。

ここでハイパーパラメータとして、以下の二つを設定する必要があります。

  • 通常時のPKの成功率
  • リードされている時のPKの成功率

前者については、PK戦でない時のPK(つまりは試合中のPK)の成功率を採用することにしました。FIFA国際サッカー連盟)によれば、2006年ドイツ大会までのワールドカップ18大会では190回のPKが与えられ、得点できたのは154回。成功率は約0.81となります。

後者については、直接定義するのが難しいと感じたので「先攻の勝率が60%」という結果から推定することにしました。つまりは「リードされている時の成功率の下がり幅」をrという変数で表現し、この変数を変化させていく中で、最も「先攻の勝率が60%」に近づく時を調べました。

調べた結果を以下の図に示します。横軸はrの値、縦軸は先攻の勝率です。

f:id:upura:20170506201627p:plain

この図から読み取れるように、今回はr=0.1として話を進めることにしました。つまり「リードされている時のPKの成功率」は0.81-0.1=0.71と定義しました。この時、先攻の勝率は0.60668です。

ボールを蹴る順番の変更

さて、ここでようやく本題に移ります。先のプログラムでは交互にボールを蹴っていましたが、次のプログラムでは「ABABルール」を適用し、蹴る順番を変更します。この時に先攻の勝率がどうなるか(さらに言えば現状の60%より低くなるのか)が鍵となります。

プログラムの変更箇所は、以下の「キックチーム交代」の部分のみです。

        # キックチーム交代
        if kicker_count % 2 == 0:
            kicker = 1 - kicker

出力は、以下の通りでした。

先攻の勝率:0.51562

「ABABルール」でも先攻有利の状況は変わりませんが、現状に比べると大幅に不公平感は緩和されるようです。