Il semble que vous recherchiez des pointes dans des intervalles de calme relatif . "Relatif" signifie par rapport aux valeurs voisines typiques, ce qui suggère de lisser la série. Un lisse robuste est souhaitable précisément parce qu'il ne doit pas être influencé par quelques pointes locales. "Silencieux" signifie que la variation autour de cette douceur est faible. Encore une fois, une estimation robuste de la variation locale est souhaitable. Enfin, un «pic» serait un grand résidu en tant que multiple de la variation locale.
Pour mettre en œuvre cette recette , nous devons choisir (a) à quelle distance "proche" signifie, (b) une recette pour le lissage, et (c) une recette pour trouver la variation locale. Vous devrez peut-être expérimenter avec (a), alors faisons-en un paramètre facilement contrôlable. De bons choix facilement disponibles pour (b) et (c) sont respectivement Lowess et IQR . Voici une R
implémentation:
library(zoo) # For the local (moving window) IQR
f <- function(x, width=7) { # width = size of moving window in time steps
w <- width / length(x)
y <- lowess(x, f=w) # The smooth
r <- zoo(x - y$y) # Its residuals, structured for the next step
z <- rollapply(r, width, IQR) # The running estimate of variability
r/z # The diagnostic series: residuals scaled by IQRs
}
À titre d'exemple de son utilisation, considérons ces données simulées où deux pointes successives sont ajoutées à une période de silence (deux de suite devraient être plus difficiles à détecter qu'une seule pointe isolée):
> x <- c(rnorm(192, mean=0, sd=1), rnorm(96, mean=0, sd=0.1), rnorm(192, mean=0, sd=1))
> x[240:241] <- c(1,-1) # Add a local spike
> plot(x)
Voici l'intrigue diagnostique:
> u <- f(x)
> plot(u)
Malgré tout le bruit dans les données d'origine, ce tracé détecte magnifiquement les pointes (relativement petites) au centre. Automatisez la détection en balayant les f(x)
valeurs les plus grandes (supérieures à environ 5 en valeur absolue: expérimentez pour voir ce qui fonctionne le mieux avec les données d'échantillon).
> spikes <- u[abs(u) >= 5]
240 241 273
9.274959 -9.586756 6.319956
La détection parasite à l'instant 273 était une valeur aberrante locale aléatoire. Vous pouvez affiner le test pour exclure (la plupart) de telles valeurs parasites en modifiant f
pour rechercher simultanément des valeurs élevées du diagnostic r/z
et des valeurs faibles de l'IQR en cours d'exécution z
. Cependant, bien que le diagnostic ait une échelle et une interprétation universelles (sans unité), la signification d'un IQR «faible» dépend des unités des données et doit être déterminée par l'expérience.