Hareketli ortalamadan veri noktaları çıkarılsın mı?


15

Hareketli ortalama verilerden veri noktaları elde etmek mümkün müdür?

Başka bir deyişle, bir veri kümesi yalnızca önceki 30 noktanın basit hareketli ortalamalarına sahipse, orijinal veri noktalarını çıkarmak mümkün müdür?

Öyleyse nasıl?


1
Cevap nitelikli bir evettir, ancak kesin prosedür, ilk veri segmentinin nasıl işlendiğine bağlıdır. Basitçe düşürülürse, 15 adet veriyi etkili bir şekilde kaybettiniz ve sizi belirsiz bir lineer denklem sistemi ile bıraktınız. Sonuç olarak, genel olarak birçok geçerli cevap var, ancak (a) ilk 15 hareketli ortalama için daha kısa pencereler (veya bu tür bir prosedür) kullanılıyorsa veya (b) çözüm (yaklaşık 15 boyut sınırlaması ...). Hangi durumdasınız?
whuber

@whuber Baktığınız için çok teşekkür ederim! 2.000 puanım var. İlk MA noktası büyük olasılıkla ilk 30 orijinal noktanın ortalamasıdır. Doğruluk, genel olarak doğru bir sonuçtan sonra ikinci sıradadır, özellikle de en son "en iyi" noktalarda iyi tahminlerdir. Nispeten basit bir yöntem önerebilir misiniz? Şimdiden teşekkürler!

1
(Yorum yazmak için beş dakikadan fazla zaman ayırırsanız ...). Yazmak istediğim şey, ortalamayı bir matris çarpımı olarak düşünebilmeniz. Ortadaki satırlar diyagonalden 1/30 * [1 1 1 ...] olacaktır. Soru, matrisi tersine çevirmek için vektörünüzün sınırlarındaki noktalarla nasıl başa çıkacağınızdır. Bunu, daha az elemanın ortalamasının bir sonucu olduğunu varsayarak veya diğer kısıtlamaları düşündüğünüzde yapabilirsiniz. Bir matris inversiyonu onu anlamanın kolay bir yolu olsa da, en etkili olmadığını unutmayın. Muhtemelen bunu yapmak için bir FFT kullanmak istiyorsunuz.
fabee

Yanıtlar:


4

Fabee'nin cevabına +1, ki bu tamamlandı. Eldeki işlemleri yaparken bulduğum paketlere dayanarak onu R'ye çevirmek için bir not. Benim durumumda, üç aylık bazda NOAA sıcaklık tahminleri olan verilerim vardı: Ocak-Şubat-Mart, Şubat-Mart-Nisan, Mart-Nisan-Mayıs, vb. her üç aylık dönemin sıcaklığının esasen bir ortalama olduğunu varsayarsak, aylık değerler.

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

Bu benim için harika çalışıyor. Teşekkürler @fabee.

EDIT: Tamam, R benim Python için çeviri, ben:

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

(Bu, R sürümüne göre hata ayıklamak için çok daha uzun sürdü. Birincisi, R ile olduğu kadar Python'a aşina olmadığım için değil, R'nin etkileşimli olarak çok daha kullanışlı olması nedeniyle.)


@Gracchus: Üzgünüz, bir C ++ adam değil, ancak RcppArmadillo paketi aracılığıyla R'de bulunan Armadillo C ++ doğrusal cebir kütüphanesinde ( arma.sourceforge.net ) ihtiyacınız olanı bulabilirsiniz .
Wayne

Tamam, senin için işe yarayıp yaramadığına bak. Eğer öyleyse, cevabımı seçebilirsiniz ;-)
Wayne

Python'daki FYI'nin en iyi uygulamaları mutlak ithalatlar yapmaktır : python.org/dev/peps/pep-0008/#imports , diğer insanların kodlarını okumayı çok daha kolay hale getirir, çünkü aslında işlevlerin yerine yapmak yerine işlevlerin nereden geldiğini biliyorsunuz bilmediğin her birine bak. Aynı şeyi r standart olmasını isterdim. Başkasının kodundaki her küçük işlevi
aramak zorunda

Ayrıca, Python etkileşimi veya IPython için Jupyter dizüstü bilgisayarlar.
kelimeler

17

Whuber'ın söylediklerini bir cevaba koymaya çalışıyorum. Let Diyelim ki büyük bir vektör olduğunu varsayalım ile n = 2000 girdileri. Eğer uzunluk bir pencere ile bir hareketli ortalama hesaplaması = 30 , bir vektör matris çarpım olarak yazabilir y = A x vektörü x matrisi ilexn=2000=30y=Axx

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

hangi vardır kadar satır ile peşin olarak yoluyla kaydırılır olanları 30 olanlar matrisin sonuna çarptı. Burada ortalama y vektörü 1970 boyutlarına sahiptir. Matrisin 1970 satırı ve 2000 sütunu vardır. Bu nedenle, ters çevrilemez.3030y19702000

Matrislere aşina değilseniz, bunu doğrusal bir denklem sistemi olarak düşünün: değişkenlerini arıyorsunuz . . . , x 2000 , ilk otuz üzerindeki ortalama y 1 verirx1,...,x2000y1 , ikinci otuz üzerindeki ortalama veriry2 vb.

x1,...,xnxyx .

A3030AA

AAz=AyxyAz

2000x

reconstruction of original signal from moving average using the pseudoinverse

Birçok sayısal program sözde ters (ör. Matlab, pitonda numpy, vb.) Sunar.

İşte benim örnek sinyalleri oluşturmak için python kodu olurdu:

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

Umarım yardımcı olur.


Bu harika bir cevap, ama bence "y ve Az arasındaki ikinci dereceden mesafeyi en aza indirir" dediğinde yanılıyorsun. Aslında y ve Az aynı şeydir. En aza indirilmiş olan, denediğim gerçek dünya sinyalleri için iyi çalışan z normudur, ancak orijinal sinyalinizde birçok aykırı değer varsa o kadar iyi değildir.
gdelfino

Takip edip etmediğimden emin değilim. y ve Ax aynı şeydir, ancak y ve Az değil Z'nin normunu da en aza indirdiği doğrudur. Ayrıca örneklerim için neden işe yaramadığını da anlamıyorum. Mavi ve kırmızı çizgi oldukça iyi uyuyor. Yorumunuzda bir şey mi eksik?
fabee

y, orijinal sinyal x'ten A ile çarpılarak hesaplanan hareketli ortalamadır. Bu prosedür bize aynı hareketli ortalama y'ye sahip bir sinyal z verir. Bu nedenle y = Az Yani sadece z normu en aza indirilir. Orijinal sinyalin büyük bir norm değerine sahip olması durumunda, prosedür iyi sonuç vermeyecektir. Büyük norm değerine sahip bir örnek sinyal aşağıdadır:
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, -40.84, 20.44, 40.489 , 13.5468, -45.2374, 10.3787, 35.8235, -41.5161, 19.9717, 43.0658, -33.7125, 13.0321}
gdelfino

Lütfen yukarıdaki sinyal için 8 pencerelik bir pencere kullanın. Bu şekilde filtrelenen sinyal, orijinal sinyalden şekil olarak çok farklıdır.
gdelfino
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.