xG 모델과 선수 트래킹 데이터로 경기력 맥락 평가하기

Expected Goals(xG) 모델에 선수 트래킹 데이터를 결합해 슈팅 맥락을 평가하는 데이터 파이프라인, 모델링, 보정과 운영 기준을 정리한다.

2026-08-14 · 최초 발행 2024-04-29

슈팅 확률에 경기 맥락을 더하는 방식

Expected Goals(xG)는 특정 슈팅이 득점으로 이어질 확률을 사전에 추정한 값이며, 보통 0~1 범위의 확률로 표현한다. 슈팅 위치와 각도, 오픈플레이·세트피스·패널티 같은 상황, 슈팅 부위, 압박 정도가 주요 입력이 된다.

이벤트 데이터만으로 구성한 xG는 슈팅 시점의 정태적 특징에 집중한다. 반면 Player Tracking Data를 결합하면 슈팅 직전의 수비 압박, 공간 지배, 골키퍼 위치처럼 시간에 따라 바뀌는 조건까지 반영할 수 있다. 이런 보강 모델은 일반적으로 예측력과 캘리브레이션을 개선하는 방향으로 쓰인다.

트래킹 데이터는 경기 중 모든 선수와 공의 위치·속도를 시간축으로 기록한 시공간 데이터다. 광학 추적은 예를 들어 25 Hz로, 웨어러블 GNSS/IMU는 예를 들어 10~18 Hz로 수집될 수 있으며, 이벤트 데이터와의 시간 동기화가 전제된다.

이벤트와 좌표 스트림을 맞추는 과정

이벤트 피드는 슈팅·패스·파울의 시점을 앵커로 제공하고, 트래킹 스트림은 그 시점 주변의 시공간 맥락을 제공한다. 두 입력을 결합할 때는 이벤트 타임스탬프를 기준으로 ±20~40ms 윈도우에서 매칭한다.

드롭아웃은 칼만 필터나 스플라인 보간으로 보정할 수 있다. 동기화가 실패한 샘플은 제외하는 규칙을 별도로 두어야 한다. 이후 좌표를 정규화하고, 피치의 좌우 반전을 공격 방향 기준으로 통일한다.

슈팅 품질을 설명하는 특징은 다음처럼 구성된다.

  • 골대 중심까지의 거리, 슈팅 각도, 약발 또는 체스트 컨트롤 여부
  • 베로나이·모션 모델 기반 점유 확률, 슈팅 경로 차단율 등 피치 컨트롤과 공간 지배력
  • 슈팅 전 1.5~3.0초 동안의 속도·가속도·방향
  • 상대 수비수 최근접 거리와 압박 속도
  • 골키퍼 위치 편차, 수적 우위·열세 지표

오픈플레이, 세트피스, 패널티, 헤더는 상황별 서브모델로 분리할 수 있다. 같은 슈팅이라도 발생 맥락이 다르기 때문이다.

모델 선택은 해석성과 시퀀스 표현력의 균형이다

로지스틱 회귀는 L2 정규화와 클래스 불균형 가중치를 적용한 베이스라인으로 쓸 수 있다. 해석과 운영은 간단하지만 비선형 관계나 변수 간 상호작용을 표현하는 데 제약이 있다.

XGBoost와 CatBoost 같은 그래디언트 부스팅은 트리 기반 상호작용을 포착하고 결측 처리에도 강건하다. 중요도와 SHAP를 통해 해석력을 확보할 수 있으며 온라인 서빙에도 적합하다.

1D-TCN, LSTM, Transformer 기반 시공간 딥러닝은 슈팅 전 시퀀스를 모델링해 동적 압박과 라인 브레이킹을 포착한다. 다만 연산량이 늘어나고 확률 캘리브레이션의 필요성이 커진다.

모델 유형 성능(예측/캘리브레이션) 확장성 일관성(재현/누수 통제) 안정성(결측·노이즈) 운영 편의
로지스틱 회귀 중, 캘리브레이션 용이 매우 높음 높음 매우 높음
그래디언트 부스팅(XGBoost/CatBoost) 높음, 보정 필요 중 높음 높음 높음 높음
시공간 딥러닝(TCN/LSTM/Transformer) 매우 높음, 보정 중요 중~높음(ML Ops 성숙도 의존)

확률 자체를 검증하는 기준

모델이 높은 점수를 맞히는 것만으로는 충분하지 않다. Platt scaling(로지스틱)과 Isotonic regression으로 확률을 보정하며, 클래스 불균형 환경에서도 활용할 수 있다.

오프라인에서는 Log Loss, Brier Score, AUC-PR, ECE(Expected Calibration Error), 신뢰도 다이어그램을 함께 본다. 검증은 시간 기반 분할(Time-based split)로 수행하고, 팀·리그 단위 누수를 막기 위해 Grouped CV를 적용한다. 온라인에서는 추론 지연을 측정하고 실사용군 대조 A/B 테스트로 검증한다.

경미 결측심각 불일치입력: 이벤트 피드, 트래킹스트림시간 동기화: 이벤트 앵커±40ms 매칭결측/불일치 검출보간/칼만 필터샘플 제외 로그특징 엔지니어링:공간/동적/피치컨트롤모델 추론: GBM/Transformer캘리브레이션: Platt/Isotonic출력: xG 확률, 설명지표(SHAP)서빙/모니터링:지연·드리프트/ECE

전술과 스카우팅에서 읽어낼 수 있는 신호

경기 전략에서는 라인 간 거리를 줄였을 때 상대 슈팅 xG가 얼마나 낮아지는지 정량화할 수 있다. 프레싱 트리거 구간에서 상대 xG/분의 변화를 추적하면 전술 조정의 근거도 생긴다.

리크루팅과 스카우팅에서는 선수별 슈팅 품질(xG/슈팅)과 과대·과소 득점(xG vs G)을 분해한다. 압박 아래에서 슈팅 품질을 유지하는 능력, 골키퍼 위치를 이용하는 능력처럼 맥락형 지표도 평가 대상이 된다.

실시간 중계에는 슈팅 xG와 시퀀스 누적 xG를 표시하고 하이라이트 자동 추천에 활용할 수 있다. 프런트 오피스는 팀 단위 누적 xG 차이로 성적 리그레션을 예측하고, 계약과 임금 책정의 근거를 확보한다.

트래킹 데이터를 보강하면 이벤트 단독 모델과 비교해 Log Loss가 1020%, Brier Score가 512% 개선될 수 있다(리그·데이터 품질 의존). 캘리브레이션 개선은 베팅·전략 시뮬레이션 수익 변동성을 줄이는 데도 연결된다. 전술 맥락을 포함함으로써 해석력과 수용성이 높아지고, 벤치·리크루팅·미디어 전 부문의 의사결정 일관성도 강화된다.

실시간 운영을 위한 경계 조건

시간 동기화 오차는 ±40ms까지 허용하고, 이를 넘기면 배제 플래그를 둔다. 좌표계는 피치 105x68m 스케일로 표준화하고 공격 방향을 정규화한다. 연속 결측이 < 200ms이면 보간하며, 이상치 속도는 >10 m/s에서 클리핑한다.

학습 데이터는 경기 날짜 기준으로 시계열 분할하고 팀·선수 그룹 누수를 차단한다. 레이블은 on-target/goal 여부의 분리 모델 또는 멀티태스크를 고려할 수 있다. 훈련 뒤 홀드아웃 데이터에 Isotonic을 적용하고, 배포 전 다시 검증한다.

운영 지표로는 PSI>0.2 경보, 시즌·캠페인 전환 시 재학습 트리거, ECE<0.03, p95 지연<50ms를 둔다. 타임아웃이나 피처 누락에는 베이스라인 xG로 폴백할 수 있도록 준비한다. 웨어러블 데이터를 사용할 때는 동의와 보관기간을 준수하고 최소한 수집 원칙을 적용한다.

시스템은 Kafka 스트림 수집, Feast 피처 스토어, FastAPI/Triton 모델 서빙, Prometheus/Grafana 모니터링으로 구성할 수 있다. 실시간 방송과 벤치 인사이트를 위한 추론 지연 목표는 p95 < 50ms이며, 배포에서는 Canary·Shadow 전략과 모델 버전·특징 버전을 함께 관리한다.

실행 가능한 모델링 스케치

전제조건: Python 3.10+, scikit-learn 1.4+, xgboost 2.x, numpy/pandas 설치. 입력은 전처리 완료 피처 테이블 가정.

# pip install scikit-learn xgboost numpy pandas
import numpy as np
import pandas as pd
from sklearn.model_selection import TimeSeriesSplit
from sklearn.metrics import log_loss, brier_score_loss
from sklearn.calibration import CalibratedClassifierCV
from xgboost import XGBClassifier

# 예시 피처: 이벤트+트래킹 혼합
cols = [
    "shot_dist", "shot_angle", "is_header", "is_open_play",
    "gk_x_dev", "gk_y_dev", "nearest_def_dist", "press_speed",
    "pitch_control_attack", "att_speed_last1s"
]

# 데이터 로드
df = pd.read_parquet("features_shots.parquet")
X, y = df[cols], df["is_goal"].astype(int)

# 시간 순서 분할
tscv = TimeSeriesSplit(n_splits=5)
lls, brs = [], []

for tr_idx, te_idx in tscv.split(X):
    X_tr, X_te = X.iloc[tr_idx], X.iloc[te_idx]
    y_tr, y_te = y.iloc[tr_idx], y.iloc[te_idx]

    base = XGBClassifier(
        n_estimators=400,
        max_depth=5,
        learning_rate=0.05,
        subsample=0.9,
        colsample_bytree=0.8,
        reg_lambda=1.0,
        eval_metric="logloss",
        tree_method="hist"
    )

    # 확률 보정(플랫 또는 아이소토닉)
    clf = CalibratedClassifierCV(base, method="isotonic", cv=3)
    clf.fit(X_tr, y_tr)

    p = clf.predict_proba(X_te)[:, 1]
    lls.append(log_loss(y_te, p))
    brs.append(brier_score_loss(y_te, p))

print(f"LogLoss(mean): {np.mean(lls):.4f}, Brier(mean): {np.mean(brs):.4f}")

# 배포용 학습
final_model = CalibratedClassifierCV(
    XGBClassifier(
        n_estimators=500, max_depth=6, learning_rate=0.05,
        subsample=0.9, colsample_bytree=0.9, reg_lambda=1.0,
        eval_metric="logloss", tree_method="hist"
    ),
    method="isotonic", cv=5
).fit(X, y)
import joblib
joblib.dump(final_model, "xg_tracking_calibrated.pkl")

패널티·프리킥·헤더 등은 상황별로 샘플을 분리해 학습하는 방식을 권장한다. 학습과 서빙의 피처 스키마는 버전으로 관리하고, 피처가 누락될 때는 안전한 폴백을 둔다. 베이스라인에서 GBM, 시공간 딥러닝으로 단계적으로 확장하면서 엄격한 검증과 거버넌스를 유지하는 것이 모델 리스크를 줄이는 경로다.

기대 득점스포츠 분석선수 트래킹시공간 모델캘리브레이션