Domanda

Ho un valore continuo per cui vorrei calcolare una media mobile esponenziale . Normalmente userò solo la formula standard per questo:

  • S n = & # 945; Y + (1 - & # 945;) S n-1

dove S n è la nuova media, & # 945; è l'alfa, Y è il campione e S n-1 è la media precedente.

Sfortunatamente, a causa di vari problemi, non ho un tempo di campionamento costante. Potrei sapere che posso campionare al massimo, diciamo, una volta per millisecondo, ma a causa di fattori fuori dal mio controllo, potrei non essere in grado di prelevare un campione per diversi millisecondi alla volta. Un caso probabilmente più comune, tuttavia, è che ho semplicemente campionato un po 'in anticipo o in ritardo: invece di campionare a 0, 1 e 2 ms. Campione a 0, 0,9 e 2,1 ms. Prevedo che, indipendentemente dai ritardi, la mia frequenza di campionamento sarà molto, molto al di sopra del limite di Nyquist, e quindi non devo preoccuparmi dell'aliasing.

Ritengo di poterlo gestire in modo più o meno ragionevole variando opportunamente l'alfa, in base al periodo di tempo trascorso dall'ultimo campione.

Parte del mio ragionamento sul fatto che questo funzionerà è che l'EMA " interpola linearmente " tra il punto dati precedente e quello attuale. Se consideriamo il calcolo di un EMA del seguente elenco di campioni ad intervalli t: [0,1,2,3,4]. Dovremmo ottenere lo stesso risultato se utilizziamo l'intervallo 2t, dove gli input diventano [0,2,4], giusto? Se l'EMA avesse ipotizzato che, in t 2 il valore fosse stato 2 da t 0 , sarebbe lo stesso del calcolo dell'intervallo t calcolato su [0,2, 2,4,4], che non sta facendo. O ha senso?

Qualcuno può dirmi come variare l'alfa in modo appropriato? " Per favore, mostra il tuo lavoro. " Ad esempio, mostrami la matematica che dimostra che il tuo metodo sta davvero facendo la cosa giusta.

È stato utile?

Soluzione

Questa risposta si basa sulla mia buona comprensione dei filtri passa-basso (" media mobile esponenziale " è in realtà solo un filtro passa-basso unipolare), ma la mia comprensione nebulosa di ciò che stai cercando per. Penso che quanto segue sia ciò che desideri:

Innanzitutto, puoi semplificare un po 'la tua equazione (sembra più complicata ma è più facile nel codice). Userò & Quot; Y & Quot; per output e " X " per input (invece di S per output e Y per input, come hai fatto).

Y n = & # 945; X + (1 - & # 945;) Y n-1 & # 8594; Y n = Y n-1 + & # 945; (X - Y n-1 )

quali codici per:

 Y += alpha * (X-Y);

Secondo, il valore di & # 945; qui è " uguale a " a 1-e - & # 916; t / & # 964; dove & # 916; t è il tempo tra i campioni e & # 964; è la costante di tempo del filtro passa-basso. Dico & Quot; uguale a & Quot; tra virgolette perché funziona bene quando & # 916; t / & # 964; è piccolo rispetto a 1 e & # 945; = 1-e - & # 916; t / & # 964; & # 8776; & # 916; & T / # 964 ;. (Ma non troppo piccolo: ti imbatterai in problemi di quantizzazione e, a meno che non ricorra ad alcune tecniche esotiche, di solito hai bisogno di un ulteriore N bit di risoluzione nella variabile di stato S, dove N = -log 2 (& # 945;).) Per valori maggiori di & # 916; t / & # 964; l'effetto del filtro inizia a scomparire, fino ad arrivare al punto in cui & # 945; è vicino a 1 e in pratica stai semplicemente assegnando l'input all'output.

Questo dovrebbe funzionare correttamente con valori variabili di & # 916; t (la variazione di & # 916; t non è molto importante fintanto che l'alfa è piccola, altrimenti incontrerai alcuni piuttosto strani problemi di Nyquist / aliasing / ecc.) e se stai lavorando su un processore in cui la moltiplicazione è più economica della divisione, oppure i problemi a virgola fissa sono importanti, precalcola & # 969; = 1 / & # 964 ;, e considera di provare ad approssimare la formula per & # 945 ;.

Se vuoi davvero sapere come derivare la formula

&

# 945; = 1-e - & # 916; t / & # 964;

quindi considera la sua fonte di equazione differenziale:

Y + & # 964; dY / dt = X

che, quando X è una funzione di passo unitario, ha la soluzione Y = 1 - e -t / & # 964; . Per piccoli valori di & # 916; t, la derivata può essere approssimata di & # 916; Y / & # 916; t, resa

Y + & # 964; & # 916; Y / & # 916; t = X

& # 916; Y / & # 916; t = (X-Y) / & # 964;

& # 916; Y = (X-Y) (& # 916; t / & # 964;) = & # 945; (X-Y)

e " estrapolazione " di & # 945; = 1-e - & # 916; t / & # 964; proviene dal tentativo di far corrispondere il comportamento con il caso della funzione di passaggio unità.

Altri suggerimenti

Dai un'occhiata qui: http://www.eckner.com/research.html

Guarda il secondo link: " " Algoritmi per serie temporali con spaziatura irregolare: medie mobili e altri operatori a rotazione "

Il documento descrive esattamente gli algoritmi di programmazione necessari, credo.

Questa non è una risposta completa, ma potrebbe essere l'inizio di una. È quanto mi è arrivato in circa un'ora di gioco; Lo sto pubblicando come esempio di ciò che sto cercando, e forse come fonte d'ispirazione per altri che stanno lavorando al problema.

Comincio con S 0 , che è la media risultante dalla media precedente S -1 e il campione Y 0 preso a t 0 . (t 1 - t 0 ) è il mio intervallo di campionamento e & # 945; è impostato su ciò che è appropriato per quell'intervallo di campionamento e il periodo in cui desidero fare la media.

Ho considerato cosa succede se mi manca il campione in t 1 e invece devo accontentarmi del campione Y 2 preso in t 2 ? Bene, possiamo iniziare espandendo l'equazione per vedere cosa sarebbe successo se avessimo avuto Y 1 :

  • S 2 = & # 945; Y 2 + (1 - & # 945;) S 1 , dove S 1 = & # 945; Y 1 + (1 - & # 945;) S 0

Sostituendo:

  • S 2 = & # 945; Y 2 + (1 - & # 945;) (& # 945; Y 1 + (1 - & # 945;) S 0 )
  • S 2 = & # 945; Y 2 + (1 - & # 945;) & # 945; Y 1 + (1 - & # 945;) (1 - & # 945;) S 0
  • S 2 = & # 945; Y 2 + (1 - & # 945;) & # 945; Y 1 + (1 - & # 945;) 2 S 0

Ho notato che la serie sembra estendersi all'infinito in questo modo, perché possiamo sostituire indefinitamente S n nella parte destra:

  • S 2 = & # 945; Y 2 + (1 - & # 945;) & # 945; Y 1 + (1 - & # 945;) 2 (& # 945; Y 0 + (1 - & # 945;) S -1 )
  • S 2 = & # 945; Y 2 + (1 - & # 945;) & # 945; Y 1 + (1 - & # 945;) 2 & # 945; Y 0 + (1 - & # 945;) < sup> 3 S -1
  • ecc.

Ok, quindi non è proprio un polinomio (sciocco me), ma se moltiplichiamo il termine iniziale per uno, vedremo uno schema:

  • S 2 = (1 - & # 945;) 0 & # 945; Y 2 + (1- & # 945;) & # 945; Y 1 + (1 - & # 945;) 2 & # 945; Y 0 + (1 - & # 945;) 3 S -1

Hm: è una serie esponenziale. Sorpresa di Quelle! Immagina che uscire dall'equazione per una media mobile esponenziale!

Quindi, ho questo x 0 + x 1 + x 2 + x 3 +. .. cosa sta succedendo, e sono sicuro che sto annusando e o un logaritmo naturale che calcia da queste parti, ma non ricordo dove stavo andando prima che finissi il tempo.

Qualsiasi risposta a questa domanda o qualsiasi prova di correttezza di tale risposta dipende fortemente dai dati che stai misurando.

Se i tuoi campioni sono stati prelevati in t 0 = 0ms, t 1 = 0.9ms et 2 = 2.1ms, ma la tua scelta di & # 945; si basa su intervalli di 1 ms e pertanto si desidera un & # 945 adattato localmente; n , la prova della correttezza della scelta significherebbe conoscere i valori del campione in t = 1ms et = 2ms.

Questo porta alla domanda: puoi interpolare i tuoi dati in modo risonabile per avere ipotesi sane di quali valori intermedi potrebbero essere stati? O puoi anche interpolare la media stessa?

Se nessuno di questi è possibile, quindi per quanto lo vedo, la scelta logica di un valore intermedio Y (t) è la media calcolata più di recente , ovvero Y (t) & # 8776; S n dove n è maxmial tale che t n & Lt; t.

Questa scelta ha una semplice conseguenza: lasciare & # 945; da solo, indipendentemente dalla differenza oraria.

Se, d'altra parte, è possibile interpolare i tuoi valori, allora questo ti darà campioni di intervallo costante media. Infine, se è persino possibile interpolare la media stessa, ciò renderebbe la domanda insignificante.

Usando un & # 945 leggermente diverso; che è uguale a (1 - & # 945; quello della domanda ), la formula di base per aggiungere un nuovo valore Y a una media esistente di S 0 assomiglia a questo:

  

S (Y, S 0 ) =

     

(1 - & # 945;) Y + & # 945; S 0 =

     

Y - & # 945; Y + & # 945; S 0 =

     

Y + & # 945; (S 0 -Y)

Se ora aggiungiamo la lunghezza dell'intervallo di tempo t e supponiamo che solo & # 945; dipende da quella t, quella formula è simile alla seguente:

  

S (Y, t, S 0 ) = Y + & # 945; t (S 0 -Y)

Ora supponiamo che t = t 1 + t 2 . Se la media viene creata aggiungendo due valori di Y per gli intervalli di tempo t 1 e t 2 , la media risultante è simile alla seguente:

  

S (Y, t 2 , S (Y, t 1 , S 0 )) =

     

Y + αt2 (S (Y, t 1 , S 0 ) - Y) =

     

Y + αt2 ((Y + & # 945; t 1 (S 0 -Y)) - Y) =

     

Y + αt2αt1 ( S 0 Y)

Se questa media dovrebbe essere la stessa di se l'intero intervallo t fosse stato aggiunto contemporaneamente, ne consegue che & # 945; t = & # 945; t 1 # 945 &; t 2 . Una definizione di & # 945; che soddisfa questo requisito sarebbe:

  

& # 945; x : = A x & nbsp; & nbsp; & nbsp; & nbsp; (per una costante A)

A causa:

  

& # 945; t = A t =   A t 1 + t 2 =   A t 1 A t 2 =   # 945 &; t 1 # 945 &; t 2

Ciò comporta la seguente funzione di media:

  

S (Y, t, S 0 ) = Y + A t (S 0 -Y)

Non l'ho davvero testato, ma se le ipotesi che ho adattato al tuo scenario sembrano una funzione di media in grado di gestire abbastanza bene le variazioni negli intervalli di campionamento.

Diciamo che vorremmo fare una media esponenziale in decomposizione su una funzione continua. Tuttavia non abbiamo tutti i valori di quella funzione, solo alcuni esempi. Questa formula farebbe una media ponderata dei campioni che abbiamo con i pesi che avrebbero nella media continua.

Moltiplicatore n = Alpha Time n -Time n-1

Sum n = Val n + Sum n-1 * Moltiplicatore n

Count n = 1 + Count n-1 * Moltiplicatore n

Avg n = Sum n / Count n

Lascerei da solo il valore alpha e riempirei i dati mancanti.

Dato che non sai cosa succede durante il periodo in cui non puoi campionare, puoi riempire quei campioni con 0 o mantenere stabile il valore precedente e usare quei valori per l'EMA. O qualche interpolazione all'indietro una volta che hai un nuovo campione, inserisci i valori mancanti e ricalcola l'EMA.

Quello che sto cercando di ottenere è che hai un input x[n] che ha buchi. Non è possibile aggirare il fatto che mancano dei dati. Quindi è possibile utilizzare un blocco dell'ordine zero o impostarlo su zero o una sorta di interpolazione tra x[n+M] e M, dove n è il numero di campioni mancanti e all'inizio del gap. Forse anche usando valori precedenti a <=>.

Questo è simile a un problema aperto nella mia lista di cose da fare. Ho un piano elaborato in una certa misura, ma non ho ancora un lavoro matematico per sostenere questo suggerimento.

Aggiorna & amp; riepilogo: vorrei mantenere il fattore di livellamento (alfa) indipendente dal fattore di compensazione (che qui definisco beta). L'eccellente risposta di Jason già accettata qui funziona alla grande per me.

Primo passo.

  • Se puoi anche misurare il tempo trascorso dall'ultimo campione (in multipli arrotondati del tempo di campionamento costante, quindi 7,8 ms dall'ultimo campione sarebbe di 8 unità), che potrebbe essere utilizzato per applicare il livellamento più volte. Applicare la formula 8 volte in questo caso. Hai effettivamente reso un livellamento più orientato verso il valore corrente.

Secondo passaggio.

  • Per ottenere un migliore livellamento, è necessario modificare l'alfa mentre si applica la formula 8 volte nel caso precedente.

Che cosa mancherà a questa approssimazione levigante?

  • Ha già perso 7 campioni nell'esempio sopra
  • Questo è stato approssimato nel passaggio 1 con una appiattita nuova applicazione del valore corrente altre 7 volte
  • Se definiamo un fattore di approssimazione beta che verrà applicato insieme a alfa (come alfa * beta anziché solo alfa), assumeremo che i 7 abbiano perso i campioni stavano cambiando senza intoppi tra i valori del campione attuali e precedenti.
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top