Jeśli mam zestaw danych, który tworzy wykres, taki jak poniżej, w jaki sposób algorytmicznie określiłbym wartości x pokazanych pików (w tym przypadku trzech z nich):
Jeśli mam zestaw danych, który tworzy wykres, taki jak poniżej, w jaki sposób algorytmicznie określiłbym wartości x pokazanych pików (w tym przypadku trzech z nich):
Odpowiedzi:
Ogólne podejście polega na wygładzeniu danych, a następnie znalezieniu pików poprzez porównanie lokalnego filtru maksymalnego z wygładzeniem . W R
:
argmax <- function(x, y, w=1, ...) {
require(zoo)
n <- length(y)
y.smooth <- loess(y ~ x, ...)$fitted
y.max <- rollapply(zoo(y.smooth), 2*w+1, max, align="center")
delta <- y.max - y.smooth[-c(1:w, n+1-1:w)]
i.max <- which(delta <= 0) + w
list(x=x[i.max], i=i.max, y.hat=y.smooth)
}
Zwracana wartość zawiera argumenty lokalnej maksima ( x
) - która odpowiada na pytanie - oraz indeksy do tablic x i y, w których występują te lokalne maksima ( i
).
Istnieją dwa parametry, które należy dostosować do okoliczności: w
jest to połowa szerokości okna używanego do obliczania lokalnego maksimum. (Jego wartość powinna być znacznie mniejsza niż połowa długości tablicy danych.) Małe wartości wychwycą małe lokalne nierówności, podczas gdy większe wartości przejdą nad nimi. Kolejnym - nieprecyzyjnym w tym kodzie - jest span
argument loess
wygładzacza. (Zazwyczaj ma wartość od zera do jednego; odzwierciedla szerokość okna jako proporcję zakresu wartości x.) Większe wartości wygładzą dane bardziej agresywnie, powodując całkowite zniknięcie lokalnych nierówności.
Aby zobaczyć, jak działa to strojenie, utwórzmy małą funkcję testową, aby wykreślić wyniki:
test <- function(w, span) {
peaks <- argmax(x, y, w=w, span=span)
plot(x, y, cex=0.75, col="Gray", main=paste("w = ", w, ", span = ", span, sep=""))
lines(x, peaks$y.hat, lwd=2) #$
y.min <- min(y)
sapply(peaks$i, function(i) lines(c(x[i],x[i]), c(y.min, peaks$y.hat[i]),
col="Red", lty=2))
points(x[peaks$i], peaks$y.hat[peaks$i], col="Red", pch=19, cex=1.25)
}
Oto kilka eksperymentów zastosowanych do niektórych syntetycznych, nieco zaszumionych danych.
x <- 1:1000 / 100 - 5
y <- exp(abs(x)/20) * sin(2 * x + (x/5)^2) + cos(10*x) / 5 + rnorm(length(x), sd=0.05)
par(mfrow=c(3,1))
test(2, 0.05)
test(30, 0.05)
test(2, 0.2)
Szerokie okno (środkowy wykres) lub bardziej agresywna gładka (dolny wykres) eliminuje lokalne maksima wykryte na górnym wykresie. Najlepszą kombinacją tutaj jest prawdopodobnie szerokie okno i tylko delikatne wygładzanie, ponieważ agresywne wygładzanie wydaje się przesuwać te szczyty (patrz środkowy i prawy punkt na dolnym wykresie i porównuj ich położenia z widocznymi szczytami surowych danych). W tym przykładzie w=50
i span=0.05
robi świetną robotę (nie pokazano).
Zauważ, że lokalne maksima w punktach końcowych nie są wykrywane. Można je sprawdzić osobno. (Aby to obsłużyć, argmax
zwraca wygładzone wartości y).
To podejście ma kilka zalet w porównaniu z bardziej formalnym modelowaniem do celów ogólnego zastosowania:
Nie przyjmuje żadnego z góry przyjętego modelu danych.
Można go dostosować do charakterystyki danych.
Można go dostosować do wykrywania rodzajów pików, które są zainteresowane.
w
i span
, a także dowiedzieć się, że wyższe wartości span
były przesunięcia pików. Wydaje się, że nawet te kroki można zautomatyzować. Np. W przypadku pierwszego wydania, jeśli moglibyśmy ocenić jakość wykrytych pików, moglibyśmy uruchomić optimize
parametry! W przypadku drugiego problemu, np. Wybierz okno po obu stronach odkrytego piku i poszukaj wyższych wartości.
Jak wspomniałem w komentarzu, jeśli szeregi czasowe wydają się okresowo dopasowywać, model regresji harmonicznej zapewnia sposób na wygładzenie funkcji i identyfikację piku poprzez zastosowanie testów pierwszej i drugiej pochodnej. Huber wskazał na test nieparametryczny, który ma zalety, gdy występuje wiele pików, a funkcja niekoniecznie jest okresowa. Ale nie ma darmowego lunchu. Chociaż jego metoda ma zalety, o których wspomina, mogą istnieć wady, jeśli model parametryczny jest odpowiedni. Jest to zawsze druga strona stosowania technik nieparametrycznych. Mimo że unika się założeń parametrycznych, podejście parametryczne jest lepsze, gdy założenia parametryczne są odpowiednie. Jego procedura nie wykorzystuje również w pełni struktury szeregów czasowych w danych.
Uważam, że chociaż wskazane są zalety sugerowanej procedury, ważne jest również wskazanie potencjalnych wad. Zarówno moje podejście, jak i Huber znajdują szczyty w efektywny sposób. Myślę jednak, że jego procedura wymaga nieco więcej pracy, gdy lokalne maksimum jest niższe niż wcześniej ustalony najwyższy szczyt.
Klasyczne podejście do wykrywania pików w przetwarzaniu sygnału jest następujące:
Innym podejściem, które działa, jest porównanie ostro filtrowanego sygnału górnoprzepustowego z silnie wygładzonym (filtr dolnoprzepustowy lub filtr mediany) i zastosowanie kroku 3.
Mam nadzieję że to pomoże.