Ekstrak poin data dari rata-rata bergerak?


15

Apakah mungkin untuk mengekstrak poin data dari data rata-rata bergerak?

Dengan kata lain, jika satu set data hanya memiliki rata-rata bergerak sederhana dari 30 poin sebelumnya, apakah mungkin untuk mengekstrak poin data asli?

Jika ya, bagaimana caranya?


1
Jawabannya adalah ya yang memenuhi syarat, tetapi prosedur yang tepat tergantung pada bagaimana segmen awal data diperlakukan. Jika dijatuhkan begitu saja, maka Anda telah secara efektif kehilangan 15 keping data, meninggalkan Anda dengan sistem persamaan linear yang tidak ditentukan. Hasilnya adalah bahwa ada banyak jawaban yang valid secara umum, tetapi Anda masih dapat membuat beberapa kemajuan jika (a) jendela yang lebih pendek (atau beberapa prosedur semacam itu) digunakan untuk 15 moving average awal atau (b) Anda dapat menentukan batasan tambahan pada solusinya (bernilai kendala sekitar 15 dimensi ...). Anda berada dalam situasi apa?
whuber

@whuber Terima kasih banyak telah melihat! Saya memiliki 2.000 poin. Poin MA pertama kemungkinan besar rata-rata dari 30 poin asli pertama. Akurasi adalah yang kedua dari hasil yang secara umum benar, terutama tebakan bagus pada titik "terkini" yang paling baru. Bisakah Anda merekomendasikan metode yang relatif sederhana? Terima kasih sebelumnya!

1
(jika Anda membutuhkan lebih dari lima menit untuk menulis komentar ...). Yang ingin saya tulis adalah Anda dapat menganggap rata-rata sebagai perkalian matriks. Baris di tengah akan memiliki 1/30 * [1 1 1 ...] sebelum diagonal. Pertanyaannya adalah, bagaimana Anda menangani titik di perbatasan vektor Anda untuk membuat matriks dapat dibalik. Anda dapat melakukan ini dengan mengasumsikan bahwa itu adalah hasil dari rata-rata lebih sedikit elemen atau Anda memikirkan kendala lain. Perhatikan bahwa sementara inversi matriks adalah cara mudah untuk memahaminya, itu bukan yang paling efisien. Anda mungkin ingin menggunakan FFT untuk melakukan itu.
Fabee

Jawaban:


4

+1 untuk jawaban fabee, yang lengkap. Hanya sebuah catatan untuk menerjemahkannya ke R, berdasarkan pada paket yang saya temukan untuk melakukan operasi. Dalam kasus saya, saya memiliki data yang merupakan prakiraan suhu NOAA berdasarkan tiga bulan: Jan-Feb-Mar, Feb-Mar-Apr, Mar-Apr-May, dll, dan saya ingin memecahnya menjadi (perkiraan) nilai bulanan, dengan asumsi bahwa setiap periode periode tiga bulan pada dasarnya adalah rata-rata.

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

Itu sangat bagus untuk saya. Terima kasih @fabee.

EDIT: OK, menerjemahkan kembali R saya ke Python, saya dapat:

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

(Yang membutuhkan waktu lebih lama untuk debug daripada versi R. Pertama karena saya tidak terbiasa dengan Python seperti dengan R, tetapi juga karena R jauh lebih dapat digunakan secara interaktif.)


@Gracchus: Maaf, bukan pria C ++, tetapi Anda dapat menemukan apa yang Anda butuhkan di perpustakaan aljabar linier Armadillo C ++ ( arma.sourceforge.net ), yang juga tersedia dalam R melalui paket RcppArmadillo.
Wayne

OK, lihat apakah itu bekerja untuk Anda. Jika demikian, Anda dapat memilih jawaban saya ;-)
Wayne

Praktik terbaik FYI di Python adalah melakukan impor absolut: python.org/dev/peps/pep-0008/#import yang membuatnya jauh lebih mudah untuk membaca kode orang lain, karena Anda benar-benar tahu dari mana fungsi itu berasal daripada harus cari setiap yang Anda tidak tahu. Berharap itu standar dalam R untuk melakukan hal yang sama. Harus mencari setiap fungsi kecil dalam kode orang lain benar-benar
menggeretakkan

Juga, notebook Jupyter untuk interaktivitas Python, atau IPython.
kata

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

reconstruction of original signal from moving average using the pseudoinverse

Banyak program numerik menawarkan pseudo-invers (mis. Matlab, numpy dengan python, dll.).

Ini akan menjadi kode python untuk menghasilkan sinyal dari contoh saya:

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

Semoga itu bisa membantu.


Ini adalah jawaban yang bagus, tetapi saya pikir Anda salah ketika Anda mengatakan bahwa "ini meminimalkan jarak kuadratik antara y dan Az". Sebenarnya y dan Az adalah hal yang sama. Yang diminimalkan adalah norma z yang bekerja dengan baik untuk sinyal dunia nyata yang telah saya coba, tetapi tidak begitu baik jika sinyal asli Anda memiliki banyak outlier.
gdelfino

Saya tidak yakin apakah saya mengikuti. y dan Ax adalah hal yang sama, tetapi bukan y dan Az Memang benar ia juga meminimalkan norma z. Saya juga tidak mengerti mengapa itu tidak berhasil untuk contoh saya. Garis biru dan merah cocok dengan sangat baik. Apakah saya melewatkan sesuatu dalam komentar Anda?
Fabee

y adalah moving average yang dihitung dari sinyal asli x dengan mengalikannya dengan A. Prosedur ini memberi kita sinyal z yang memiliki moving average yang sama y. Oleh karena itu y = Az Jadi hanya norma z yang diperkecil. Jika sinyal asli kebetulan memiliki nilai norma yang besar, maka prosedur tidak akan memberikan hasil yang baik. Contoh sinyal dengan nilai norma besar adalah di bawah ini:
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, -148.899 , 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, 43.248.848.848.848 , 13.5468, -45.2374, 10.3787, 35.8235, -41.5161, 19.9717, 43.0658, -33.7125, 13.0321}
gdelfino

Silakan gunakan ukuran windows 8 untuk sinyal di atas. Dengan cara ini sinyal yang disaring sangat berbeda bentuknya dari sinyal aslinya.
gdelfino
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.