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.
| Hendelsestype | Antall |
|---|---|
| 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
| Fra | Til | Antall |
|---|---|---|
| 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 |
Konverteringsrate per situasjonstype

Kontring vs. normalt spill
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
Tekstbasert analyse

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.

Kontringsdybde — hva utløser dem, og hvor på banen skjer det?
Kontringer har en konverteringsrate på 35,8 % — mer enn tre ganger høyere enn normalt spill. Men hva utløser disse farlige overgangene, og fra hvilke posisjoner skytes de?

Hva utløser kontringa?
Hvor på banen skytes kontringsskuddene?
Sammenlignet med alle skudd viser analysen et tydelig mønster: kontringer ender oftere med skudd fra bred vinkel langs sidelinjen (9 og 11 i sonekart: 29 % vs. 16 % for alle skudd), og sjeldnere med langskudd fra avstand (28 % vs. 43 %). Dette gjenspeiler klassisk kontringsspill — bryt langs kanten, kutt inn og avslutt fra siden av 16-meteren.
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).

Konklusjoner
- 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.
- Gjennombruddsballer gir de beste sjansene (26,0 %). Å spille ballen bak forsvarsrekken er markant mer effektivt enn kombinasjonsspill og innlegg fra siden.
- 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.
- 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).
- Attempt → Corner (40 098) viser pressbølger. Mange skudd blokkeres til corner, som igjen gir nytt press – en selvforsterkende angrepssyklus.
- 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.
- 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.
- 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 (EA Sports) (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 spillere med ≥ 20 skudd i datasettet. Dei sterkeste korrelasjonane mot konverteringsrate er HeadingAccuracy (r = +0,19) og Finishing (r = +0,17). SprintSpeed har ingen statistisk samanheng (r = −0,02).

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.

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:

Hvilke FIFA-attributter korrelerer med Overall innenfor hver rolle?
Pearson-korrelasjon mot Overall-rating (FIFA sin samlede vurdering av spilleren i sin rolle):
| Rolle | Sterkeste korrelasjoner |
|---|---|
| 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 spillere per posisjonskategori (FIFA 19)
Rangert etter Overall-rating. Annotert med nøkkelattributter for rollen. Den stiplede linjen markerer elite-grensen (Overall ≥ 85).




Begrensninger og videre arbeid
- Vindusstørrelsen
K = 4er 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.