Datenpunkte aus gleitendem Durchschnitt extrahieren?

15

Ist es möglich, Datenpunkte aus gleitenden Durchschnittsdaten zu extrahieren?

Mit anderen Worten, wenn ein Datensatz nur einfache gleitende Durchschnitte der vorherigen 30 Punkte enthält, ist es dann möglich, die ursprünglichen Datenpunkte zu extrahieren?

Wenn das so ist, wie?


quelle
1
Die Antwort ist ein qualifiziertes Ja, aber die genaue Vorgehensweise hängt davon ab, wie das anfängliche Datensegment behandelt wird. Wenn Sie es einfach fallen lassen, haben Sie effektiv 15 Daten verloren und haben ein unbestimmtes System linearer Gleichungen. Das Fazit ist, dass es im Allgemeinen viele gültige Antworten gibt, aber Sie können dennoch einige Fortschritte erzielen, wenn entweder (a) kürzere Fenster (oder ein solches Verfahren) für die ersten 15 gleitenden Durchschnitte verwendet werden oder (b) Sie zusätzliche Einschränkungen festlegen können die Lösung (etwa 15 Dimensionen im Wert von Einschränkungen ...). In welcher Situation bist du?
whuber
@whuber Vielen Dank für das Anschauen! Ich habe 2.000 Punkte. Der erste MA-Punkt ist höchstwahrscheinlich ein Durchschnitt der ersten 30 ursprünglichen Punkte. Die Genauigkeit ist an zweiter Stelle nach einem im Allgemeinen korrekten Ergebnis, insbesondere nach guten Schätzungen zu den "neuesten" Punkten. Können Sie eine relativ einfache Methode empfehlen? Danke im Voraus!
1
(Wenn Sie mehr als fünf Minuten brauchen, um einen Kommentar zu schreiben ...). Was ich schreiben wollte, ist, dass man sich die Mittelung als Matrixmultiplikation vorstellen kann. Die mittleren Zeilen haben 1/30 * [1 1 1 ...] vor der Diagonale. Die Frage ist, wie Sie mit Punkten an den Grenzen Ihres Vektors umgehen, um die Matrix invertierbar zu machen. Sie können dies tun, indem Sie davon ausgehen, dass sie das Ergebnis einer Durchschnittsbildung über weniger Elemente sind, oder wenn Sie über andere Einschränkungen nachdenken. Beachten Sie, dass eine Matrixinversion zwar ein einfacher Weg ist, sie jedoch nicht am effizientesten ist. Sie möchten wahrscheinlich eine FFT verwenden, um dies zu tun.
Fabee

Antworten:

4

+1 auf die Antwort von fabee, die vollständig ist. Nur eine Notiz, um es in R zu übersetzen, basierend auf den Paketen, die ich gefunden habe, um die Operationen zur Hand zu machen. In meinem Fall hatte ich Daten, bei denen es sich um NOAA-Temperaturvorhersagen für drei Monate handelt: Januar-Februar-März, Februar-März-April, März-April-Mai usw., und ich wollte sie in (ungefähre) Daten aufteilen. Monatswerte unter der Annahme, dass die Temperatur jedes Dreimonatszeitraums im Wesentlichen ein Durchschnitt ist.

library (Matrix)
library (matrixcalc)

# Feb-Mar-Apr through Nov-Dec-Jan temperature forecasts:

qtemps <- c(46.0, 56.4, 65.8, 73.4, 77.4, 76.2, 69.5, 60.1, 49.5, 41.2)

# Thus I need a 10x12 matrix, which is a band matrix but with the first
# and last rows removed so that each row contains 3 1's, for three months.
# Yeah, the as.matrix and all is a bit obfuscated, but the results of
# band are not what svd.inverse wants.

a <- as.matrix (band (matrix (1, nrow=12, ncol=12), -1, 1)[-c(1, 12),])
ai <- svd.inverse (a)

mtemps <- t(qtemps) %*% t(ai) * 3

Welches funktioniert gut für mich. Danke @fabee.

BEARBEITEN: OK, rückübersetzend mein R zu Python, erhalte ich:

from numpy import *
from numpy.linalg import *

qtemps = transpose ([[46.0, 56.4, 65.8, 73.4, 77.4, 76.2, 69.5, 60.1, 49.5, 41.2]])

a = tril (ones ((12, 12)), 2) - tril (ones ((12, 12)), -1)
a = a[0:10,:]

ai = pinv (a)

mtemps = dot (ai, qtemps) * 3

(Das Debuggen hat viel länger gedauert als die R-Version. Erstens, weil ich mit Python nicht so vertraut bin wie mit R, aber auch, weil R viel interaktiver nutzbar ist.)

Wayne
quelle
@Gracchus: Entschuldigung, kein C ++ - Typ, aber vielleicht finden Sie das, was Sie brauchen, in der linearen Algebra-Bibliothek von Armadillo C ++ ( arma.sourceforge.net ), die auch in R über das RcppArmadillo-Paket verfügbar ist.
Wayne
OK, sehen Sie, ob es bei Ihnen funktioniert. Wenn ja, können Sie meine Antwort auswählen ;-)
Wayne
FYI-Best Practices in Python bestehen darin, absolute Importe durchzuführen : python.org/dev/peps/pep-0008/#imports. Dies erleichtert das Lesen des Codes anderer Benutzer erheblich, da Sie tatsächlich wissen, woher die Funktionen kommen, anstatt sie zu müssen schau nach jedem, den du nicht kennst. Ich wünschte, es wäre Standard in R, dasselbe zu tun. Das Nachschlagen aller kleinen Funktionen im Code eines anderen macht mich
nervös
Jupyter-Notizbücher für Python-Interaktivität oder IPython.
wordsforhewise
17

Ich versuche, das Gesagte in eine Antwort zu fassen. Angenommen, Sie haben einen großen Vektor mit n = 2000 Einträgen. Wenn Sie einen gleitenden Durchschnitt mit einem Fenster der Länge = 30 berechnen , können Sie dies als Vektor-Matrix-Multiplikation y = A x des Vektors x mit der Matrix schreibenxn=2000=30y=Axx

A=130(1...10...001...10...0...1...100...01...1)

Das hat , die verschoben werden, während Sie durch die Reihen vorrücken, bis die 30 das Ende der Matrix erreichen. Hier hat der gemittelte Vektor y Dimensionen von 1970. Die Matrix hat 1970 Zeilen und 2000 Spalten. Daher ist es nicht umkehrbar.3030y19702000

x1,...,x2000y1y2 und so weiter.

x1,...,xnxyx

A3030AA

AAz=AyxyAz

2000x

reconstruction of original signal from moving average using the pseudoinverse

Viele numerische Programme bieten Pseudoinverse an (z. B. Matlab, Numpy in Python usw.).

Hier wäre der Python-Code, um die Signale aus meinem Beispiel zu generieren:

from numpy import *
from numpy.linalg import *
from matplotlib.pyplot import *
# get A and its inverse     
A = (tril(ones((2000,2000)),-1) - tril(ones((2000,2000)),-31))/30.
A = A[30:,:]
pA = pinv(A) #pseudo inverse

# get x
x = random.randn(2000) + 5
y = dot(A,x)

# reconstruct
x2 = dot(pA,y)

plot(x,label='original x')
plot(y,label='averaged x')
plot(x2,label='reconstructed x')
legend()
show()

Ich hoffe, das hilft.

Fabee
quelle
Dies ist eine großartige Antwort, aber ich denke, Sie irren sich, als Sie sagten, dass "es den quadratischen Abstand zwischen y und Az minimiert". Tatsächlich sind y und Az dasselbe. Was minimiert wird, ist die Norm von z, die gut für die Signale der realen Welt funktioniert, die ich ausprobiert habe, aber nicht so gut ist, wenn Ihr ursprüngliches Signal viele Ausreißer hat.
Gdelfino
Ich bin nicht sicher, ob ich folge. y und Axe sind dasselbe, aber nicht y und Az. Es ist wahr, dass es auch die Norm von z minimiert. Ich verstehe auch nicht, warum es bei meinen Beispielen nicht funktioniert. Die blaue und die rote Linie passen ziemlich gut zusammen. Vermisse ich etwas in deinem Kommentar?
Fabee
y ist der gleitende Durchschnitt, der aus dem ursprünglichen Signal x durch Multiplikation mit A berechnet wird. Diese Prozedur gibt uns ein Signal z, das den gleichen gleitenden Durchschnitt y hat. Also wird nur die Norm von z minimiert. Wenn das ursprüngliche Signal zufällig einen großen Normwert aufweist, liefert das Verfahren keine guten Ergebnisse. Ein Beispielsignal mit großem Normwert ist unten:
gdelfino
{42,8, -33,7, 13,2, -45,6, 10,2, 35,8, -41,4, 20,253, 43,3429, -33,2735, 13,6135, -45,1067, 10,6346, 36,1352, -40,9703, 20,6616, 43,6796, -32,8966, 14,0406, -44,7001, 10,99 , 36.4675, -40.7277, 20.8823, 43.7878, -32.7415, 13.9951, -44.7947, 11.044, 36.3873, -40.7117, 20.7505, 43.8204, -32.9399, 13.9129, -44.9549, 10.8703, 36.1559, -40.41.889 , 13.5468, -45.2374, 10.3787, 35.8235, -41.5161, 19.9717, 43.0658, -33.7125, 13.0321}
gdelfino
Bitte verwenden Sie eine Fenstergröße von 8 für das obige Signal. Auf diese Weise unterscheidet sich das gefilterte Signal stark von dem ursprünglichen Signal.
Gdelfino