แยกจุดข้อมูลจากค่าเฉลี่ยเคลื่อนที่หรือไม่


15

เป็นไปได้หรือไม่ที่จะดึงจุดข้อมูลออกจากข้อมูลเฉลี่ยเคลื่อนที่?

กล่าวอีกนัยหนึ่งถ้าชุดข้อมูลมีค่าเฉลี่ยเคลื่อนที่อย่างง่ายจาก 30 คะแนนก่อนหน้าเป็นไปได้หรือไม่ที่จะแยกจุดข้อมูลดั้งเดิมออก

ถ้าเป็นเช่นนั้นได้อย่างไร


1
คำตอบคือใช่ที่ผ่านการรับรอง แต่ขั้นตอนที่แน่นอนนั้นขึ้นอยู่กับว่าส่วนแรกของข้อมูลถูกปฏิบัติอย่างไร ถ้ามันถูกทิ้งอย่างง่ายดายคุณจะสูญเสียข้อมูล 15 ชิ้นอย่างมีประสิทธิภาพทำให้คุณมีระบบสมการเชิงเส้นที่ไม่สิ้นสุด ผลที่สุดคือมีคำตอบที่ถูกต้องโดยทั่วไป แต่คุณยังสามารถดำเนินการบางอย่างได้หากใช้ (a) หน้าต่างที่สั้นกว่า (หรือบางกระบวนงาน) ใช้สำหรับค่าเฉลี่ยเคลื่อนที่ 15 เริ่มต้นหรือ (b) คุณสามารถระบุข้อ จำกัด เพิ่มเติมได้ วิธีแก้ปัญหา (ข้อ จำกัด ประมาณ 15 มิติ ... ) คุณอยู่ในสถานการณ์อะไร
whuber

@whuber ขอบคุณมากสำหรับการมอง! ฉันมี 2,000 คะแนน จุด MA แรกน่าจะเป็นค่าเฉลี่ยของคะแนนเดิม 30 คะแนนแรก ความแม่นยำเป็นสองรองจากผลลัพธ์ที่ถูกต้องโดยทั่วไปการคาดคะเนที่ดีที่สุดโดยเฉพาะในจุด "ล่าสุด" คุณช่วยแนะนำวิธีการที่ค่อนข้างง่ายได้ไหม? ขอบคุณล่วงหน้า!

1
(ถ้าคุณใช้เวลามากกว่าห้านาทีในการเขียนความคิดเห็น ... ) สิ่งที่ฉันต้องการเขียนคือคุณสามารถคิดว่าค่าเฉลี่ยเป็นการคูณเมทริกซ์ แถวที่อยู่ตรงกลางจะมี 1/30 * [1 1 1 ... ... ] หน้าเส้นทแยงมุม คำถามคือคุณจะจัดการกับจุดที่เส้นขอบของเวกเตอร์ของคุณอย่างไรเพื่อทำให้เมทริกซ์กลับด้านได้ คุณสามารถทำได้โดยสมมติว่าพวกมันเป็นผลมาจากค่าเฉลี่ยน้อยกว่าองค์ประกอบหรือคุณคิดว่ามีข้อ จำกัด อื่น ๆ โปรดทราบว่าในขณะที่เมทริกซ์ผกผันเป็นวิธีที่ง่ายต่อการเข้าใจ แต่ไม่มีประสิทธิภาพมากที่สุด คุณอาจต้องการใช้ FFT เพื่อทำเช่นนั้น
fabee

คำตอบ:


4

+1 ถึงคำตอบของ fabee ซึ่งเสร็จสมบูรณ์ เพิ่งทราบว่าจะแปลมันเป็น R ตามแพคเกจที่ฉันได้พบการดำเนินการที่อยู่ในมือ ในกรณีของฉันฉันมีข้อมูลที่เป็นการคาดการณ์อุณหภูมิของ NOAA เป็นเวลาสามเดือน: ม.ค. - ก.พ. - มี.ค. , ก.พ. - มี.ค. - เม.ย. , มี.ค. - เม.ย. - พฤษภาคมเป็นต้นและฉันต้องการแบ่งออกเป็น (โดยประมาณ) ค่ารายเดือนสมมติว่าอุณหภูมิของแต่ละงวดสามเดือนนั้นเป็นค่าเฉลี่ย

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

ซึ่งใช้งานได้ดีสำหรับฉัน ขอบคุณ @fabee

แก้ไข: ตกลงกลับแปล R ของฉันเป็น Python ฉันได้รับ:

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

(ซึ่งใช้เวลานานกว่าการดีบักมากกว่ารุ่น R อันดับแรกเพราะฉันไม่คุ้นเคยกับ Python เหมือนกับ R แต่ยังเป็นเพราะ R สามารถใช้งานได้แบบโต้ตอบมากขึ้น)


@Gracchus: ขออภัยไม่ใช่ผู้ชาย C ++ แต่คุณอาจพบสิ่งที่คุณต้องการในห้องสมุดพีชคณิตเชิงเส้น Armadillo C ++ ( arma.sourceforge.net ) ซึ่งมีอยู่ใน R ผ่านแพ็คเกจ RcppArmadillo ด้วย
เวย์น

ตกลงดูว่ามันเหมาะกับคุณไหม ถ้าเป็นเช่นนั้นคุณสามารถเลือกคำตอบของฉัน ;-)
Wayne

วิธีปฏิบัติที่ดีที่สุดของ FYI ใน Python คือการนำเข้าแบบสัมบูรณ์: python.org/dev/peps/pep-0008/#การนำเข้าซึ่งทำให้ง่ายต่อการอ่านรหัสของผู้อื่นมากขึ้นเพราะคุณรู้ว่าหน้าที่มาจากไหนแทนที่จะต้อง ค้นหาแต่ละคนที่คุณไม่รู้จัก หวังว่ามันจะเป็นมาตรฐานใน R ที่จะทำเช่นเดียวกัน ต้องค้นหาทุกฟังก์ชั่นเล็ก ๆ น้อย ๆ ในรหัสของคนอื่นบดเกียร์ของฉันจริงๆ ...
Wordsforthewise

นอกจากนี้สมุดบันทึก Jupyter สำหรับการโต้ตอบ Python หรือ IPython
Wordsforthewise

17

ฉันพยายามที่จะนำสิ่งที่คนพูดมาตอบคำถาม สมมุติว่าคุณมีเวกเตอร์ขนาดใหญ่มีn = 2000รายการ หากคุณคำนวณค่าเฉลี่ยเคลื่อนที่ด้วยหน้าต่างที่มีความยาว= 30คุณสามารถเขียนนี่เป็นการคูณเมทริกซ์เวกเตอร์y = A xของเวกเตอร์xกับเมทริกซ์xn=2000=30y=Axx

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

ซึ่งมีอันซึ่งถูกเลื่อนผ่านในขณะที่คุณเลื่อนไปตามแถวจนกว่าจะมี30อันที่จุดสิ้นสุดของเมทริก เวกเตอร์เฉลี่ยy ที่นี่มีขนาด 1970 เมทริกซ์มีแถว1970และคอลัมน์2000 ดังนั้นจึงไม่สามารถย้อนกลับได้3030y19702000

ถ้าคุณไม่คุ้นเคยกับการฝึกอบรมคิดเกี่ยวกับมันเป็นระบบสมการเชิงเส้น: คุณกำลังค้นหาสำหรับตัวแปรเช่นนั้นโดยเฉลี่ยในสามสิบแรกผลผลิตy 1 , โดยเฉลี่ยในช่วงสามสิบวินาทีที่สองให้ผลผลิตy 2เป็นต้นx1,...,x2000y1y2

x1,...,xnxyx

A3030AA

AAz=AyxyAz

2000x

การสร้างสัญญาณเดิมจากค่าเฉลี่ยเคลื่อนที่โดยใช้ pseudoinverse

โปรแกรมเชิงตัวเลขหลายตัวเสนอโปรแกรมหลอกผู้บุกรุก (เช่น Matlab, numpy ใน python และอื่น ๆ )

นี่คือรหัสหลามเพื่อสร้างสัญญาณจากตัวอย่างของฉัน:

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

หวังว่าจะช่วย


นี่เป็นคำตอบที่ดี แต่ฉันคิดว่าคุณเข้าใจผิดเมื่อคุณพูดว่า "มันลดระยะกำลังสองระหว่าง y และ Az" ในความเป็นจริง y และ Az เป็นสิ่งเดียวกัน สิ่งที่ถูกลดทอนลงคือบรรทัดฐานของ z ซึ่งทำงานได้ดีสำหรับสัญญาณในโลกแห่งความจริงที่ฉันได้ลอง แต่ไม่ดีนักถ้าสัญญาณดั้งเดิมของคุณมีค่าผิดปกติมากมาย
gdelfino

ฉันไม่แน่ใจว่าฉันทำตาม y และ Axe เป็นสิ่งเดียวกัน แต่ไม่ใช่ y และ Az มันเป็นความจริงที่ว่ามันจะลดบรรทัดฐานของ z ด้วย ฉันไม่เห็นด้วยว่าทำไมมันไม่ทำงานกับตัวอย่างของฉัน เส้นสีน้ำเงินและเส้นสีแดงนั้นเข้ากันได้ดีทีเดียว ฉันไม่มีอะไรในความคิดเห็นของคุณ?
fabee

y คือค่าเฉลี่ยเคลื่อนที่ที่คำนวณจากสัญญาณดั้งเดิม x โดยการคูณด้วย A ขั้นตอนนี้ให้สัญญาณ z ซึ่งมีค่าเฉลี่ยเคลื่อนที่ที่เหมือนกัน y ดังนั้น y = Az ดังนั้นบรรทัดฐานของ z จึงถูกย่อให้เล็กสุด หากสัญญาณดั้งเดิมมีค่าบรรทัดฐานขนาดใหญ่กระบวนการจะไม่ให้ผลลัพธ์ที่ดี สัญญาณตัวอย่างที่มีค่าบรรทัดฐานขนาดใหญ่อยู่ด้านล่าง:
gdelfino

{42.8, -33.7, 13.2, -45.6, 10.2, 35.8, -41.4, 20.33, 43.3429, -33.2735, 13.6135, -45.1067, 10.6346, 36.1352, -40.9703, 20.6616, 43.6796, -32.8966 , 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.953, , 13.5468, -45.2374, 10.3787, 35.8235, -41.5161, 19.9717, 43.0658, -33.7125, 13.0321}
gdelfino

โปรดใช้หน้าต่างขนาด 8 สำหรับสัญญาณด้านบน วิธีนี้สัญญาณที่กรองจะแตกต่างกันมากในรูปทรงจากสัญญาณดั้งเดิม
gdelfino
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.