Voetbalwedstrijden voorspellen met Python

Met de start van het EK Voetbal schieten de EK Poules als paddenstoelen uit de grond. Nu vraag jij jezelf natuurlijk af of je wellicht bepaalde data kunt gebruiken om de uitslagen van de voetbalwedstrijden te voorspellen.

Let wel op: De methode die we hier gebruiken biedt natuurlijk geen garantie voor een juiste voorspelling. Het is echter wel een data-gedreven manier om voorspelling te kunnen doen. Ook willen we je natuurlijk geen gokprobleem aanpraten, dus ga verstandig om met je geld. Nu we de formaliteiten en disclaimers achter de rug hebben kunnen we aan de slag met het maken van iets gaafs.

Voetbalwedstrijden voorspellen in slechts 6 stappen

In dit script lopen we door de volgende 6 stappen heen om de uitslag te kunnen voorspellen:

  1. Inladen van libraries: Voor dit script maken we gebruik van slechts drie bibliotheken:
    • numpy: Voor numerieke berekeningen.
    • pandas: Voor data-analyse en -manipulatie.
    • scipy.stats: Voor het genereren van Poisson-gerandomiseerde waarden.
  2. Landgegevens en ELO-ratings: ELO-ratings worden gebruikt om de sterkte van de teams te kwantificeren. Ze helpen bij het bepalen van de verwachte doelpunten voor elk team op basis van hun relatieve sterkte.
  3. Gemiddelde doelpunten per wedstrijd: Dit zijn de gemiddelde doelpunten die elk team per wedstrijd scoort. Deze waarden kunnen worden aangepast met echte data om nauwkeuriger voorspellingen te maken.
  4. Verwachte doelpunten berekenen: Deze functie berekent de verwachte doelpunten voor elk team op basis van hun ELO-ratings en gemiddelde doelpunten. Dit helpt om een realistisch aantal doelpunten voor elke wedstrijd te schatten.
  5. Monte Carlo-simulatie uitvoeren: We voeren 10.000 simulaties uit waarbij het aantal doelpunten voor elk team wordt gegenereerd volgens de Poisson-verdeling. Dit helpt om de variabiliteit en mogelijke uitkomsten van de wedstrijd te modelleren.

    Waarom Poisson gebruiken?
    De Poisson-verdeling is nuttig in voetbalvoorspellingen omdat het de kans berekent dat een bepaald aantal gebeurtenissen (in dit geval, doelpunten) plaatsvinden in een vaste tijdsperiode. Voetbaldoelpunten zijn zeldzame gebeurtenissen die onafhankelijk van elkaar optreden, waardoor de Poisson-verdeling geschikt is voor dit doel.

    Wat is een Monte Carlo-simulatie?
    Een Monte Carlo-simulatie is een statistische techniek die gebruik maakt van willekeurige sampling en herhaling om de waarschijnlijkheid van verschillende uitkomsten te modelleren. In deze context simuleert de Monte Carlo-methode duizenden wedstrijden op basis van de verwachte doelpunten om de waarschijnlijkheid van elke mogelijke uitkomst (winst, verlies, gelijkspel) te bepalen.
  6. Resultaten analyseren: We analyseren de resultaten van de simulaties en berekenen de waarschijnlijkheid van elke mogelijke uitkomst (winst, verlies, gelijkspel). Dit geeft een probabilistisch beeld van de mogelijke resultaten van de wedstrijd.
import numpy as np
import pandas as pd
from scipy.stats import poisson

# Landen en bijbehorende gegevens
country_one = 'Nederland'
country_two = 'Frankrijk'

elo_country_one = 1720
elo_country_two = 1760

goals_per_match_country_one = 1.8
goals_per_match_country_two = 2.2

# Verwachte doelpunten berekenen
def expected_goals(elo1, elo2, avg_goals):
    return avg_goals * (elo1 / (elo1 + elo2))

exp_goals_country_one = expected_goals(elo_country_one, elo_country_two, goals_per_match_country_one)
exp_goals_country_two = expected_goals(elo_country_two, elo_country_one, goals_per_match_country_two)

print(f"Verwachte doelpunten {country_one}: {exp_goals_country_one}")
print(f"Verwachte doelpunten {country_two}: {exp_goals_country_two}")

# Monte Carlo-simulatie uitvoeren
simulations = 10000
country_one_goals = poisson.rvs(exp_goals_country_one, size=simulations)
country_two_goals = poisson.rvs(exp_goals_country_two, size=simulations)

# Resultaten analyseren
results = pd.DataFrame({country_one: country_one_goals, country_two: country_two_goals})
results['Result'] = np.where(results[country_one] > results[country_two], f'{country_one} Wins',
                             np.where(results[country_one] < results[country_two], f'{country_two} Wins', 'Draw'))

prob_country_one_win = (results['Result'] == f'{country_one} Wins').mean()
prob_country_two_win = (results['Result'] == f'{country_two} Wins').mean()
prob_draw = (results['Result'] == 'Draw').mean()

print(f"Waarschijnlijkheid dat {country_one} wint: {prob_country_one_win:.2%}")
print(f"Waarschijnlijkheid dat {country_two} wint: {prob_country_two_win:.2%}")
print(f"Waarschijnlijkheid op een gelijkspel: {prob_draw:.2%}")

Het resultaat

Eenmaal klaar met de berekeningen geeft het script de volgende output.

voetbalwedstrijden voorspellen - uitslag

Ideeën voor nóg betere voorspellingen

Zou je de voorspelling nog nauwkeuriger willen maken? Dan kun je wellicht ook overwegen om de volgende elementen in te calculeren voor je voorspelling:

  • Thuisvoordeel: Teams presteren vaak beter in hun thuisstadion.
  • Blessures en Schorsingen: De afwezigheid van sleutelspelers kan de prestaties van een team aanzienlijk beïnvloeden.
  • Vorm en Morale: De recente vorm van een team en de mentale toestand van de spelers.

Bronnen voor Data

Voor nauwkeurige voorspellingen kun je echte data gebruiken van de volgende bronnen:

  1. FIFA.com: De officiële website van FIFA biedt gedetailleerde ranglijsten en statistieken voor internationale teams. Deze data kan direct worden gebruikt voor het bepalen van de ELO-ratings en andere relevante statistieken voor teamsterkte.
  2. Eloratings.net: Hier vind je de ELO-ratings van alle landen. Wel volgens een ander systeem dan FIFA.
  3. Kaggle Datasets: De ‘European Soccer Database’ bevat data van meer dan 25.000 wedstrijden. Zoek naar datasets met historische wedstrijdresultaten en teamstatistieken.