Come posso trovare i picchi in un set di dati?


47

Se ho un set di dati che produce un grafico come il seguente, come potrei determinare algoritmicamente i valori x dei picchi mostrati (in questo caso tre di essi):

inserisci qui la descrizione dell'immagine


13
Vedo sei massimi locali. A quali tre ti riferisci? :-). (Ovviamente è ovvio - la spinta della mia osservazione è di incoraggiarti a definire un "picco" in modo più preciso, perché questa è la chiave per creare un buon algoritmo.)
whuber

3
Se i dati sono una serie temporale puramente periodica con aggiunta di qualche componente di rumore casuale, è possibile inserire una funzione di regressione armonica in cui il periodo e l'ampiezza sono parametri stimati dai dati. Il modello risultante sarebbe una funzione periodica che è liscia (cioè una funzione di alcuni seni e coseni) e quindi avrà punti temporali identificabili in modo univoco quando la prima derivata è zero e la seconda derivata è negativa. Quelle sarebbero le vette. I luoghi in cui la prima derivata è zero e la seconda derivata è positiva saranno quelli che chiamiamo trogoli.
Michael Chernick,

2
Ho aggiunto il tag mode, controlla alcune di queste domande, avranno risposte interessanti.
Andy W,

Grazie a tutti per le risposte e i commenti, è molto apprezzato! Mi ci vorrà del tempo per capire e implementare gli algoritmi suggeriti in relazione ai miei dati, ma mi assicurerò che aggiornerò in seguito con feedback.
assiomatico

Forse è perché i miei dati sono davvero rumorosi, ma non ho avuto successo con la risposta qui sotto. Tuttavia, ho avuto successo con questa risposta: stackoverflow.com/a/16350373/84873
Daniel

Risposte:


36

Un approccio generale consiste nel livellare i dati e quindi trovare i picchi confrontando un filtro massimo locale con il liscio . In 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)
}

Il suo valore di ritorno include gli argomenti del maxima locale ( x) - che risponde alla domanda - e gli indici nelle matrici x e y in cui si verificano quei massimi locali ( i).

Esistono due parametri da sintonizzare sulle circostanze: w è la mezza larghezza della finestra utilizzata per calcolare il massimo locale. (Il suo valore dovrebbe essere sostanzialmente inferiore alla metà della lunghezza dell'array di dati.) I valori piccoli rileveranno piccoli dossi locali mentre i valori più grandi passeranno proprio sopra quelli. Un altro - non esplicito in questo codice - è l' spanargomento del loesspiù fluido. (In genere è compreso tra zero e uno; riflette una larghezza della finestra come proporzione dell'intervallo di valori x). Valori più grandi uniformano i dati in modo più aggressivo, facendo scomparire del tutto i dossi locali.

Per rendere effettiva questa ottimizzazione, creiamo una piccola funzione di test per tracciare i risultati:

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)
}

Ecco alcuni esperimenti applicati ad alcuni dati sintetici, leggermente rumorosi.

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)

Terreni

Un'ampia finestra (trama centrale) o una levigatura più aggressiva (trama in basso) eliminano i massimi locali rilevati nella trama in alto. La migliore combinazione qui è probabilmente una finestra ampia e solo un livellamento delicato, poiché il livellamento aggressivo sembra spostare questi picchi (vedere i punti centrale e destro nella trama inferiore e confrontare le loro posizioni con i picchi apparenti dei dati grezzi). In questo esempio, w=50e span=0.05fa un grande lavoro (non mostrato).

Notare che i massimi locali agli endpoint non vengono rilevati. Questi possono essere ispezionati separatamente. (A supporto di ciò, argmaxrestituisce i valori y uniformi.)


Questo approccio presenta numerosi vantaggi rispetto alla modellazione più formale per il lavoro per scopi generali:

  • Non adotta alcun modello preconcetto dei dati.

  • Può essere adattato alle caratteristiche dei dati.

  • Può essere adattato per rilevare i tipi di picchi a cui è interessato.


3
Al contrario, @Michael: non presumo nulla sulla periodicità. In effetti, l'esempio sembra periodico ma non lo è: notate il termine quadratico. La regressione armonica fallirà con questo esempio (e con molte altre serie simili). Inoltre, non seleziono nulla "visivamente": tutto è fatto con l'algoritmo. (Perché ho la forte impressione che tu non abbia letto questa risposta?)
whuber

1
Riesco a trovare i picchi in modo algoritmico attraverso il primo e il secondo test dei derivati ​​mentre è necessario utilizzare altri mezzi (forse qualcosa come una ricerca numerica). Il mio punto non era quello di cercare di affermare che un approccio era migliore dell'altro, né criticavo la tua risposta. Vedo solo molte somiglianze e alcune differenze e stavo cercando di ottenere una comprensione più chiara di come si identificano i picchi.
Michael Chernick,

3
@Michael I picchi sono posizioni che non superano un massimo mobile; questo li rende veloci e facili da calcolare: non c'è ricerca numerica, solo una semplice scansione . Il vantaggio di usare un smooth differenziabile è che può interpolare picchi tra determinati valori x: questo è utile per risoluzioni x grossolane o irregolari. O(n)
whuber

4
@Michael, se non hai "tempo" per leggere una risposta / un commento, potresti considerare di astenermi dal rispondere / fare affermazioni sul post. Questo è qualcosa che hai fatto ripetutamente e spesso porta a scambi non costruttivi e / o fai dichiarazioni errate che ritiri in seguito. Sembra una perdita del tuo tempo e degli altri in cui conversi. Ad esempio, l'intero thread di commenti ha sicuramente impiegato più tempo della semplice lettura della risposta per cominciare. Il motivo per cui decidi di utilizzare il sito in questo modo continua a sconcertarmi. Non vedo come fa bene a nessuno.
Macro,

2
Grazie per l'approccio interessante. Penso di avere anche il punto su cui Michael stava raggiungendo: era necessario visualizzare i grafici per decidere i valori migliori per we span, e anche scoprire che valori più alti di spanstavano spostando i picchi. Sembra che anche questi passaggi possano essere automatizzati. Ad esempio per il primo numero, se potessimo valutare la qualità dei picchi scoperti, potremmo eseguire optimizei parametri! Per il secondo problema, ad es. Scegliere una finestra su entrambi i lati del picco scoperto e cercare valori più alti.
Darren Cook,

1

Come ho detto nel commento, se le serie temporali sembrano adattarsi periodicamente a un modello di regressione armonica offre un modo per rendere più liscia la funzione e identificare il picco applicando il primo e il secondo test derivativo. Huber ha sottolineato un test non parametrico che presenta vantaggi in presenza di più picchi e la funzione non è necessariamente periodica. Ma non c'è pranzo libero. Mentre ci sono i vantaggi del suo metodo che menziona, possono esserci degli svantaggi se un modello parametrico è appropriato. Questo è sempre il rovescio della medaglia nell'uso di tecniche non parametriche. Sebbene eviti ipotesi parametriche, l'approccio parametrico è migliore quando le assunzioni parametriche sono appropriate. Inoltre, la sua procedura non sfrutta appieno la struttura delle serie temporali nei dati.

Penso che sia opportuno sottolineare i vantaggi di una procedura suggerita, ma è anche importante sottolineare i potenziali svantaggi. Sia il mio approccio che quello di Huber trovano le vette in modo efficiente. Tuttavia, penso che la sua procedura richieda un po 'più di lavoro quando un massimo locale è inferiore al picco più alto precedentemente determinato.


2
Potresti per favore dimostrare la "maniera efficiente" del tuo approccio? Parte della sfida è ideare un algoritmo per trovare più picchi - che nel tuo caso significa trovare tutti gli zeri di una derivata (calcolata in modo costoso), non solo uno zero - ed essere espliciti su quale di questi punti critici classificherai come "picchi" e quali no. Inoltre, un supporto o un'amplificazione della tua affermazione secondo cui "l'approccio parametrico è migliore quando le assunzioni parametriche sono appropriate" sarebbe positivo, poiché, come tutti sappiamo, le assunzioni parametriche non sono mai esattamente corrette.
whuber

@whuber Ho detto che avresti adattato il modello quindi poiché il modle è una somma di seni e coseni la funzione è periodica i picchi si verificano quando sia la prima derivata è zero che la seconda derivata nel punto zero sta diminuendo. Questo è ciò che intendevo quando ho detto che fai il primo e il secondo test derivativo. Ora puoi risolvere per trovare tutte le soluzioni, ma se hai un picco gli altri sono un periodo e più periodi di distanza dalla soluzione che hai. Il mio punto non è rivendicare alcuna superiorità del metodo. Voglio solo sottolineare che non c'è pranzo libero.
Michael Chernick,

I metodi non parametrici hanno il vantaggio di non richiedere l'assunzione di modelli, in questo caso nessuna assunzione di periodicità. La mia affermazione sugli approcci parametrici migliore degli approcci non parametrici quando valgono le ipotesi di modellazione dovrebbe esservi molto familiare. Non ho bisogno di discutere su ipotesi parametriche che non valgono mai esattamente. Questa è un'opinione con cui sono sostanzialmente d'accordo. Ma sto parlando di qualcosa come l'efficienza di Pitman. Le stime non parametriche non sono efficienti quanto le stime parametriche quando il modello è "corretto".
Michael Chernick,

Questa è teoria. In pratica i modelli parametrici possono essere buone approssimazioni alla realtà. In tal caso la stima parametrica (diciamo mle) è più efficiente della stima non parametrica. Anche gli intervalli di confidenza parametrici saranno migliori perché saranno più stretti. Ma molte volte non sai quanto sia buono il modello parametrico per il tuo esempio. In questi casi devi decidere tra conservatorismo (essere al sicuro) con l'approccio non parametrico o essere audace (e possibilmente sbagliato) usando l'approccio parametrico.
Michael Chernick,

1
Quello che sto cercando di suggerire, Michael, è che in questo caso è probabile che l'approccio non parametrico sia di gran lunga migliore rispetto a qualsiasi approccio parametrico, tranne quando i dati si avvicinano in modo particolarmente stretto al modello, e anche in questo caso funzioneranno bene. Supponendo che la periodicità sia un ottimo esempio: il tuo algoritmo farà errori dello stesso ordine di grandezza delle deviazioni dalla periodicità all'interno dei dati. La possibilità di commettere tali errori annulla qualsiasi vantaggio conferito da una maggiore efficienza asintotica. Utilizzare una procedura del genere senza condurre prima test approfonditi sulla GoF sarebbe una cattiva idea.
whuber

1

Un classico approccio di rilevamento dei picchi nell'elaborazione del segnale è il seguente:

  1. Filtra il segnale in un intervallo ragionevole ragionevole, a seconda della frequenza di campionamento e delle proprietà del segnale, ad esempio per ECG, un filtro passa banda IIR a 0,5-20Hz, un filtro a fase zero assicurerà che non venga introdotto alcun cambiamento di fase (e relativo ritardo)
  2. Una trasformazione di Hilbert o un approccio wavelet possono quindi essere utilizzati per enfatizzare i picchi
  3. È quindi possibile applicare una soglia statica o dinamica, in cui tutti i campioni sopra la soglia sono considerati picchi. Nel caso di una soglia dinamica, di solito è definita come una deviazione standard della soglia N sopra o sotto una stima della media mobile della media.

Un altro approccio che funziona è quello di confrontare un segnale filtrato nettamente passa-alto con un segnale fortemente livellato (passa-basso o filtrato mediano) e applicare il passaggio 3.

Spero che sia di aiuto.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.