하나의 숫자에 모든 걸 걸지 마라
2026 월드컵을 앞두고, 한 가지 질문이 머릿속을 떠나지 않았습니다. "과연 누가 우승할까?"
단순히 호기심을 넘어, 이 질문은 머신러닝 실무자로서 놓치기 어려운 도전 과제였습니다. 제한된 데이터, 다양한 모델, 그리고 각 모델이 만들어내는 서로 다른 '세상' — 이 셋이 만나면 어떤 일이 벌어질까요?
결론부터 말하면, 저는 11개의 서로 다른 모델을 만들었고, 우승 후보는 4팀으로 갈렸습니다.
- 스페인 (Elo, Poisson, 로지스틱 회귀 등)
- 아르헨티나 (Random Forest, XGBoost)
- 프랑스 (신경망)
- 네덜란드 (Colley)
이 결과는 단순한 재미를 넘어서, '앙상블(Ensemble) 예측'의 본질을 보여줍니다. 서로 다른 모델이 같은 데이터로 학습했는데도 다른 결론에 도달하는 이유, 그리고 그 불일치가 왜 더 솔직한 답변인지에 대한 이야기입니다.
이 글은 358개의 실제 국제 경기 데이터(2010-2022 월드컵, 2020/2024 유로)를 기반으로 합니다. 근거자료에서 전체 소스와 코드를 확인할 수 있습니다.
11개의 엔진, 하나의 인터페이스
모든 모델을 공정하게 비교하기 위해, 각 모델은 동일한 계약(Contract)을 따르도록 설계했습니다.
def match_probs(model, team_a, team_b):
"""
모든 모델은 이 함수를 구현한다.
반환값: (승리 확률, 무승부 확률, 패배 확률)
"""
...
def simulate_tournament(model, n_sims=20000):
"""
조별 예선 -> 3위 팀 비교 -> 32강 토너먼트 -> 우승팀 결정
모든 시뮬레이션은 NumPy 벡터 연산으로 처리된다.
"""
...
핵심은 각 모델이 match_probs를 어떻게 채우는지입니다. 이 부분이 바로 불일치의 원천이 됩니다.
모델 유형 1: 레이팅 시스템 (결과 기반)
- Elo: 자가 교정되는 숫자. 경기 후
R' = R + K(S - E)로 업데이트됩니다. 기대 승리 확률은E = 1/(1 + 10^(−Δ/400))입니다. - Colley: 시간 순서를 무시하고, 모든 경기의 승패 관계를 하나의 선형 시스템으로 풉니다. 대각 성분에 +2를 더해 항상 해가 존재하도록 보장합니다.
- PageRank: 경기를 방향 그래프로 보고, 패자가 승자에게 '지지(Endorsement)'를 보내는 구조입니다. 구글이 웹페이지 랭킹에 사용한 알고리즘과 동일합니다.
이 세 모델은 팀의 평판이나 최근 폼이 아닌, 오직 데이터에 존재하는 결과만으로 팀의 강함을 평가합니다. 그 결과, 네덜란드가 시장의 기대보다 훨씬 높게 평가되었습니다.
모델 유형 2: 골 모델 (득점 기반)
이 모델들은 결과 자체가 아닌 득점 수를 예측합니다.
import statsmodels.api as sm
# 골 수 ~ exp(beta0 + beta1 * 팀 간 전력 차이)
# 로그 링크 함수를 사용한 Poisson GLM 적합
fit = sm.GLM(goals, sm.add_constant(strength_diff),
family=sm.families.Poisson()).fit()
# 적합 결과: lambda = exp(0.167 + 0.00164 * strength_diff)
# 이 lambda를 통해 두 팀의 득점 분포를 만들고,
# 외적(Outer Product)을 계산해 승/무/패 확률을 도출한다.
- Poisson: 득점 평균이 분산과 같다고 가정합니다.
- Negative Binomial: 평균과 분산이 다를 수 있도록 허용합니다. 실제 데이터 적합 결과, 분산 계수 α ≈ 0.008로 매우 작아 국제전 득점은 거의 등분산에 가깝다는 것을 확인했습니다.
모델 유형 3: 분류기 (특징 기반)
머신러닝 분류기들은 세 가지 특징(전력 차이, 결합 전력, 토너먼트 여부)을 입력받아 승/무/패를 직접 예측합니다.
- 로지스틱 회귀
- K-최근접 이웃(KNN)
- 랜덤 포레스트
- XGBoost
- 신경망 (MLP)
왜 결과가 갈리는가: 불일치의 세 가지 이유
단일 경기에서도 모델 간 의견 차이는 극명했습니다. 스페인 vs 모로코 경기에서 스페인의 승리 확률은 PageRank의 69%에서 XGBoost의 25%까지 넓게 퍼졌습니다.
| 모델 | 스페인 승 | 무승부 | 모로코 승 |
|---|---|---|---|
| PageRank | 69% | 24% | 7% |
| Poisson | 63% | 22% | 15% |
| 로지스틱 | 61% | 24% | 15% |
| Elo | 61% | 26% | 13% |
| Colley | 57% | 26% | 17% |
| 신경망 | 56% | 20% | 24% |
| KNN | 47% | 27% | 27% |
| 랜덤 포레스트 | 40% | 39% | 22% |
| XGBoost | 25% | 64% | 11% |
이러한 차이는 단순한 오차가 아니라, 같은 게임을 바라보는 서로 다른 이론입니다. 그 원인은 크게 세 가지로 요약됩니다.
- 정보의 원천 (Information Source): Elo는 최근 성적(폼)을, Colley/PageRank는 데이터 내의 결과만을 반영합니다.
- 골 vs 결과 (Goals vs. Outcomes): Poisson 계열은 득점을, 분류기는 결과를 직접 모델링합니다. 팽팽한 경기에서 무승부 확률을 다르게 부여합니다.
- 편향 vs 분산 (Bias vs. Variance): XGBoost와 같은 유연한 모델은 358개의 적은 데이터에서 노이즈까지 학습할 위험이 있습니다. 이는 교차 검증에서 가장 유연한 모델의 성능이 가장 낮게 나온 결과에서도 확인됩니다.
앙상블의 교훈: 합의는 '솔직한 회색지대'에 있다
10개 모델의 평균(컨센서스)은 여전히 그럴듯합니다. 스페인 약 20%, 프랑스와 아르헨티나 약 14%, 그리고 네덜란드와 잉글랜드가 그 뒤를 잇습니다.
하지만 중요한 것은 회색 막대(Grey Bar) 입니다. 모델 간 최소값과 최대값의 범위가 매우 넓다는 것입니다.
누군가 "월드컵 우승팀은 스페인이다"라고 단일 숫자를 제시한다면, 그 사람은 이 회색 막대를 숨기고 있는 겁니다. 그리고 그 막대가 바로 가장 솔직한 부분입니다.
한국 개발자에게 주는 실무 인사이트 🧑💻
이 프로젝트는 단순한 축구 예측을 넘어, AI/ML 프로젝트를 진행하는 모든 개발자에게 중요한 메시지를 줍니다.
- 모델의 '독립성'을 의심하라: 여러 모델을 쓴다고 해서 모두가 '독립적인 증인'이 아닙니다. 같은 피처와 사전 확률을 공유한다면, 그들의 합의는 기계적인 결과일 뿐입니다. 국내 프로젝트에서도 여러 모델을 비교할 때, 서로 다른 정보를 쓰는지 확인해야 합니다.
- 과적합은 '작은 데이터'의 적: XGBoost가 성능이 좋다고 해서 무작정 도입했다간, 데이터가 적을 때는 오히려 독이 됩니다. 교차 검증 결과를 믿고, 단순한 모델부터 시작하는 것이 장기적으로 빠른 길입니다.
- '하나의 숫자'보다 '불확실성의 범위'를 제시하라: 비즈니스 미팅에서 "우리 모델의 정확도는 85%입니다"라고 말하는 대신, "모델에 따라 78%~90%까지 차이가 납니다"라고 말하는 것이 더 솔직하고, 의사결정에 유용합니다.
이 기술의 한계 또는 주의사항
- 데이터 편향: 학습 데이터가 월드컵과 유로에 치중되어 있어 비유럽 팀의 전력이 과소평가될 수 있습니다.
- 중립 경기 가정: 시뮬레이션은 모든 경기를 중립 구장으로 가정합니다.
- 모델 간 상관관계: 골 모델과 분류기는 동일한 Elo 기반의 사전 확률을 사용하므로, 그들의 합의는 '독립적 검증'이 아닙니다. 진정한 독립성은 Colley와 PageRank만이 가집니다.
다음 단계 학습 방향
이 프로젝트에서 끝내지 말고, 더 깊은 세계로 들어가 보세요.
- 베팅 시장과의 비교: 모델의 예측 확률을 베팅 시장의 마진 제거(De-vig) 확률과 비교해보세요. 시장이 비효율적인지, 아니면 모델이 놓치는 정보가 있는지 알 수 있습니다.
- 시계열 모델링: 경기 결과는 시간의 흐름에 따라 변합니다. 현재는 정적이지만,
경기 날짜를 피처로 넣어 시간 가중치를 주는 방법을 고민해보세요. - Python 실무 스킬: NumPy 벡터 연산으로 2만 번의 토너먼트 시뮬레이션을 빠르게 처리하는 방법은, 데이터 처리 성능이 중요한 실무에서 큰 도움이 됩니다.
함께 보면 좋은 글
- Claude Managed Agents × Cloudflare: 뇌와 손을 분리한 AI 에이전트의 진화
- CSS 상대 색상(Relative Color)으로 애니메이션 테마링 끝내기 OKLCH 실전 가이드


