พอดีกับคำที่ใช้ในข้อมูล


26

แม้ว่าฉันจะอ่านโพสต์นี้ฉันก็ยังไม่รู้ว่าจะใช้กับข้อมูลของฉันอย่างไรและหวังว่าจะมีคนช่วยฉันได้

ฉันมีข้อมูลต่อไปนี้:

y <- c(11.622967, 12.006081, 11.760928, 12.246830, 12.052126, 12.346154, 12.039262, 12.362163, 12.009269, 11.260743, 10.950483, 10.522091,  9.346292,  7.014578,  6.981853,  7.197708,  7.035624,  6.785289, 7.134426,  8.338514,  8.723832, 10.276473, 10.602792, 11.031908, 11.364901, 11.687638, 11.947783, 12.228909, 11.918379, 12.343574, 12.046851, 12.316508, 12.147746, 12.136446, 11.744371,  8.317413, 8.790837, 10.139807,  7.019035,  7.541484,  7.199672,  9.090377,  7.532161,  8.156842,  9.329572, 9.991522, 10.036448, 10.797905)
t <- 18:65

และตอนนี้ฉันแค่ต้องการให้พอดีกับคลื่นไซน์

y(t)=Asin(ωt+ϕ)+C.

กับสี่ราชวงศ์, ,และไปω ϕ CAωϕC

ส่วนที่เหลือของรหัสของฉันมีลักษณะดังต่อไปนี้

res <- nls(y ~ A*sin(omega*t+phi)+C, data=data.frame(t,y), start=list(A=1,omega=1,phi=1,C=1))
co <- coef(res)

fit <- function(x, a, b, c, d) {a*sin(b*x+c)+d}

# Plot result
plot(x=t, y=y)
curve(fit(x, a=co["A"], b=co["omega"], c=co["phi"], d=co["C"]), add=TRUE ,lwd=2, col="steelblue")

แต่ผลลัพธ์นั้นแย่จริงๆ

ไซน์พอดี

ฉันจะขอบคุณมากสำหรับความช่วยเหลือใด ๆ

ไชโย


คุณกำลังพยายามปรับคลื่นไซน์ให้พอดีกับข้อมูลหรือคุณกำลังพยายามทำให้พอดีกับโมเดลฮาร์มอนิกบางชนิดที่มีไซน์และองค์ประกอบโคไซน์หรือไม่? มีฟังก์ชั่นฮาร์โมนิกในแพ็คเกจ TSA ใน R ที่คุณอาจต้องการเช็คเอาท์ พอดีกับโมเดลของคุณโดยใช้สิ่งนั้นและดูผลลัพธ์ที่คุณได้รับ
Eric Peterson

5
คุณลองใช้ค่าเริ่มต้นที่แตกต่างกันหรือไม่? ฟังก์ชันการสูญเสียของคุณไม่ใช่แบบนูนดังนั้นค่าเริ่มต้นที่แตกต่างกันอาจนำไปสู่การแก้ปัญหาที่แตกต่างกัน
Stefan Wager

1
บอกเราเพิ่มเติมเกี่ยวกับข้อมูล มักจะมีช่วงเวลาที่รู้จักกันดังนั้นจึงไม่จำเป็นต้องมีการประเมินจากข้อมูล นี่เป็นอนุกรมเวลาหรืออย่างอื่นใช่ไหม มันง่ายกว่ามากถ้าคุณสามารถแยกคำไซน์และโคไซน์แยกจากกันโดยใช้โมเดลเชิงเส้น
Nick Cox

2
การมีช่วงเวลาที่ไม่รู้จักทำให้โมเดลของคุณไม่เป็นเชิงเส้น (เหตุการณ์ดังกล่าวถูกพูดถึงในคำตอบที่เลือกที่โพสต์ที่เชื่อมโยง) ที่ระบุว่าพารามิเตอร์อื่น ๆ เป็นเชิงเส้นแบบมีเงื่อนไข สำหรับกิจวัตร LS ที่ไม่เชิงเส้นบางอย่างที่ข้อมูลมีความสำคัญและสามารถปรับปรุงพฤติกรรมได้ ทางเลือกหนึ่งอาจจะใช้วิธีการทางสเปกตรัมเพื่อรับช่วงเวลาและเงื่อนไขในนั้น อีกประการหนึ่งคือการปรับปรุงช่วงเวลาและพารามิเตอร์อื่น ๆ ผ่านการปรับให้เหมาะสมแบบไม่เชิงเส้นและเชิงเส้นตามลำดับในแบบวนซ้ำ
Glen_b -Reinstate Monica

(ฉันเพิ่งแก้ไขคำตอบที่นั่นเพื่อทำให้กรณีที่ไม่ทราบระยะเวลาเป็นตัวอย่างที่ชัดเจนของสิ่งที่สามารถทำให้มันไม่เป็นเชิงเส้น)
Glen_b

คำตอบ:


18

ถ้าคุณเพียงต้องการประมาณการที่ดีของและไม่สนใจมากเกี่ยวกับข้อผิดพลาดมาตรฐานของ:ω

ssp <- spectrum(y)  
per <- 1/ssp$freq[ssp$spec==max(ssp$spec)]
reslm <- lm(y ~ sin(2*pi/per*t)+cos(2*pi/per*t))
summary(reslm)

rg <- diff(range(y))
plot(y~t,ylim=c(min(y)-0.1*rg,max(y)+0.1*rg))
lines(fitted(reslm)~t,col=4,lty=2)   # dashed blue line is sin fit

# including 2nd harmonic really improves the fit
reslm2 <- lm(y ~ sin(2*pi/per*t)+cos(2*pi/per*t)+sin(4*pi/per*t)+cos(4*pi/per*t))
summary(reslm2)
lines(fitted(reslm2)~t,col=3)    # solid green line is periodic with second harmonic

พล็อตไซน์

(ความพอดีที่ดีกว่านี้อาจจะเป็นสาเหตุของค่าผิดปกติในซีรีส์ในบางวิธีลดอิทธิพลของพวกเขา)

---

หากคุณต้องการความคิดเกี่ยวกับความไม่แน่นอนในคุณสามารถใช้ความน่าจะเป็นของโปรไฟล์ ( pdf1 , pdf2 - การอ้างอิงเกี่ยวกับการรับ CIs หรือ SEs โดยประมาณจากความน่าจะเป็นของโปรไฟล์หรือตัวแปรไม่ได้หายาก)ω

(อีกวิธีหนึ่งคุณสามารถป้อนค่าประมาณเหล่านี้เป็น nls ... และเริ่มรวมเข้าด้วยกันแล้ว)


(+1) คำตอบที่ดี ฉันพยายามให้พอดีกับโมเดลเชิงเส้นด้วยlm(y~sin(2*pi*t)+cos(2*pi*t)แต่มันไม่ได้ผล ( cosเทอมคือ 1 เสมอ) เพิ่งอยากรู้อยากเห็น: สองบรรทัดแรกทำอะไร (ฉันรู้ว่าspectrumประมาณความหนาแน่นสเปกตรัม)
COOLSerdash

1
t2*pi*t

1
@COOLSerdash (ctd) - บรรทัดที่ 2 ค้นหาความถี่ที่เกี่ยวข้องกับจุดสูงสุดที่ใหญ่ที่สุดในสเปกตรัมและสลับกลับเพื่อระบุช่วงเวลา อย่างน้อยในกรณีนี้ (แต่ฉันสงสัยอย่างกว้างขวางมากขึ้น) ค่าเริ่มต้นของมันจะระบุระยะเวลาที่เพิ่มโอกาสสูงสุดอย่างใกล้ชิดจนฉันลบขั้นตอนที่ฉันมีเพื่อเพิ่มโอกาสในโปรไฟล์ให้มากที่สุดในภูมิภาคในช่วงเวลานั้น ฟังก์ชั่นspecใน TSA อาจจะดีกว่า (ดูเหมือนว่าจะมีตัวเลือกเพิ่มเติมซึ่งหนึ่งในนั้นอาจมีความสำคัญในบางครั้ง) แต่ในกรณีนี้จุดสูงสุดหลักอยู่ในที่เดียวกับที่spectrumฉันไม่ได้รำคาญ
Glen_b -Reinstate Monica

@Glen_b วิธีนี้ใช้งานได้อย่างมหัศจรรย์สำหรับกรณีการใช้งานของฉัน ฉันยังต้องเพื่อให้พอดีกับ cos (x) โค้ง แต่มันไม่ทำงานเช่นกัน ... ผมเปลี่ยนreslmไปreslm <- lm(y ~ cos(2*pi/per*t)+tan(2*pi/per*t))แต่ที่ไม่ได้มองขวา คำใบ้ใด ๆ
Amit Kohli

ทำไมคุณถึงมีสีแทน?
Glen_b -Reinstate Monica

15

2π/20

เมื่อฉันใส่ที่เป็นnlsของstartรายการผมได้เส้นโค้งที่เป็นที่เหมาะสมมากขึ้นแม้ว่ามันจะยังคงมีอคติบางอย่างเป็นระบบ

ขึ้นอยู่กับเป้าหมายของคุณกับชุดข้อมูลนี้คุณสามารถลองปรับปรุงให้เหมาะสมโดยการเพิ่มคำศัพท์เพิ่มเติมหรือใช้วิธีการแบบไม่พารามิเตอร์เช่นกระบวนการแบบเกาส์ที่มีเคอร์เนลเป็นระยะ

ไซน์พอดี

การเลือกค่าเริ่มต้นโดยอัตโนมัติ

หากคุณต้องการเลือกความถี่ที่โดดเด่นคุณสามารถใช้การแปลงฟูริเยร์อย่างรวดเร็ว (FFT) นี่เป็นวิธีที่นอกเหนือจากความเชี่ยวชาญของฉันดังนั้นฉันจะให้คนอื่นกรอกรายละเอียดหากต้องการ (โดยเฉพาะเกี่ยวกับขั้นตอนที่ 2 และ 3) แต่Rรหัสด้านล่างควรใช้งานได้

# Step 1: do the FFT
raw.fft = fft(y)

# Step 2: drop anything past the N/2 - 1th element.
# This has something to do with the Nyquist-shannon limit, I believe
# (https://en.wikipedia.org/wiki/Nyquist%E2%80%93Shannon_sampling_theorem)
truncated.fft = raw.fft[seq(1, length(y)/2 - 1)]

# Step 3: drop the first element. It doesn't contain frequency information.
truncated.fft[1] = 0

# Step 4: the importance of each frequency corresponds to the absolute value of the FFT.
# The 2, pi, and length(y) ensure that omega is on the correct scale relative to t.
# Here, I set omega based on the largest value using which.max().
omega = which.max(abs(truncated.fft)) * 2 * pi / length(y)

คุณสามารถพล็อตabs(truncated.fft)เพื่อดูว่ามีความถี่สำคัญอื่น ๆ หรือไม่ แต่คุณต้องเล่นซอกับการปรับขนาดของแกน x เล็กน้อย

นอกจากนี้ฉันเชื่อว่า @Glen_b นั้นถูกต้องว่าปัญหานั้นเกิดขึ้นเมื่อคุณรู้ว่าโอเมก้า (หรือบางทีคุณต้องรู้ phi ด้วยใช่ไหมฉันไม่แน่ใจ) ไม่ว่าในกรณีใดการรู้ค่าเริ่มต้นสำหรับพารามิเตอร์อื่น ๆ นั้นไม่ควรสำคัญเท่ากับโอเมก้าหากพวกมันอยู่ใน ballpark ที่ถูกต้อง คุณอาจได้รับการประมาณการที่ดีของพารามิเตอร์อื่น ๆ จาก FFT แต่ฉันไม่แน่ใจว่ามันจะทำงานอย่างไร


1
ขอบคุณสำหรับคำใบ้นั้น เพื่ออธิบายให้กระจ่าง: ข้อมูลเป็นส่วนหนึ่งของ microarray ที่ช่วงเวลาของยีนถูกวัดในช่วงเวลาเช่นข้อมูลที่แสดงเป็นข้อมูลการแสดงออกของยีนหนึ่ง ปัญหาตอนนี้คือฉันต้องการใช้วิธีนี้กับยีนประมาณ 40k ทั้งหมดที่มีคาบและแอมพลิจูดต่างกัน ดังนั้นจึงค่อนข้างสำคัญว่าแบบเต็มที่ดีนั้นจะขึ้นอยู่กับเงื่อนไขเบื้องต้น
ปาสกาล

1
@Pascal ดูการอัปเดตของฉันด้านบนเพื่อรับคำแนะนำในการเลือกค่าเริ่มต้นโดยอัตโนมัติสำหรับ omega
David J. Harris

2
ϕab

ฉันสงสัยว่าค่า x ใดที่เข้ามาเล่นที่นี่ แน่ใจว่ามันสร้างความแตกต่างสำหรับโอเมก้าไม่ว่าค่า y ที่กำหนดจะถูกคั่นด้วย 1 หรือ 5 x ก้าวใช่มั้ย
knub

1
Programming เคล็ดลับที่ไม่เกี่ยวข้องกับคำถาม: ความระมัดระวังในการตั้งชื่อ R foo.barวัตถุเป็น เพราะนี่คือวิธีการวิธีการวิจัยระบุสำหรับการเรียน
Firebug

10

เป็นทางเลือกแทนสิ่งที่ถูกกล่าวไปแล้วมันอาจจะคุ้มค่าที่สังเกตได้ว่าแบบจำลอง AR (2) จากคลาสของแบบจำลอง ARIMA สามารถใช้ในการสร้างการคาดการณ์ด้วยรูปแบบคลื่นไซน์

yt=C+ϕ1yt1+ϕ2yt2+at
Cϕ1ϕ2at

ϕ12+4ϕ2<0.

Panratz (1991) บอกเราเกี่ยวกับรอบสุ่ม:

รูปแบบวงจรสโตแคสติกสามารถพิจารณารูปแบบคลื่นไซน์ที่บิดเบี้ยวในรูปแบบการคาดการณ์: มันเป็นคลื่นไซน์ที่มีระยะเวลาสุ่ม (ความน่าจะเป็น), แอมพลิจูดและมุมเฟส

เพื่อดูว่าแบบจำลองดังกล่าวสามารถติดตั้งกับข้อมูลที่ฉันใช้auto.arima()ฟังก์ชั่นจากแพคเกจการคาดการณ์เพื่อดูว่ามันจะแนะนำรุ่น AR (2) ปรากฎว่าauto.arima()ฟังก์ชั่นแนะนำรุ่น ARMA (2,2); ไม่ใช่โมเดล AR บริสุทธิ์ (2) แต่นี่ก็โอเค ไม่เป็นไรเพราะโมเดล ARMA (2,2) มีส่วนประกอบ AR (2) ดังนั้นจึงใช้กฎเดียวกัน (เกี่ยวกับ stochastic cycles) นั่นคือเรายังสามารถตรวจสอบเงื่อนไขข้างต้นเพื่อดูว่าการคาดการณ์คลื่นไซน์จะเกิดขึ้นได้หรือไม่

ผลลัพธ์ของการauto.arima(y)แสดงด้านล่าง

Series: y 
ARIMA(2,0,2) with non-zero mean 

Coefficients:
         ar1      ar2      ma1     ma2  intercept
      1.7347  -0.8324  -1.2474  0.6918    10.2727
s.e.  0.1078   0.0981   0.1167  0.1911     0.5324

sigma^2 estimated as 0.6756:  log likelihood=-60.14
AIC=132.27   AICc=134.32   BIC=143.5

ϕ12+4ϕ2<01.73472+4(0.8324)<00.3202914<0

เนื้อเรื่องด้านล่างแสดงชุดดั้งเดิม, y, ขนาดพอดีของแบบจำลอง ARMA (2,2), และการคาดการณ์แบบหมดตัวอย่าง 14 ครั้ง ดังที่เห็นได้การคาดการณ์ที่ไม่อยู่ในตัวอย่างนั้นเป็นไปตามรูปแบบของคลื่นไซน์

ป้อนคำอธิบายรูปภาพที่นี่

ระลึกไว้เสมอสองสิ่ง 1) นี่เป็นการวิเคราะห์ที่รวดเร็วมาก (การใช้เครื่องมืออัตโนมัติ) และการรักษาที่เหมาะสมจะเกี่ยวข้องกับการทำตามวิธีการของ Box-Jenkins 2) การคาดการณ์ ARIMA ทำได้ดีในการพยากรณ์ระยะสั้นดังนั้นคุณอาจพบว่าการคาดการณ์ระยะยาวจากแบบจำลองในคำตอบโดย @David J. Harris และ @Glen_b น่าเชื่อถือมากขึ้น

สุดท้ายหวังว่านี่เป็นส่วนเสริมที่ดีของคำตอบที่ให้ข้อมูลแล้วบางส่วน

การอ้างอิง : การพยากรณ์ด้วยโมเดลการถดถอยแบบไดนามิก: Alan Pankratz, 1991, (John Wiley and Sons, นิวยอร์ก), ไอ 0-471-61528-5


1

วิธีการในปัจจุบันเพื่อให้พอดีกับเส้นโค้งบาปกับชุดข้อมูลที่กำหนดต้องมีการคาดเดาพารามิเตอร์แรกตามด้วยกระบวนการแทรกซึม นี่เป็นปัญหาการถดถอยที่ไม่เป็นเชิงเส้น วิธีการที่แตกต่างกันประกอบด้วยการแปลงการถดถอยแบบไม่เป็นเชิงเส้นเป็นการถดถอยเชิงเส้นด้วยสมการอินทิกรัลเชิงซ้อนที่สะดวก จากนั้นไม่จำเป็นต้องเดาเริ่มต้นและไม่จำเป็นต้องทำซ้ำกระบวนการ: การติดตั้งจะได้รับโดยตรง ในกรณีที่ฟังก์ชัน y = a + r * sin (w * x + phi) หรือ y = a + b * sin (w * x) + c * cos (w * x) ดูหน้ากระดาษ 35-36 "Régression sinusoidale" เผยแพร่ใน Scribd: http://www.scribd.com/JJacquelin/documents ในกรณีของฟังก์ชั่น y = a + p * x + r * sin (w * x + phi): หน้า 49-51 ของบท "การผสมเชิงเส้นและการถดถอยแบบไซน์" ในกรณีที่ฟังก์ชันมีความซับซ้อนมากขึ้นกระบวนการทั่วไปได้อธิบายไว้ในบท "การถดถอยแบบไซน์ทั่วไป" หน้า 54-61 ตามด้วยตัวเลขตัวอย่าง y = r * sin (w * x + phi) + (b / x) + c * ln (x), หน้า 62-63


0

หากคุณทราบจุดต่ำสุดและสูงที่สุดของข้อมูลการค้นหาค่าโคไซน์ของคุณคุณสามารถใช้ฟังก์ชันง่าย ๆ นี้เพื่อคำนวณค่าสัมประสิทธิ์โคไซน์ทั้งหมด:

getMyCosine <- function(lowest_point=c(pi,-1), highest_point=c(0,1)){
  cosine <- list(
    T = pi / abs(highest_point[1] - lowest_point[1]),
    b = - highest_point[1],
    k = (highest_point[2] + lowest_point[2]) / 2,
    A = (highest_point[2] - lowest_point[2]) / 2
  )
  return(cosine)
}

ด้านล่างใช้เพื่อจำลองการเปลี่ยนแปลงของอุณหภูมิตลอดทั้งวันด้วยฟังก์ชันโคไซน์โดยป้อนค่าชั่วโมงและค่าอุณหภูมิสำหรับชั่วโมงต่ำสุดและอบอุ่นที่สุด:

c <- getMyCosine(c(4,10),c(17,25)) 
# lowest temprature at 4:00 (10 degrees), highest at 17:00 (25 degrees)

x = seq(0,23,by=1);  y = c$A*cos(c$T*(x +c$b))+c$k ; 
library(ggplot2);   qplot(x,y,geom="step")

เอาท์พุทอยู่ด้านล่าง: โคไซน์คำนวณจากจุดต่ำสุดและสูงสุด


3
วิธีการนี้ดูเหมือนจะมีความละเอียดอ่อนเป็นพิเศษต่อการออกจากการสุ่มใด ๆ ที่ดูจากพฤติกรรมไซน์บริสุทธิ์ซึ่งจะทำให้ไม่สามารถใช้กับชุดข้อมูลใด ๆ ได้เกือบจะเหมือนชุดที่แสดงในคำถาม เป็นไปได้ว่ามันสามารถใช้เพื่อให้ค่าเริ่มต้นสำหรับวิธีการวนซ้ำอื่น ๆ ที่แนะนำในเธรดนี้
whuber

เห็นด้วยมันเป็นวิธีที่ง่ายที่สุดจะดีสำหรับการประมาณแบบง่ายภายใต้สมมติฐานบางอย่าง
IVIM

0

อีกตัวเลือกหนึ่งคือการใช้ฟังก์ชั่นทั่วไปOptim หรือ NLS ฉันได้ลองทั้งคู่แล้วไม่มีใครแข็งแกร่งเลย

ฟังก์ชั่นต่อไปนี้ใช้ข้อมูลเป็น y และคำนวณพารามิเตอร์

calc.period <- function(y,t)
{     
   fs <- 1/(t[2]-t[1])
   ssp <- spectrum(y,plot=FALSE )  
   fN <- ssp$freq[which.max(ssp$spec)]
   per <- 1/(fN*fs)
   return(per)
 }

fit.sine<- function(y, t)
{ 
  data <- data.frame(x = as.vector(t), y=as.vector(y))
  min.RSS <- function (data, par){
    with(data, sum((par[1]*sin(2*pi*par[2]*x + par[3])+par[4]-y )^2))
  }  
  amp = sd(data$y)*2.**0.5
  offset = mean(data$y)
  fest <- 1/calc.period(y,t)
  guess = c( amp, fest,  0,   offset)
  #res <- optim(par=guess, fn = min.RSS, data=data ) 
  r<-nls(y~offset+A*sin(2*pi*f*t+phi), 
     start=list(A=amp, f=fest, phi=0, offset=offset))
  res <- list(par=as.vector(r$m$getPars()))
  return(res)
}

 genSine <- function(t, params)
     return( params[1]*sin(2*pi*params[2]*t+ params[3])+params[4])

การใช้งานมีดังต่อไปนี้:

t <- seq(0, 10, by = 0.01)
A <- 2 
f <- 1.5
phase <- 0.2432
offset <- -2

y <- A*sin(2*pi*f*t +phase)+offset + rnorm(length(t), mean=0, sd=0.2)

reslm1 <- fit.sine(y = y, t= t)

รหัสต่อไปนี้เปรียบเทียบข้อมูล

ysin <- genSine(as.vector(t), params=reslm1$par)
ysin.cor <- genSine(as.vector(t), params=c(A, f, phase, offset))

plot(t, y)
lines(t, ysin, col=2)
lines(t, ysin.cor, col=3)
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.