Wyodrębnić punkty danych z ruchomej średniej?

15

Czy można wyodrębnić punkty danych z ruchomych danych średnich?

Innymi słowy, jeśli zestaw danych zawiera tylko proste średnie ruchome z poprzednich 30 punktów, czy można wyodrębnić oryginalne punkty danych?

Jeśli tak to jak?


źródło
1
Odpowiedź brzmi „tak”, ale dokładna procedura zależy od tego, jak traktowany jest początkowy segment danych. Jeśli zostanie po prostu upuszczony, oznacza to, że skutecznie straciłeś 15 części danych, pozostawiając nieokreślony układ równań liniowych. Konsekwencją jest to, że istnieje wiele prawidłowych odpowiedzi, ale nadal możesz poczynić pewne postępy, jeśli (a) krótsze okna (lub niektóre takie procedury) zostaną zastosowane dla początkowych 15 średnich kroczących lub (b) możesz określić dodatkowe ograniczenia rozwiązanie (ograniczenia o wartości około 15 wymiarów ...). W jakiej jesteś sytuacji?
whuber
@whuber Dziękuję bardzo za opiekę! Mam 2000 punktów. Pierwszy punkt MA jest najprawdopodobniej średnią z pierwszych 30 oryginalnych punktów. Dokładność jest drugim po generalnie poprawnym wyniku, szczególnie trafnym zgadywaniem w „ostatnich” punktach. Czy możesz polecić stosunkowo prostą metodę? Z góry dziękuję!
1
(jeśli poświęcisz więcej niż pięć minut na napisanie komentarza ...). Chciałem napisać, że uśrednianie można traktować jako mnożenie macierzy. Rzędy pośrodku będą miały 1/30 * [1 1 1 ...] przed przekątną. Pytanie brzmi: jak radzić sobie z punktami na granicach wektora, aby matryca była odwracalna. Możesz to zrobić, zakładając, że są one wynikiem uśrednienia mniejszej liczby elementów lub myślisz o innych ograniczeniach. Zauważ, że chociaż odwrócenie macierzy jest łatwym sposobem na zrozumienie tego, nie jest najbardziej wydajne. Prawdopodobnie chcesz do tego użyć FFT.
fabee

Odpowiedzi:

4

+1 do odpowiedzi fabee, która jest kompletna. Tylko uwaga, aby przetłumaczyć go na język R, w oparciu o pakiety, które znalazłem do wykonania dostępnych operacji. W moim przypadku miałem dane, które są prognozami temperatury NOAA na trzy miesiące: styczeń-luty-marzec, luty-marzec-kwiecień, marzec-kwiecień-maj itd. I chciałem je rozbić na (przybliżone) wartości miesięczne, przy założeniu, że temperatura każdego trzymiesięcznego okresu jest zasadniczo średnią.

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

Który działa dla mnie świetnie. Dzięki @fabee.

EDYCJA: OK, tłumacząc wstecz moje R na Python, otrzymuję:

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

(Debugowanie trwało dłużej niż wersja R. Po pierwsze dlatego, że nie znam tak dobrze Pythona jak z R, ale także dlatego, że R jest znacznie bardziej użyteczny interaktywnie.)

Wayne
źródło
@Gracchus: Niestety, nie jestem facetem z C ++, ale możesz znaleźć to, czego potrzebujesz w bibliotece algebry liniowej Armadillo C ++ ( arma.sourceforge.net ), która jest również dostępna w R za pośrednictwem pakietu RcppArmadillo.
Wayne,
OK, sprawdź, czy to działa dla Ciebie. Jeśli tak, możesz wybrać moją odpowiedź ;-)
Wayne
Najlepszą praktyką FYI w Pythonie jest importowanie absolutne: python.org/dev/peps/pep-0008/#imports, co znacznie ułatwia odczytywanie kodu innych osób, ponieważ tak naprawdę wiesz, skąd pochodzą funkcje, zamiast konieczności sprawdź każdego, którego nie znasz. Szkoda, że ​​nie było standardem w R, aby zrobić to samo.
Konieczność
Ponadto notesy Jupyter do interaktywności w języku Python lub IPython.
słowa
17

xn=2000=30y=Axx

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

3030y19702000

x1,...,x2000y1y2

x1,...,xnxyx

A3030AA

AAz=AyxyAz

2000x

rekonstrukcja oryginalnego sygnału z ruchomej średniej za pomocą pseudoinwersji

Wiele programów numerycznych oferuje pseudo-inwersje (np. Matlab, numpy w python itp.).

Oto kod python do generowania sygnałów z mojego przykładu:

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

Mam nadzieję, że to pomaga.

fabee
źródło
To świetna odpowiedź, ale myślę, że się mylisz, kiedy powiedziałeś, że „minimalizuje kwadratową odległość między y a Az”. W rzeczywistości y i Az są tym samym. Zminimalizowana jest norma z, która działa dobrze dla sygnałów z prawdziwego świata, których próbowałem, ale nie jest tak dobra, jeśli twój oryginalny sygnał ma wiele wartości odstających.
gdelfino
Nie jestem pewien, czy podążam. y i Axe są tym samym, ale nie y i Az To prawda, że ​​minimalizuje również normę z. Nie rozumiem też, dlaczego to nie działa w moich przykładach. Niebieska i czerwona linia ładnie do siebie pasują. Czy brakuje mi czegoś w twoim komentarzu?
fabee
y jest średnią ruchomą obliczoną na podstawie oryginalnego sygnału x przez pomnożenie przez A. Ta procedura daje nam sygnał z, który ma tę samą średnią ruchomą y. Dlatego y = Az Tak więc tylko norma z zostaje zminimalizowana. Jeśli oryginalny sygnał ma dużą wartość normalną, procedura nie da dobrych wyników. Przykładowy sygnał o dużej wartości normalnej znajduje się poniżej:
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.9988 , 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, -49.889.44, 498,8944,409,498,8944,464,488,894,40 , 13.5468, -45.2374, 10.3787, 35.8235, -41.5161, 19.9717, 43.0658, -33.7125, 13.0321}
gdelfino
Dla powyższego sygnału użyj okna o rozmiarze 8. W ten sposób filtrowany sygnał ma bardzo różny kształt od sygnału oryginalnego.
gdelfino