Intro

영국 프리미어리그 중계를 보다보면 위처럼 실시간 승부 예측 확률이 자주 화면에 띄워지곤 합니다. 이 값을 보면서 지고 있는 팀을 응원하는 팬들은 우리팀이 얼마나 어려움을 겪고 있는지 확인 할 수 있고, 이 낮은 확률을 뚫고 승리를 거머쥐었을 때는 극적인 감정을 배로 만들어줍니다. 저도 친구들과 함께 축구를 볼 때면 자주 이 확률 값을 가지고 이야기나누죠. “포기하지마, 아직 이길 확률이 5%나 있잖아😛” 이 값은 축구 보는 재미를 한층 더해주는 재미있는 요소 중 하나입니다.

뿐만 아니라 경기 중 베팅 상품이 있는 해외 베팅 업체들의 경우, 배당률 산정 및 이용자들의 배팅 전략 등에 이러한 확률이 아주 활용되고 있죠. 하지만 우리나라 프로리그인 K리그 경우에는 아직 실시간 승부예측 확률을 중계 중에 활용하고 있지 않고, 경기 중 베팅 상품을 운영하고 있지도 않고 있습니다. 스포츠를 좋아하는 사람으로서 이런 사용 사례들을 벤치마킹해서 스포츠 산업을 키운다면 참 좋을 텐데 말이죠.

그래서,

  1. 실시간 승부 예측 모형이 어떻게 설계되고 학습됐는지 궁금하다.
  2. K리그 의 실시간 승부예측 모형을 만들어 보면 재밌겠다.

라는 아이디어를 바탕으로 K리그 실시간 승리 확률 모형을 만들어 보았습니다.

축구경기 승부예측 모형

축구경기 승부예측 모형은 크게 두 가지 용도로 활용됩니다.

  • 첫 번째는 축구 팬들에게 경기를 재미를 보는 재미를 높여주고,
  • 두 번째는 베팅 사이트의 배당률을 선정하는 모형으로 활용됩니다.

축구 경기 관람을 즐기는 팬들이 점점 늘어나고, 베팅 산업이 성장하면서 승부예측 모형의 활용가치도 덩달아 커져 가고 있습니다. 특히 야구에서는 경기 내용 분석이나, WPA(승리확률기여도)와 같은 지표를 만들어 내는 데 실시간 승부예측 모형이 널리 활용되고 있습니다. 승리확률기여도는 해당선수의 플레이가 경기 결과에 미친 긍정적, 부정적 영향력을 누적하여 선수의 가치를 나타내는 지표로 야구를 좋아하는 사람에게는 아주 친숙한 지표이죠.

승부예측 모형 연구

축구 경기 승부예측 모형은 1960년대 부터 시작되었다고 합니다. 최근에는 AI의 시대라고 해도 과언이 아닐 만큼 워낙 다양한 ML/AI 알고리즘이 개발되고 있고, 따라서 이를 활용한 많은 승부예측 모형들이 제시되고 있습니다. 축구경기 승부 예측 모형은 어떤 모델링 기법을 활용하는 가에 따라서 크게 두 종류로 나눌 수 있습니다.

1. Machine Learning 기반 (승, 무, 패) 분류 모델

다양한 머신러닝 모형을 활용해 경기 결과(승, 무, 패)를 직접 분류(Classificiation) 하는 문제를 푸는 방법입니다. 활용 가능한 머신러닝 방법론이 매우 많기 때문에 다음과 같은 장점들이 있습니다.

  • 다양한 ML/DL 기법 활용 가능
  • 예측 정확도 향상을 타겟으로 모델 설계
  • 변수(Feature) 활용에 제약이 적음

2. 포아송 확률 모형

축구경기에서 발생하는 골이 포아송 분포라고 가정하고 포아송 분포의 파라미터를 설계하고 추정하는 방식입니다. 골 분포를 추정하기 때문에 다음과 같은 장점이 있습니다.

  • 확률 분포로부터 샘플링을 통한 경기 시뮬레이션 가능
  • 변수들과 결과의 상관관계를 설명하는 데에 유리
  • Ordinal 한 승 무 패 결과를 보장

Modeling

승, 무, 패 결과를 잘 맞추는 모델 보다 예측결과가 연속적이며 설명력이 있는 모델이 적합하다 생각하여 포아송 확률 모형으로 K리그 실시간 승부 예측 모형을 설계했습니다. 자료조사 중 KU Leuven 연구팀의 P.Robberechts 가 포아송 확률 모형을 활용한 실시간 승부 예측 모형 연구를 찾게 되었고, 해당 논문 기반으로 모델링을 진행하게 되었습니다.

Dataset

1. K리그 데이터 포털

k리그 데이터 포털에서 경기 중 실시간 이벤트 데이터를 제공하고 있습니다. 실시간으로 제공하는 이벤트 종류는 득점, 경고, 퇴장, 슛, 오프사이드, 파울, 코너킥 7가지가 있습니다.

2. Statsbomb opendata

축구 통계 분석 회사 statsbomb 에서는 여러 유럽 축구 리그, 월드컵 등의 경기 이벤트 데이터를 제공하고 있습니다. K리그 데이터가 충분하지 않은 상황에서 Statsbomb 데이터를 활용하였습니다.

3. Whoscored.com

팀의 실력을 나타내는 elo rating 값을 계산하기 위해서 시즌 별 각 팀의 경기 결과 데이터를 축구 통계사이트 Whoscored.com 를 참고 하였습니다.

Features

K리그 축구경기의 골 모델의 파라미터 설계에 활용될 변수를 다음과 같은 항목으로 구성하였습니다. K리그 포털 이벤트 데이터로부터 얻을 수 있는 정보가 제한적이라 많은 변수를 활용할 수 가 없어서 아쉬웠습니다.

  • 현재 시점
  • 골 차이
  • elo rating 차이
  • (누적) 득점
  • (누적) 퇴장
  • (누적) 경고

*elo rating 은 팀의 실력을 나타내는 지표로 각 팀들의 전 시즌 성적 + 해당 시즌 경기 결과로 계산하였습니다. 자세한 데이터 전처리, 모델링 코드는 여기에 정리해 두었습니다.

elo rating 은 다음과 같이 구해집니다.

CODE
def elo(h_elo, a_elo, result):
    dr = h_elo - a_elo

    if result > 0:
        h_result = 1
        a_result = 0
    elif result == 0:
        h_result = 0.5
        a_result = 0.5
    else :
        h_result = 0
        a_result = 1

    h_we = 1/(10**(-dr/400)+1)
    a_we = 1/(10**(dr/400)+1)

    # K value for league match is 20

    h_e = h_elo + 20*(h_result - h_we)
    a_e = a_elo + 20*(a_result - a_we)

    return int(h_e), int(a_e)


Bayesian Poisson Model

다음과 같이 홈, 어웨이 팀의 골을 포아송 모형으로 설계합니다. 이 모형은 21년도 KDD에서 발표되었던 KU Leuven 연구팀의 모형에 착안하여 설계하였습니다. 특정 시점 $t$에서 경기 결과 시점의 각 팀의 골은 현재 시점의 골에 남은 시간에 발생할 골의 수의 합으로 나타낼 수 있습니다.

\[Goal_{home, end} \sim \mathrm{Pois}((T-t)* \theta_{home, t}) + Goal_{home, t}\] \[Goal_{away, end} \sim \mathrm{Pois}((T-t)* \theta_{away, t}) + Goal_{away, t}\]

각각의 포아송 분포 파라미터 $\theta$ 는 아래와 같이 설계합니다. 특정 시점 $t$에서 경기 상황 변수 Feature 들($x_t$)에다 가중치를 곱하고, 홈 팀에겐 $Ha$ 상수를 추가하여 홈 어드벤티지가 있도록 하였습니다.

\[\theta_{home,t} = \exp(\vec{w_t}*x_t+w_0+\mathrm{Ha})\] \[\theta_{away,t} = \exp(\vec{w_t}*x_t+w_0)\]

각 파라미터들의 prior distribution 과 시간에 따른 $\vec{w_t}$ 는 다음과 같은 관계 및 초기 분포 값으로 설정하였습니다. 각각의 시점 $t$ 마다 가중치가 다르게 학습되면서도, 연속성을 띄도록 설계된 것입니다.

\[w_t \sim \mathrm{N}(0, 2), w_{t+1} \sim \mathrm{N}(w_t, 2), \mathrm{Ha} \sim \mathrm{N}(0, 2),\]
CODE
import arviz as az
import pandas as pd
import numpy as np
import pymc as  pm
import pytensor.tensor as pt

bayesian_poisson_model = pm.Model()

with bayesian_poisson_model:
    
    alpha = []
    alpha.append(pm.Normal("alpha_1", mu=0, sigma=2, shape=9))
    beta = pm.Normal("beta", sigma = 2)
    hw = pm.HalfNormal("home_ad", sigma=2)

    for i in np.arange(2, 20):
        alpha.append(pm.Normal("alpha_{}".format(i), mu=alpha[-1], sigma=2))

    home_theta = []
    away_theta = []
    for i in np.arange(1, 20):
        home_theta.append((1-(i/20)) * pt.exp(pt.dot(home_X[i-1,:,:], alpha[i-1]) + beta + hw))
        away_theta.append((1-(i/20)) * pt.exp(pt.dot(away_X[i-1,:,:], alpha[i-1]) + beta))
    
    Y_h_ob = []
    for i in np.arange(1, 20):
        Y_h_ob.append(pm.Poisson("Y_h_obs_{}".format(i), home_theta[i-1], observed=home_y[i-1,:]))
        Y_h_ob.append(pm.Poisson("Y_a_obs_{}".format(i), away_theta[i-1], observed=away_y[i-1,:]))



Model 구조

Estimation

K리그 이벤트 수집의 한계로 모델 파라미터의 추론은 이벤트 데이터가 풍부한 Statsbomb 데이터를 활용했습니다. K리그 데이터도 유럽리그처럼 축구 분석 연구를 위한 데이터 셋이 있었으면 참 좋겠지만, 어쩔 수 없었습니다. 서로 다른 리그간의 수준차이나 플레이 성향차이, 수집과정에서의 이벤트 수집 기준 등에 의한 모델의 성능저하는 감수 할 수 밖에 없을 것 같습니다.

모형의 파라미터들은 MCMC Sampling 기법으로 추정하였습니다. MCMC(Markov Chain Monte Carlo) 추정하기 어려운 분포를 Sampling 을 통해 찾아가는 방법입니다. Python 환경에서의 MCMC Sampling 에 활용되는 ‘PYMC’ Package 를 활용했습니다.

승리 예측

모형의 파라미터를 예측하면, 특정 시점에서 경기 종료시까지의 넣을 골 수를 나타내는 확률값을 얻어낼 수 있습니다. 두 포아송 분포에서 충분한 샘플링을 통해 시뮬레이션을 하고, 그 결과들을 활용해서 승, 무, 패 비율을 예측할 수 있습니다. 예를 들어 대한민국과 일본의 경기에서 1:0 으로 전반이 종료되었고, 추정된 확률 모델과 전반전 경기 데이터를 통해 얻어낸 한국과 일본이 후반전 동안 골을 넣을 포아송 분포의 파라미터를 각각 $\theta_{Kor,45min} = 1.5$ , $\theta_{Jap,45min} = 1.2$ 라고 해봅시다. 이 상황에서 전반 종료 시점에 경기 결과를 추정된 포아송 분포로부터 샘플링을 통해 시뮬레이션을 할 수 있습니다. 한국의 골분포에서 샘플링을 한 후 1을 더한 값을 일본의 골분포에서 샘플링 한 값과 비교하면 그 것이 하나의 게임 샘플링이 되는 것입니다. 이러한 방식으로 경기결과를 예측헸을 때, 한국의 승 무 패 확률은 다음과 같이 산출됩니다. [75%, 16%, 9%]

실시간 승리확률 예측 예시

다음은 2024년 0월 0일에 있었던 K 리그 4라운드 전북 vs 울산의 경기를 실제 발생한 이벤트 기반으로 실시간 승리 확률을 예측한 결과입니다.

각 팀이 골을 넣을 때마다. 승 무 패 확률이 크게 변합니다. 경기 흐름도 물론 중요하지만, 결국 승리 확률에 결정적인 요소는 골일 수 밖에 없죠. 시간이 끝나 갈 수록 두 팀의 경기 결과가 무승부로 점점 수렴해가는 것도 잘 나타나 있습니다.

Outro

PL 중계에서 활용 되고 있는 실시간 승, 무, 패 확률 모형을 K league 경기에 활용해 보았습니다. 각 리그의 수준과 데이터를 수집한 주체가 분명 다르기에 모델링 적인 측면에서 아쉬운 점이 많습니다. K league 에서도 적극적으로 데이터를 오픈소스로 개방하여 여러 축구 분석 커뮤니티가 더 활발해졌으면 좋겠습니다. 😄

Reference

P.Robberechts : A Bayesian Approach to In-Game Win probability in soccer
Statsbomb Opendata
elo-ratings
Pymc