În care generăm un set de date cu duratele jocului, facem o mică analiză exploratorie a datelor și apoi încercăm să identificăm instanțe neobișnuite și cauzele acestora.
În postarea mea pe Twitter, am menționat că una dintre ultimele sale caracteristici de răscumpărare este comunitatea de statistici AFL. Simt întotdeauna nevoia să-mi cer scuze pentru postările legate de sport celor de lungă durată ale acestui blog, dar iată chestia: sportul poate oferi seturi de date bogate, poate genera numeroase întrebări interesante și poate fi o modalitate distractivă de a-ți exersa abilitățile de analiză a datelor.
De exemplu, Emlyn scrie:
și mă gândesc imediat (1) există un set de date cu durata sferturilor în jocurile AFL, (2) dacă nu, putem face unul, (3) de ce să ne limităm la sezoanele recente și (4) asta sună ca o treabă pentru unul dintre pachetele mele R preferate, anomalii.
Setul de date
Jocurile AFL sunt jucate pe parcursul a patru sferturi, care durează de obicei aproximativ 30 de minute fiecare. Din câte știu, durata trimestrelor nu este disponibilă prin intermediul fitzRoy pachet și nici nu am găsit un set de date online.
Deci, iată un cod rapid, murdar și fragil care îl folosește rvest pentru a răzui datele din tabelele AFL și iată setul de date rezultat în format CSV, cu duratele trimestrului în secunde. Avem date trimestriale privind durata din 2001 încoace. Primele rânduri arată astfel:
url match_id match_date Q1 Q2 Q3 Q41 https://afltables.com/afl/stats/games/2001/051220010330.html 51220010330 2001-03-30 2094 1623 1842 2004 2 https://afltables.com/afl/stats/games/2001/041020010331.html 41020010331 2001-03-31 1722 1882 1816 1704 3 https://afltables.com/afl/stats/games/2001/071520010331.html 71520010331 2001-03-31 1772 1872 1978 1738 4 https://afltables.com/afl/stats/games/2001/030820010331.html 30820010331 2001-03-31 1783 2035 1926 1916 5 https://afltables.com/afl/stats/games/2001/131920010331.html 131920010331 2001-03-31 1611 1751 2100 1814 6 https://afltables.com/afl/stats/games/2001/011620010401.html 11620010401 2001-04-01 1779 1686 1871 1755
Analiza exploratorie a datelor (EDA)
Există multe opțiuni bune pentru EDA folosind R. Îmi place simplitatea skimr.
skimr::skim(afl_quarter_lengths, starts_with("Q"))
── Data Summary ────────────────────────
Values
Name afl_quarter_lengths
Number of rows 4926
Number of columns 7
_______________________
Column type frequency:
numeric 4
________________________
Group variables None
── Variable type: numeric ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
skim_variable n_missing complete_rate mean sd p0 p25 p50 p75 p100 hist
1 Q1 17 0.997 1810. 134. 1213 1725 1807 1895 2571 ▁▅▇▁▁
2 Q2 17 0.997 1817. 138. 1216 1730 1816 1906 2429 ▁▂▇▂▁
3 Q3 17 0.997 1830. 142. 1223 1743 1828 1919 2395 ▁▂▇▃▁
4 Q4 17 0.997 1820. 152. 1201 1728 1814 1911 3956 ▃▇▁▁▁
Nu prea multe valori lipsă, bine.
Ne putem uita la distribuția lungimii sferturilor în funcție de sezon.
library(tidyverse)
library(lubridate)
theme_set(theme_bw())
afl_quarter_lengths %>%
pivot_longer(4:7) %>%
mutate(season = year(match_date)) %>%
ggplot(aes(season, value)) +
geom_boxplot(aes(group = season)) +
facet_wrap(~name) +
labs(x = "Season",
y = "Duration (seconds)",
title = "Duration of quarters in AFL games 2021-2025",
subtitle = "data from afltables.com")

De remarcat: (1) sezonul 2020 a fost afectat de COVID și durata trimestrelor a fost redusă; (2) ultimele 5 sezoane au înregistrat o creștere constantă a lungimii sferturilor, deși printr-o modificare medie de numai aproximativ 100 de secunde sau cam așa; (3) putem vedea deja potențiale valori aberante.
Creșterea duratei jocului pare să fie de îngrijorare pentru Casa AFL, dacă aproape nimeni altcineva, așa că ne putem uita la asta. Putem discuta despre cea mai bună modalitate de procesare și vizualizare, dar să calculăm doar timpul total de joc, valorile medii și mediane în funcție de sezon, să omitem sezonul 2020 și să reprezentăm sub formă de puncte.
afl_quarter_lengths %>%
mutate(season = year(match_date),
total = Q1 + Q2 + Q3 + Q4) %>%
group_by(season) %>%
summarise(`mean duration` = mean(total, na.rm = TRUE),
`median duration` = median(total, na.rm = TRUE)) %>%
pivot_longer(-season) %>%
filter(season != 2020) %>%
ggplot(aes(season, value)) +
geom_point() +
facet_wrap(~name) +
geom_smooth() +
labs(x = "Season",
y = "Duration (seconds)",
title = "Mean and median AFL game duration 2001-2025",
subtitle = "data from afltables.com")


Probabil o tendință ascendentă, mai ales în ultimele sezoane. Este de remarcat faptul că diferența dintre cele mai scurte și cele mai lungi valori medii sau mediane este de aproximativ 10 minute, într-un joc de 2 1/2 ore.
Folosind anomalize
Acum să folosim anomalii a căuta sferturi neobișnuit de scurte sau lungi. Putem urma împreună cu ghidul de pornire rapidă, făcând câteva modificări pentru a evita mesajele de eroare – vezi comentariile din codul de mai jos. Dacă acestea sunt bune practici pentru analiza serii cronologice, ar necesita mai multe cercetări, dar deocamdată se pare că acestea generează rezultate interesante.
library(tibbletime)
afl_quarter_lengths_anomalized <- afl_quarter_lengths %>%
pivot_longer(4:7) %>%
# remove missing values and the COVID-affected season 2020
filter(!is.na(value),
year(match_date) != 2020) %>%
# group data by quarter
group_by(name) %>%
# convert to tibbletime
as_tbl_time(index = match_date) %>%
# required to prevent Error in `reconstruct()`
as_period("1 day") %>%
time_decompose(value, merge = TRUE) %>%
anomalize(remainder) %>%
time_recompose()
afl_quarter_lengths_anomalized %>%
plot_anomalies()


Codul de mai sus aruncă câteva avertismente despre „Indexul nu este ordonat”, pe care le putem ignora deoarece datele potrivirii sunt în ordine crescătoare. Ei bine, avem anomalii – șase în total. The plot_anomalies() metoda este destul de bună, dar putem exercita mai mult control asupra complotului folosind ggplot2 metode – fie prin modificarea ieșirii de la plot_anomalies() sau lucrul cu cadrul de date de ieșire.
afl_quarter_lengths_anomalized %>%
ggplot(aes(match_date, value)) +
geom_point(aes(color = anomaly)) +
facet_wrap(~name) +
scale_color_manual(values = c("grey80", "red3")) +
theme(legend.position = "top") +
labs(x = "Match date",
y = "Duration (seconds)",
title = "Anomalous quarter lengths in AFL games 2001-2025",
subtitle = "data from afltables.com")


De asemenea, putem experimenta cu diferiți algoritmi pentru descompunerea seriilor de timp și detectarea anomaliilor. Aceasta, de exemplu, găsește 8 anomalii.
afl_quarter_lengths_anomalized_tw <- afl_quarter_lengths %>%
pivot_longer(4:7) %>%
filter(!is.na(value),
year(match_date) != 2020) %>%
group_by(name) %>%
as_tbl_time(index = match_date) %>%
as_period("1 day") %>%
time_decompose(value, merge = TRUE, method = "twitter") %>%
anomalize(remainder, method = "gesd") %>%
time_recompose()
afl_quarter_lengths_anomalized_tw %>%
plot_anomalies()


Motivele întârzierii jocului
Rămânând cu metoda care a găsit 8 anomalii, putem filtra datele de ieșire, putem vizita adresa URL a meciului la Tabelele AFL și apoi facem câteva cercetări online pentru a vedea dacă rapoartele de meci indică motivele întârzierii. Am introdus manual acele informații în tabelul de mai jos, cu un link către sursă.
afl_quarter_lengths_anomalized_tw %>% filter(anomaly == "Yes") %>% select(url, match_id, name, match_date) url match_id name match_date delay_reason 1 https://afltables.com/afl/stats/games/2018/141620180628.html 141620180628 Q1 2018-06-28 injury 2 https://afltables.com/afl/stats/games/2023/011220230701.html 11220230701 Q1 2023-07-01 injury 3 https://afltables.com/afl/stats/games/2024/192120240914.html 192120240914 Q1 2024-09-14 injury 4 https://afltables.com/afl/stats/games/2014/011920140810.html 11920140810 Q2 2014-08-10 injury 5 https://afltables.com/afl/stats/games/2001/030920010901.html 30920010901 Q3 2001-09-01 injury 6 https://afltables.com/afl/stats/games/2021/111820210809.html 111820210809 Q4 2021-08-09 weather 7 https://afltables.com/afl/stats/games/2022/091620220325.html 91620220325 Q4 2022-03-25 goal celebration 8 https://afltables.com/afl/stats/games/2024/041120240823.html 41120240823 Q4 2024-08-23 weather
De exemplu, primul meci din 2018 a avut loc între Sydney Swans și Richmond Tigers și aflăm că „cel de-al 100-lea joc al lui Conca se termină cu o accidentare îngrozitoare“. „Piciorul stâng al lui Conca a fost prins sub Lance Franklin la jumătatea primului sfert, mijlocașul Tigers în agonie, fiind tratat de echipa medicală a clubului (…) Jocul a fost oprit câteva minute.„. Verificări.
Ce este asta, „sărbătoarea obiectivului”? Întârzierea jocului meu preferat, am fost acolo!
Anomalii lipsă
Ce zici de întârzierile care au avut loc în pauzele trimestriale, întrebi? Bună întrebare și răspunsul este că nu avem acele date, îmi pare rău.
Ce zici de runda 2 2023, Brisbane Lions versus Melbourne Demons la The Gabba, când „Locația olimpica din 2032 a căzut brusc în întuneric, cu 12 minute rămase în al patrulea sfert, cu Lions cu 40 de puncte înaintea Demons”, amânând jocul cu 35 de minute? Din anumite motive, AFL Tables are cel de-al patrulea trimestru al acestui joc listat ca 31 de minute și 54 de secunde, demonstrând încă o dată că analiza este doar la fel de bună ca datele.
Asta este.
Sper că v-a plăcut.
