Als we het over anomalieën hebben, bedoelen we datapunten die uitschieters zijn of een uitzonderlijke gebeurtenis vormen. Zulke gebeurtenissen identificeren is eenvoudig in kleine datasets en kan met simpele analysegrafieken zoals boxplots. Maar het wordt al snel ingewikkeld bij grote datasets, zeker bij tijdreeksen. Een tijdreeks is data die op vaste tijdsintervallen over een periode is vastgelegd en bij analyse een trend of seizoenspatroon laat zien. Het identificeren van anomalieën in zulke gevallen is best lastig.
Daarvoor is er het anomalize-pakket voor anomaliedetectie in tijdreeksanalyse. Het is een nette, op tijd gebaseerde anomaliedetectie-algoritme dat schaalbaar is van één tot veel tijdreeksen.
Er zijn verschillende beschikbare pakketten en methoden die bijdragen aan de werking, of je kunt zeggen dat het een combinatie is van bestaande bronnen met een schaalbare aanpak.
De open-sourceprojecten die hebben geholpen, zijn onder andere:
Twitter’s AnomalyDetection-pakket: beschikbaar op Github (cran anaomalyDetection is ander werk).
Rob Hyndman’s functie forecast::tsoutliers() uit het forecast-pakket.
Javier Lopez-de-lacalle’s pakket tsoutliers op CRAN.
Deze pakketten en functies worden geïntegreerd in een schaalbare workflow.
De workflow van anomalize is opgedeeld in drie delen:
Tijdreeksdecompositie met time_decompose().
Anomaliedetectie op de remainder met anomalize().
Transformatie van onder- en bovengrens van anomalieën met time_recompose().
Workflow van anomaliedetectie
Decompositie van tijdreeksen
De eerste stap is de tijdreeksdecompositie met time_decompose(). De gemeten of numerieke waarde waarop je voor een bepaalde groep wilt detecteren, wordt opgesplitst in vier kolommen: observed, season, trend en remainder. De standaardmethode voor decompositie is stl, een seizoensdecompositie met een Loess-smoother.
Loess-regressie is de meest gebruikte methode om een volatiele tijdreeks te vergladden. Er worden meerdere regressies gefit in de lokale buurt; je kunt ook zeggen dat de data wordt opgedeeld en dat op elk deel regressie wordt toegepast. Dat is nuttig bij tijdreeksen, omdat we de begrenzing in de tijd kennen, die hier de X-variabele is. Deze methode werkt goed wanneer de trend domineert over de seizoensinvloed van de tijdreeks.
Hier is trend de langetermijngroei die over veel observaties plaatsvindt, en seizoensinvloed het cyclische patroon dat optreedt op een dagelijkse cyclus per minuut of uur, of wekelijks.
Er is een tweede techniek voor seizoensdecompositie in tijdreeksen op basis van de mediaan: de Twitter-methode, die ook wordt gebruikt in het AnomalyDetection-pakket. Deze is identiek aan STL voor het verwijderen van de seizoenscomponent. Het verschil zit in het verwijderen van de trend: die gebruikt een stukgewijze mediaan van de data (één of meerdere medianen gesplitst op opgegeven intervallen) in plaats van een smoother te fitten. Deze methode werkt goed wanneer de seizoensinvloed domineert over de trend in de tijdreeks.
Laten we het hebben over de output van de functie time_decompose(). Zoals hierboven besproken produceert die 4 kolommen:
observed: De werkelijke waarden.
season: De seizoens- of cyclische component. Standaard is er een wekelijkse seizoensinvloed.
trend: De langetermijntrend. Standaard is de span 3 maanden.
remainder: Wordt gebruikt voor het analyseren van uitschieters. Het is simpelweg observed minus zowel season als trend.
De functie time_decompose() heeft een argument merge. Door dit op TRUE te zetten, behoud je de originele data samen met de geproduceerde kolommen.
# Using data package provided in the anomalize package and taking single time series of package purrr
purrr_package = tidyverse_cran_downloads%>%
filter(package =="purrr")%>%
ungroup()
purrr_anomaly = purrr_package %>%
time_decompose(count)
purrr_anomaly%>% glimpse()Mogelijk gemaakt door
Nadat de tijdreeksanalyse is voltooid en de remainder de gewenste eigenschappen heeft om anomalieën te detecteren, worden opnieuw drie nieuwe kolommen gemaakt.
remainder_l1: De ondergrens van de remainder.
remainder_l2: De bovengrens van de remainder.
anomaly: Kolom die aangeeft of de observatie een anomalie is of niet.
Anomalieën zijn high-leveragepunten die de verdeling vertekenen. Anomalize implementeert twee methoden die bestand zijn tegen high-leveragepunten:
IQR: Interkwartielafstand
GESD: Generalized Extreme Studentized Deviate Test
IQR
Dit is vergelijkbaar met de methode die in de functie tsoutliers() van het forecast-pakket wordt gebruikt. Bij IQR neem je een verdeling en gebruik je de 25%- en 75%-kwartielen om de verdeling van de remainder vast te stellen. De grenzen worden standaard ingesteld op een factor 3 keer boven en onder de interkwartielafstand; elke remainder buiten die grenzen wordt als anomalie beschouwd.
GESD
Bij GESD worden anomalieën stapsgewijs geëvalueerd door de grootste overtreders te verwijderen en de teststatistieken en kritieke waarden opnieuw te berekenen; eenvoudiger gezegd: het bereik wordt iteratief herberekend nadat anomalieën zijn geïdentificeerd.
Beide, IQR en GESD, hebben hun voor- en nadelen. IQR is relatief sneller omdat er geen lussen in zitten, maar het is niet zo nauwkeurig als GESD, aangezien anomalieën de mediaan scheeftrekken, wat bij GESD wordt ondervangen.
purrr_anomaly = purrr_anomaly%>%
anomalize(remainder)
purrr_anomaly%>% glimpse()Mogelijk gemaakt door
Transformatie van onder- en bovengrens van anomalieën
De laatste stap van de workflow is het creëren van onder- en bovengrenzen rond de observed-waarden met time_recompose. Daarbij worden season, trend, remainder_l1 en remainder_l2 opnieuw samengesteld tot nieuwe grenzen:
recomposed_l1: De ondergrens van uitschieters rond de observed-waarden.
recomposed_l2: De bovengrens van uitschieters rond de observed-waarden.
purrr_anomaly = purrr_anomaly%>%
time_recompose()
purrr_anomaly%>% glimpse()Mogelijk gemaakt door
purrr_anomaly%>%
plot_anomaly_decomposition()+
ggtitle("Plotting Anomalies")Mogelijk gemaakt door
Parameters afstemmen
Een anomaliedetector modelleren is niet compleet zonder de parameters te finetunen, die volledig afhankelijk zijn van de data.
Laten we de parameters afstellen. De parameters van elk niveau van de workflow verschillen, omdat elk niveau zijn eigen taak uitvoert.
Parameters van decompositie aanpassen
Zoals eerder besproken zijn trend en seizoensinvloed essentieel voor het decomponeren van een tijdreeks. Dus moet je ook de frequentie en trend van de functie time_decompose aanpassen. Standaard worden de waarden automatisch ingesteld: 7 dagen voor de frequentie in beide methoden (STL, Twitter) en voor de trend 91 dagen voor STL en 85 dagen voor Twitter.
Je kunt beide of één van de argumenten naar wens tweaken, maar let goed op vóór je aanpast: wijzigen zonder observatie kan leiden tot overfitting of underfitting van het decompositieproces.
purrr_package %>%
time_decompose(count, frequency ="auto", trend ="2 weeks")%>%
anomalize(remainder)%>%
plot_anomaly_decomposition()+
ggtitle("Trend = 2 Weeks / Frequency = auto ")Mogelijk gemaakt door
Parameters voor anomaliedetectie aanpassen
Zoals hierboven besproken wordt de anomalie hier bepaald op basis van de waarden van de remainder door grenzen te berekenen om uitschieters te categoriseren. De parameters alpha en max_anoms sturen de functie anomalize(). Simpel gezegd: alpha regelt de bandbreedte van de grens; standaard is die 0,05. Door de waarde te verlagen, vergroot je de band, waardoor het lastiger wordt voor een punt om als anomalie te gelden.
purrr_package%>%
time_decompose(count)%>%
anomalize(remainder, alpha =0.05)%>%
time_recompose()%>%
plot_anomalies(time_recompose = T)+
ggtitle("alpha = 0.05")Mogelijk gemaakt door
purrr_package%>%
time_decompose(count)%>%
anomalize(remainder, alpha =0.025)%>%
time_recompose()%>%
plot_anomalies(time_recompose = T)+
ggtitle("alpha = 0.025")Mogelijk gemaakt door
De parameter max_anom bepaalt het percentage data dat een anomalie mag zijn. Deze parameter is nuttig wanneer alpha lastig af te stemmen is en je je wilt richten op de meest uitgesproken anomalieën.
purrr_package%>%
time_decompose(count)%>%
anomalize(remainder, alpha =0.2, max_anoms =0.2)%>%
time_recompose()%>%
plot_anomalies(time_recompose = T)+
ggtitle("20% anomaly Allowed")Mogelijk gemaakt door
purrr_package%>%
time_decompose(count)%>%
anomalize(remainder, alpha =0.2, max_anoms =0.05)%>%
time_recompose()%>%
plot_anomalies(time_recompose = T)+
ggtitle("5% anomaly Allowed")Mogelijk gemaakt door
Anomalize: korte beschrijving
Als we het over anomalieën hebben, bedoelen we datapunten die uitschieters zijn of een uitzonderlijke gebeurtenis vormen. Zulke gebeurtenissen identificeren is eenvoudig in kleine datasets en kan met simpele analysegrafieken zoals boxplots. Maar het wordt al snel ingewikkeld bij grote datasets, zeker bij tijdreeksen. Een tijdreeks is data die op vaste tijdsintervallen over een periode is vastgelegd en bij analyse een trend of seizoenspatroon laat zien. Het identificeren van anomalieën in zulke gevallen is best lastig.
Daarvoor is er het anomalize-pakket voor anomaliedetectie in tijdreeksanalyse. Het is een nette, op tijd gebaseerde anomaliedetectie-algoritme dat schaalbaar is van één tot veel tijdreeksen.
Er zijn verschillende beschikbare pakketten en methoden die bijdragen aan de werking, of je kunt zeggen dat het een combinatie is van bestaande bronnen met een schaalbare aanpak.
De open-sourceprojecten die hebben geholpen, zijn onder andere:
Deze pakketten en functies worden geïntegreerd in een schaalbare workflow.
De workflow van anomalize is opgedeeld in drie delen:
time_decompose().anomalize().time_recompose().Workflow van anomaliedetectie
Decompositie van tijdreeksen
De eerste stap is de tijdreeksdecompositie met time_decompose(). De gemeten of numerieke waarde waarop je voor een bepaalde groep wilt detecteren, wordt opgesplitst in vier kolommen: observed, season, trend en remainder. De standaardmethode voor decompositie is stl, een seizoensdecompositie met een Loess-smoother.
Loess-regressie is de meest gebruikte methode om een volatiele tijdreeks te vergladden. Er worden meerdere regressies gefit in de lokale buurt; je kunt ook zeggen dat de data wordt opgedeeld en dat op elk deel regressie wordt toegepast. Dat is nuttig bij tijdreeksen, omdat we de begrenzing in de tijd kennen, die hier de X-variabele is. Deze methode werkt goed wanneer de trend domineert over de seizoensinvloed van de tijdreeks.
Hier is trend de langetermijngroei die over veel observaties plaatsvindt, en seizoensinvloed het cyclische patroon dat optreedt op een dagelijkse cyclus per minuut of uur, of wekelijks.
Er is een tweede techniek voor seizoensdecompositie in tijdreeksen op basis van de mediaan: de
Twitter-methode, die ook wordt gebruikt in hetAnomalyDetection-pakket. Deze is identiek aan STL voor het verwijderen van de seizoenscomponent. Het verschil zit in het verwijderen van de trend: die gebruikt een stukgewijze mediaan van de data (één of meerdere medianen gesplitst op opgegeven intervallen) in plaats van een smoother te fitten. Deze methode werkt goed wanneer de seizoensinvloed domineert over de trend in de tijdreeks.Laten we het hebben over de output van de functie
time_decompose(). Zoals hierboven besproken produceert die 4 kolommen:De functie time_decompose() heeft een argument
merge. Door dit op TRUE te zetten, behoud je de originele data samen met de geproduceerde kolommen.Anomalieën in de remainders detecteren
Nadat de tijdreeksanalyse is voltooid en de remainder de gewenste eigenschappen heeft om anomalieën te detecteren, worden opnieuw drie nieuwe kolommen gemaakt.
Anomalieën zijn high-leveragepunten die de verdeling vertekenen. Anomalize implementeert twee methoden die bestand zijn tegen high-leveragepunten:
IQR
Dit is vergelijkbaar met de methode die in de functie tsoutliers() van het forecast-pakket wordt gebruikt. Bij IQR neem je een verdeling en gebruik je de 25%- en 75%-kwartielen om de verdeling van de remainder vast te stellen. De grenzen worden standaard ingesteld op een factor 3 keer boven en onder de interkwartielafstand; elke remainder buiten die grenzen wordt als anomalie beschouwd.
GESD
Bij GESD worden anomalieën stapsgewijs geëvalueerd door de grootste overtreders te verwijderen en de teststatistieken en kritieke waarden opnieuw te berekenen; eenvoudiger gezegd: het bereik wordt iteratief herberekend nadat anomalieën zijn geïdentificeerd.
Transformatie van onder- en bovengrens van anomalieën
De laatste stap van de workflow is het creëren van onder- en bovengrenzen rond de observed-waarden met
time_recompose. Daarbij worden season, trend, remainder_l1 en remainder_l2 opnieuw samengesteld tot nieuwe grenzen:Anomalieën plotten
Parameters afstemmen
Een anomaliedetector modelleren is niet compleet zonder de parameters te finetunen, die volledig afhankelijk zijn van de data.
Laten we de parameters afstellen. De parameters van elk niveau van de workflow verschillen, omdat elk niveau zijn eigen taak uitvoert.
Parameters van decompositie aanpassen
Zoals eerder besproken zijn trend en seizoensinvloed essentieel voor het decomponeren van een tijdreeks. Dus moet je ook de frequentie en trend van de functie
time_decomposeaanpassen. Standaard worden de waarden automatisch ingesteld: 7 dagen voor de frequentie in beide methoden (STL, Twitter) en voor de trend 91 dagen voor STL en 85 dagen voor Twitter.Je kunt beide of één van de argumenten naar wens tweaken, maar let goed op vóór je aanpast: wijzigen zonder observatie kan leiden tot overfitting of underfitting van het decompositieproces.
Parameters voor anomaliedetectie aanpassen
Zoals hierboven besproken wordt de anomalie hier bepaald op basis van de waarden van de remainder door grenzen te berekenen om uitschieters te categoriseren. De parameters alpha en max_anoms sturen de functie anomalize(). Simpel gezegd: alpha regelt de bandbreedte van de grens; standaard is die 0,05. Door de waarde te verlagen, vergroot je de band, waardoor het lastiger wordt voor een punt om als anomalie te gelden.
De parameter max_anom bepaalt het percentage data dat een anomalie mag zijn. Deze parameter is nuttig wanneer alpha lastig af te stemmen is en je je wilt richten op de meest uitgesproken anomalieën.
Referenties
Wil je meer leren over R? Volg dan DataCamp’s cursus Introduction to Time Series Analysis.
Bekijk ook onze Time Series Analysis using R: Tutorial.