En dataanalyse av 940 000+ kamphendelser fra fem toppligaer ved hjelp av Python, NetworkX og SQL.

Bakgrunn og datagrunnlag

Denne analysen tar utgangspunkt i et datasett med over 940 000 kamphendelser fra fem europeiske ligaer (Bundesliga, Serie A, La Liga, Ligue 1 og Premier League) over flere sesonger. Dataene er lagret i en MySQL-database og inneholder én rad per hendelse – frispark, corner, skudd, kort, innbyttinger og mer – med tilhørende kamp-ID, tidsangivelse, lag og tekstbeskrivelse.

HendelsestypeAntall
Free kick won (frispark vunnet) 237 932
Foul (frispark mot) 232 925
Attempt (skudd) 229 135
Corner 91 204
Substitution (innbytte) 51 738
Offside 43 476
Yellow card 39 911
Hand ball, Red card, m.fl. ~14 000

Av de 229 135 skuddene endte 24 446 (10,7 %) i mål – identifisert via kolonnen is_goal.

Metode

Teknisk oppsett

Analysen er gjennomført i en Jupyter Notebook med følgende teknologistakk:

  • Python 3.14 med pandas, numpy, matplotlib
  • NetworkX for grafanalyse og visualisering av hendelsessekvenser
  • SQLAlchemy + PyMySQL for tilkobling til MySQL-databasen
from sqlalchemy import create_engine
import pandas as pd

engine = create_engine('mysql+pymysql://bruker:passord@host:3307/fotballdata')
df_events = pd.read_sql("""
    SELECT * FROM events A
    INNER JOIN event_type B ON A.event_type = B.idx
""", con=engine)

Analyse 1 – Hendelsessekvens-graf (NetworkX)

For å forstå hvilke hendelseskjeder som typisk leder frem til et skudd, ble det bygget en rettet vektet graf (DiGraph) der:

  • Noder = hendelsestyper (Corner, Foul, Free kick won, Attempt, Goal, …)
  • Kanter = overgang mellom to hendelsestyper i en sekvens
  • Kantvekt = antall ganger overgangen forekom i datasettet

For hvert Attempt- eller Goal-event ble de K = 4 foregående hendelsene i samme kamp (etter sort_order) hentet ut. Alle konsekutive par i denne sekvensen ble lagt til som kanter, og selvkanter (samme hendelse to ganger på rad) ble filtrert bort.

K = 4
transitions = collections.Counter()

for _, grp in df_g.groupby('id_odsp'):
    labels = grp['event_label'].tolist()
    for i, label in enumerate(labels):
        if label not in {'Attempt', 'Goal'}:
            continue
        seq = labels[max(0, i - K) : i + 1]
        for a, b in zip(seq, seq[1:]):
            if a != b:
                transitions[(a, b)] += 1

Analyse 2 – Konverteringsrate per situasjon

Kun Attempt-rader ble brukt. Konverteringsrate ble beregnet som is_goal.mean() × 100 gruppert på:

  • situation – situasjonstype (åpent spill, frispark, corner, straffe)
  • fast_break – flagg for kontring (0 / 1)
  • assist_method – assisttype (pasning, innlegg, gjennombrudd, m.m.)

Resultater

Topp 10 hendelsesoverganger som leder til skudd

FraTilAntall
Foul Free kick won 109 205
Free kick won Foul 79 236
Free kick won Attempt 73 128
Corner Attempt 69 607
Foul Attempt 44 978
Attempt Corner 40 098
Attempt Foul 23 154
Substitution Attempt 23 061
Yellow card Attempt 20 858
Offside Attempt 19 096
Merk: Foul og Free kick won opptrer i par i datasettet (én hendelse registreres for hvert lag), og de høye tallene for Foul ↔ Free kick won gjenspeiler dette – ikke to separate spillhandlinger.

Konverteringsrate per situasjonstype

Frispark (direkte)31,3 % (n = 11 741)
Corner15,0 % (n = 18 225)
Straffe13,6 % (n = 5 422)
Åpent spill8,9 % (n = 193 747)

Kontring vs. normalt spill

Kontring35,8 % (n = 4 588)
Normalt spill10,2 % (n = 224 547)

Kontringer er 3,5 ganger mer effektive enn skudd fra normalt spill, til tross for at de utgjør under 2 % av alle skudd.

Konverteringsrate per assisttype

Gjennombrudd26,0 % (n = 7 372)
Ingen assist12,9 % (n = 61 276)
Innlegg / cross11,9 % (n = 43 271)
Hodepasning10,9 % (n = 7 713)
Pasning7,9 % (n = 109 503)

Tekstbasert analyse

Etter corner15,0 % (n = 18 225)
Hodestøt11,4 % (n = 42 664)
Fra utsiden av 16-meter2,7 % (n = 93 667)

Nøkkelord som «counter» og «intercept» fantes ikke i text-feltet, da dette beskriver selve avslutningen (fotsted, posisjon, utfall) – ikke forhistorien. Kontringer fanges i stedet opp av den dedikerte fast_break-kolonnen.

Ligaanalyse — fem europeiske toppligaer

Alle fem ligaene har overraskende like konverteringsrater (10,0–11,2 %), men spillestilene skiller seg klart på kontring-andelen.

Ligaanalyse — konverteringsrate og kontring per liga

La Liga11,2 % (49 948 skudd)
Bundesliga11,1 % (41 537 skudd)
Ligue 110,6 % (48 994 skudd)
Premier League10,5 % (33 912 skudd)
Serie A10,0 % (54 744 skudd)
Bundesliga er kontring-ligaen (3,0 %). Premier League bruker kontring bare i 1,0 % av skuddene — lavest av alle fem. Serie A har flest skudd totalt, men lavest konverteringsrate. Forskjellene mellom ligaene er likevel moderate; det er situasjonstype og assisttype som forklarer mest variasjon i målrate.

Tidsanalyse — konverteringsrate gjennom kampen

Konverteringsraten stiger jevnt gjennom kampen: fra 9,8 % i de første 15 minuttene til 12,0 % i overtiden. Samtidig øker det totale skuddvolumet mot slutten av ordinær tid (76–90 min: 46 356 skudd — flest i noen periode).

Konverteringsrate per 15-minuttersperiode

90+ min12,0 % (2 234 skudd)
76–90 min11,3 % (46 356 skudd)
61–75 min11,0 % (38 260 skudd)
0–15 min9,8 % (30 959 skudd)
Sluttspurten gir dobbel effekt. Det skytes flest skudd i de siste 15 minuttene (76–90), og hvert enkelt skudd er mer effektivt enn tidlig i kampen — trolig fordi forsvarsspillerne er trettere og rekkene er mer åpne.

Konklusjoner

  1. Kontringer er de farligste situasjonene (35,8 %). Selv om de er sjeldne (~2 % av alle skudd), er konverteringsraten mer enn tre ganger høyere enn for normalt spill. En defensiv feil i overgangsfasen er svært kostbar.
  2. Gjennombruddsballer gir de beste sjansene (26,0 %). Å spille ballen bak forsvarsrekken er markant mer effektivt enn kombinasjonsspill og innlegg fra siden.
  3. Dødball dominerer antallsmessig. Corner → Attempt (69 607) og Free kick won → Attempt (73 128) er de hyppigste direkte veiene til skudd. Set pieces er en kritisk del av offensivt spill.
  4. Skudd utenfor 16-meteren er nesten aldri lønnsomme (2,7 %). 97 av 100 langskudd ender uten mål – men de gir ofte reboundmuligheter (corner / blokkert).
  5. Attempt → Corner (40 098) viser pressbølger. Mange skudd blokkeres til corner, som igjen gir nytt press – en selvforsterkende angrepssyklus.
  6. Bundesliga er kontring-ligaen (3,0 %). Premier League bruker kontring minst (1,0 %). Totalt er konverteringsratene likevel nær like (10,0–11,2 %) på tvers av de fem ligaene.
  7. Kampens siste kvartal er det farligste (11,3 %). Skuddvolumet topper seg i 76–90-perioden (46 356 skudd), og konverteringsraten er klart høyere enn tidlig i kampen (9,8 % i 0–15 min). Trøtthet og åpne rekker gir et taktisk vindu i sluttfasen.
  8. Composure skiller elitespillere fra gjennomsnittet. FIFA-analysen viser at ro under press (+21 poeng for angripere) er den enkeltegenskapen som gjennomgående differensierer toppspillere i alle roller.

Spillerattributter og rolleanalyse (FIFA 19-data)

For å forstå hvem som skaper målsjanser, ble hendelsesdataene koblet mot FIFA 19-spillerdatabasen (16 654 spillere) via en speilkobling (events.player_fixed → players.idx_fifa → Data.ID). Totalt 163 167 skudd (71,2 %) fikk et gyldig FIFA-oppslag, fordelt på 3 043 unike spillere.

FIFA-rating vs. faktisk konverteringsrate

Scatter-plottet nedanfor viser samanhengen mellom FIFA-attributtar og reell konverteringsrate for spelarar med ≥ 20 skudd i datasettet. Dei sterkaste korrelasjonane mot konverteringsrate er HeadingAccuracy (r = +0,19) og Finishing (r = +0,17). SprintSpeed har ingen statistisk samanheng (r = −0,02).

FIFA-rating vs faktisk konverteringsrate

Hvilke attributter kjennetegner hver rolle?

Radardiagrammene nedenfor viser gjennomsnittlig FIFA-rating per posisjonskategori — med rollespesifikke attributter for hver kategori. Det gir et mer presist bilde enn å sammenligne alle roller på de samme egenskapene.

FIFA attributtprofil per rolle — radardiagram

Hva skiller elitespillere fra gjennomsnittsspillere i hver rolle?

Spillere med Overall ≥ 85 (elite) og Overall 65–74 (gjennomsnitt) ble sammenliknet på nøkkelattributter for hver rolle. De største gapene:

Angrep — Composure+21,4 poeng
GK — Composure+19,3 poeng
Forsvar — Markering+19,9 poeng
Forsvar — Avbrytingar+19,6 poeng
Midtbane — Visjon+18,7 poeng

Elite vs gjennomsnittleg spelarar per rolle

Funn: Composure (ro under press) er den enkeltegenskapen som skiller elite fra gjennomsnitt i tre av fire roller. For forsvar er taktisk disiplin (markering, avbrytinger) det avgjørende skillet.

Hvilke FIFA-attributter korrelerer med Overall innenfor hver rolle?

Pearson-korrelasjon mot Overall-rating (FIFA sin samlede vurdering av spilleren i sin rolle):

RolleSterkaste korrelasjonar
Forsvar StandingTackle r = +0,88 · Interceptions r = +0,88 · Marking r = +0,84
Midtbane BallControl r = +0,89 · ShortPassing r = +0,83 · Vision r = +0,79
Angrep BallControl r = +0,90 · Positioning r = +0,89 · Composure r = +0,84
Keeper GKReflexes r = +0,91 · GKDiving r = +0,89 · GKPositioning r = +0,88

Topp 15 spelarar per posisjonskategori (FIFA 19)

Rangert etter Overall-rating. Annotert med nøkkelattributter for rollen. Den stiplede linjen markerer elite-grensen (Overall ≥ 85).

Topp 15 angripere — FIFA 19

Topp 15 midtbanespelerar — FIFA 19

Topp 15 forsvarsspelerar — FIFA 19

Topp 15 keeperar — FIFA 19

Begrensninger og videre arbeid

  • Vindusstørrelsen K = 4 er vilkårlig; et dynamisk besittelsesbasert vindu vil gi mer presise sekvenser.
  • Hendelser fra begge lag er inkludert i grafen, noe som skaper artefakter (Foul ↔ Free kick won er speilhendelser).
  • Dataene er aggregert på tvers av fem ligaer; ligaspesifikke mønstre er skjult.
  • Foreslått videre analyse: filtrer på event_team = angripende lag, bruk sanntidsposisjonsdata (x/y) for Expected Goals (xG)-modell.
Analyse utført med Python / Jupyter Notebook · Data: European Soccer Database (Kaggle) · Verktøy: pandas, NetworkX, matplotlib, SQLAlchemy · © 2026

No comments

Leave your comment

In reply to Some User