(Ta odpowiedź stanowi odpowiedź na zduplikowane (teraz zamknięte) pytanie w Wykrywanie zaległych zdarzeń , które przedstawiało niektóre dane w formie graficznej.)
Wykrywanie wartości odstających zależy od charakteru danych i tego, co chcesz o nich założyć. Metody ogólnego zastosowania opierają się na solidnych statystykach. Ideą tego podejścia jest scharakteryzowanie dużej ilości danych w sposób, na który nie mają wpływu żadne wartości odstające, a następnie wskazanie dowolnych indywidualnych wartości, które nie mieszczą się w tej charakterystyce.
Ponieważ jest to szereg czasowy, komplikuje to konieczność (ponownego) wykrywania wartości odstających na bieżąco. Jeśli ma to być zrobione, gdy seria się rozwija, to wolno nam wykorzystywać tylko starsze dane do wykrywania, a nie przyszłe dane! Ponadto, jako ochronę przed wieloma powtarzanymi testami, chcielibyśmy zastosować metodę, która ma bardzo niski odsetek wyników fałszywie dodatnich.
Te rozważania sugerują przeprowadzenie prostego, niezawodnego testu danych odstających od ruchomego okna na danych . Istnieje wiele możliwości, ale jedna prosta, łatwa do zrozumienia i łatwa do wdrożenia oparta jest na działającym MAD: absolutna mediana odchylenia od mediany. Jest to bardzo solidna miara zmienności danych, podobna do odchylenia standardowego. Źródło nadmiernych szczyt będzie kilka Mads lub bardziej większy niż mediana.
R
x = ( 1 , 2 , … , n )n = 1150y
# Parameters to tune to the circumstances:
window <- 30
threshold <- 5
# An upper threshold ("ut") calculation based on the MAD:
library(zoo) # rollapply()
ut <- function(x) {m = median(x); median(x) + threshold * median(abs(x - m))}
z <- rollapply(zoo(y), window, ut, align="right")
z <- c(rep(z[1], window-1), z) # Use z[1] throughout the initial period
outliers <- y > z
# Graph the data, show the ut() cutoffs, and mark the outliers:
plot(x, y, type="l", lwd=2, col="#E00000", ylim=c(0, 20000))
lines(x, z, col="Gray")
points(x[outliers], y[outliers], pch=19)
Zastosowany do zestawu danych, takiego jak czerwona krzywa zilustrowana w pytaniu, daje następujący wynik:
Dane są pokazane na czerwono, 30-dniowe okno mediany + 5 * progów MAD na szaro, a wartości odstające - które są po prostu wartościami danych powyżej szarej krzywej - na czarno.
(Próg można obliczyć dopiero na końcu początkowego okna. Dla wszystkich danych w tym początkowym oknie stosuje się pierwszy próg: dlatego szara krzywa jest płaska między x = 0 a x = 30).
Skutkami zmiany parametrów są (a) zwiększenie wartości window
będzie miało tendencję do wygładzania szarej krzywej i (b) zwiększenie threshold
spowoduje podniesienie szarej krzywej. Wiedząc o tym, można wziąć początkowy segment danych i szybko zidentyfikować wartości parametrów, które najlepiej oddzielają odległe szczyty od reszty danych. Zastosuj te wartości parametrów, aby sprawdzić resztę danych. Jeśli wykres pokazuje, że metoda pogarsza się z czasem, oznacza to, że charakter danych się zmienia i parametry mogą wymagać ponownego dostrojenia.
Zauważ, jak mało ta metoda zakłada o danych: nie muszą one być normalnie dystrybuowane; nie muszą wykazywać żadnej częstotliwości; nie muszą nawet być nieujemne. Wszystko to zakłada się, że dane zachowują się w podobny sposób uzasadniony w czasie i że Dalekie szczyty są wyraźnie wyższe niż w pozostałej części danych.
Jeśli ktoś chciałby eksperymentować (lub porównać jakieś inne rozwiązanie z oferowanym tutaj), oto kod, którego użyłem do wygenerowania danych takich jak te pokazane w pytaniu.
n.length <- 1150
cycle.a <- 11
cycle.b <- 365/12
amp.a <- 800
amp.b <- 8000
set.seed(17)
x <- 1:n.length
baseline <- (1/2) * amp.a * (1 + sin(x * 2*pi / cycle.a)) * rgamma(n.length, 40, scale=1/40)
peaks <- rbinom(n.length, 1, exp(2*(-1 + sin(((1 + x/2)^(1/5) / (1 + n.length/2)^(1/5))*x * 2*pi / cycle.b))*cycle.b))
y <- peaks * rgamma(n.length, 20, scale=amp.b/20) + baseline