R'de yarı sinüzoidal model için uygun olanı nasıl bulabilirim?


37

Baltık Denizi'nin deniz yüzeyinin sıcaklığının her yıl aynı olduğunu varsaymak istiyorum, sonra bunu bir fonksiyon / doğrusal modelle tanımlamak istiyorum. Benim düşüncem, yılı bir ondalık sayı olarak girmek (ya da num_months / 12) ve sıcaklığın o zaman ne olacağı hakkında bilgi almaktı. R'deki lm () fonksiyonuna atıldığında, sinüzoidal verileri tanımıyor, bu yüzden sadece düz bir çizgi oluşturuyor. Bu yüzden sin () fonksiyonunu bir I () braketi içine koydum ve fonksiyona manüel olarak sığdırmak için birkaç değer denedim, ve bu istediğime yaklaşıyor. Fakat deniz yaz aylarında daha hızlı ısınıyor ve sonbaharda daha yavaş soğuyor ... Bu yüzden model ilk yıl yanlıştır, daha sonra birkaç yıl sonra daha düzelir ve daha sonra gelecekte daha fazla olur ve daha yanlış.

R'nin benim için modeli tahmin etmesini nasıl sağlayabilirim, böylece sayıları kendim tahmin etmek zorunda kalmayacağım? Burada anahtar, her yıl aynı değerleri üretmesini istiyorum, sadece bir yıl için doğru değil. Matematik hakkında daha fazla şey bilseydim, belki günah () yerine Poisson ya da Gaussian gibi bir şey olduğunu tahmin edebilirdim, ama bunu nasıl yapacağımı da bilmiyorum. İyi bir cevaba yaklaşmak için her türlü yardım büyük memnuniyetle karşılanacaktır.

İşte kullandığım veriler ve şimdiye kadarki sonuçları gösterecek kod:

# SST from Bradtke et al 2010
ToY <- c(1/12,2/12,3/12,4/12,5/12,6/12,7/12,8/12,9/12,10/12,11/12,12/12,13/12,14/12,15/12,16/12,17/12,18/12,19/12,20/12,21/12,22/12,23/12,24/12,25/12,26/12,27/12,28/12,29/12,30/12,31/12,32/12,33/12,34/12,35/12,36/12,37/12,38/12,39/12,40/12,41/12,42/12,43/12,44/12,45/12,46/12,47/12,48/12)
Degrees <- c(3,2,2.2,4,7.6,13,16,16.1,14,10.1,7,4.5,3,2,2.2,4,7.6,13,16,16.1,14,10.1,7,4.5,3,2,2.2,4,7.6,13,16,16.1,14,10.1,7,4.5,3,2,2.2,4,7.6,13,16,16.1,14,10.1,7,4.5)
SST <- data.frame(ToY, Degrees)
SSTlm <- lm(SST$Degrees ~ I(sin(pi*2.07*SST$ToY)))
summary(SSTlm)
plot(SST,xlim=c(0,4),ylim=c(0,17))
par(new=T)
plot(data.frame(ToY=SST$ToY,Degrees=8.4418-6.9431*sin(2.07*pi*SST$ToY)),type="l",xlim=c(0,4),ylim=c(0,17))

Yanıtlar:


44

Doğrusal regresyon ile yapılabilir -

Sadece bir ikisine de ihtiyacım ve her frekansta dönem.cossincos

Mevsimselliği herhangi bir genlikte ve fazda ele almak için doğrusal bir regresyonda ve terimini kullanabilmenizin nedeni, aşağıdaki trigonometrik kimliktir :cossincos

Genlik ile birlikte bir 'genel' sinüs dalgası ve faz , , lineer bir kombinasyonu olarak yazılabilir burada ve gibi olduğu ve . İki eşdeğer olduğunu görelim:φ A günah ( x + φ ) bir günah x + b çünkü x a b A = AφAsin(x+φ)asinx+bcosxab günahφ=bA=a2+b2sinφ=ba2+b2

asin(x)+bcos(x)=a2+b2(aa2+b2sin(x)+ba2+b2cos(x))=A[sin(x)cos(φ)+cos(x)sin(φ)]=Asin(x+φ).

İşte 'temel' model:

 SSTlm <- lm(Degrees ~ sin(2*pi*ToY)+cos(2*pi*ToY),data=SST)
 summary(SSTlm)

[Kesik]

Coefficients:
                      Estimate Std. Error t value Pr(>|t|)    
(Intercept)              8.292      0.135   61.41   <2e-16 *** 
sin(2 * pi * ToY)       -5.916      0.191  -30.98   <2e-16 ***  
cos(2 * pi * ToY)       -4.046      0.191  -21.19   <2e-16 *** 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1   1 

Residual standard error: 0.9355 on 45 degrees of freedom
Multiple R-squared: 0.969,      Adjusted R-squared: 0.9677 
F-statistic: 704.3 on 2 and 45 DF,  p-value: < 2.2e-16 

 plot(Degrees~ToY,ylim=c(1.5,16.5),data=SST)
 lines(SST$ToY,SSTlm$fitted,col=2)

günah uygun

Düzenleme: Önemli not - terimi, işlev süresi bir dönem = 1 birim olacak şekilde ayarlandığı için çalışır . Periyot 1'den farklıysa, periyodun olduğunu söyleyin , o zaman bunun yerine .t ω ( 2 π / ω )2πttω(2π/ω)t

İşte ikinci harmonik ile model:

 SSTlm2 <- lm(Degrees ~ sin(2*pi*ToY)+cos(2*pi*ToY)
                        +sin(4*pi*ToY)+cos(4*pi*ToY),data=SST)
 summary(SSTlm2)

[Kesik]

Coefficients:
                  Estimate Std. Error  t value Pr(>|t|)    
(Intercept)        8.29167    0.02637  314.450  < 2e-16 ***  
sin(2 * pi * ToY) -5.91562    0.03729 -158.634  < 2e-16 ***  
cos(2 * pi * ToY) -4.04632    0.03729 -108.506  < 2e-16 ***  
sin(4 * pi * ToY)  1.21244    0.03729   32.513  < 2e-16 ***  
cos(4 * pi * ToY)  0.33333    0.03729    8.939 2.32e-11 ***  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1   1 

Residual standard error: 0.1827 on 43 degrees of freedom
Multiple R-squared: 0.9989,     Adjusted R-squared: 0.9988 
F-statistic:  9519 on 4 and 43 DF,  p-value: < 2.2e-16 

 plot(Degrees~ToY,ylab="Degrees",xlab="ToY",ylim=c(1.5,16.5),data=SST)
 lines(SSTlm2$fitted~ToY,col=2,data=SST)

günah 2 uygun

... 6*pi*ToYvb. ile vb. Verilerde küçük bir miktar gürültü olsaydı, muhtemelen bu ikinci modelde dururdum.

Yeterince terim ile asimetrik ve hatta pürüzlü periyodik dizilere tam olarak sığabilirsiniz, ancak ortaya çıkan uyarılar "kıpırdayabilir". İşte testere dişiüçüncü (kırmızı) ve dördüncü (yeşil) harmoniklere sahip, asimetrik bir fonksiyon (bu bir testere dişi - periyodik fonksiyonunuzun ölçekli bir versiyonuna eklendi). Yeşil uyum ortalama olarak biraz daha yakın ancak “dikkat çekici” (uygunluk her noktadan geçse bile uygunluk noktalar arasında çok tuhaf olabilir).

günah 3 ve 4 uygun

Buradaki periyodiklik, verilerdeki mevsimsel bir model için yalnızca 12 df olduğunu gösterir. Modeldeki engellemeyle, 11 mevsimsel parametre için sadece yeterli derecede serbestliğe sahipsiniz. Eklemekte olduğunuz bu yana iki , her harmonik sadece size izin verecektir sığabilecek son armonik ile terimleri birini son dönem için onlardan, altıncı harmonik (ve bu biri olmak zorunda ; terimi all olacaktır sıfır, cos ise 1 ile -1 arasında değişir.günahcossin

Düzgün olmayan serilerde bu yaklaşımdan daha yumuşak olan uyarlar istiyorsanız, periyodik spline uydurmalara bakmak isteyebilirsiniz .

Yine bir başka yaklaşım mevsimsel mankenleri kullanmaktır, ancak düzgün / periyodik bir işlevse sin / cos yaklaşımı genellikle daha iyidir.

Mevsimsellik için bu tür bir yaklaşım, durum uzaylı modellerde trigonometrik veya yapay mevsimsellik kullanmak gibi mevsimselliğin değiştiği durumlara da adapte olabilir.


Burada tartışılan doğrusal model yaklaşımının kullanımı basit olmakla birlikte, @ COOLSerdash'ın doğrusal olmayan regresyon yaklaşımının bir avantajı, çok daha geniş bir durum yelpazesiyle başa çıkabilmesidir - doğrusal bir durumda olmadan önce çok fazla değişiklik yapmanız gerekmez. regresyon artık uygun değildir, ancak doğrusal olmayan en küçük kareler hala kullanılabilir ( bilinmeyen bir süreye sahip olmak böyle bir durum olabilir).


Müthiş! Teşekkürler, frekanslarla başa çıkma yöntemleri hakkında daha fazla şey öğrenmeye çalışmalıyım. Çünkü neden kısmına ihtiyaç duyulduğunu tam olarak anlamadım, ancak ilkeyi bilmek uygulamayı kolaylaştırıyor.
GaRyu

@COOLSerdash - Aslında, cevabınızı silmemiş olmanızı dilerdim (gerçekten de onu reddettim); çok daha geniş bir koşullarda çalışma avantajına sahiptir; sorun hakkında birkaç şey düzeltin ve doğrusallığı kaybedebilirsiniz - ve sonra benim yaklaşımım işe yaramaz, ama sizinki hala çalışıyor. Bu şekilde yapabilmek için söylenecek çok şey olduğunu düşünüyorum.
Glen_b

@Glen_b Ah özür dilerim, gönderinizin gereksiz olduğunu düşünüyorum çünkü sorunla başa çıkmanın standart yolunu kullanmadım. Ben geri aldım.
COOLSerdash

@GaRyu, cevabımın üst kısmına yakın bir yerde düzenleme yaptığımı görüyor, burada ekleme neden hileyi yapıyor. cos
Glen_b

1
Bu ben değildim .... Faz dengesini olan biten isim sanki deniyor ve matematiksel olarak yapıyor. Ancak sizin için kilit nokta, 31 Aralık / 1 Ocak’ın, radyasyon alımındaki değişikliklere sıcaklık cevabında verilen yılın belli bir orijini olması muhtemeldir. Yani faz ofseti, burada da iklimsel bir şeyin adıdır, kayıt sisteminize göre minimum ve maksimum sıcaklığın zamanlaması. (Küçük bir detay ama yılın 12 ay boyunca 1/24, 3/24, ..., 23/24 olarak hesaplanmasını tercih ediyorum.)
Nick Cox

10

Sorunuzda sağladığınız sıcaklık her yıl tam olarak tekrar eder. Bunun dört yıldaki sıcaklığın ölçülmediğinden şüpheleniyorum. Örneğinizde, bir modele ihtiyacınız olmaz, çünkü sıcaklıklar tam olarak tekrar eder. Fakat aksi takdirde, nlsişlevi bir sinüs eğrisine sığdırmak için kullanabilirsiniz :

ToY <- c(1/12,2/12,3/12,4/12,5/12,6/12,7/12,8/12,9/12,10/12,11/12,12/12,13/12,14/12,15/12,16/12,17/12,18/12,19/12,20/12,21/12,22/12,23/12,24/12,25/12,26/12,27/12,28/12,29/12,30/12,31/12,32/12,33/12,34/12,35/12,36/12,37/12,38/12,39/12,40/12,41/12,42/12,43/12,44/12,45/12,46/12,47/12,48/12)
Degrees <- c(3,2,2.2,4,7.6,13,16,16.1,14,10.1,7,4.5,3,2,2.2,4,7.6,13,16,16.1,14,10.1,7,4.5,3,2,2.2,4,7.6,13,16,16.1,14,10.1,7,4.5,3,2,2.2,4,7.6,13,16,16.1,14,10.1,7,4.5)
SST <- data.frame(ToY, Degrees)

par(cex=1.5, bg="white")
plot(Degrees~ToY,xlim=c(0,4),ylim=c(0,17), pch=16, las=1)

nls.mod <-nls(Degrees ~ a + b*sin(2*pi*c*ToY), start=list(a = 1, b = 1, c=1))

co <- coef(nls.mod) 
f <- function(x, a, b, c) {a + b*sin(2*pi*c*x) }

curve(f(x, a=co["a"], b=co["b"], c=co["c"]), add=TRUE ,lwd=2, col="steelblue")

NLS fit

Ancak, özellikle başlangıçta uyum çok iyi değil. Verilerinizin basit bir sinüs eğrisi ile yeterince modellenemediği anlaşılıyor. Belki daha karmaşık bir trigonometrik fonksiyon hile yapar?

nls.mod2 <-nls(Degrees ~ a + b*sin(2*pi*c*ToY)+d*cos(2*pi*e*ToY), start=list(a = 1, b = 1, c=1, d=1, e=1))

co2 <- coef(nls.mod2) 
f <- function(x, a, b, c, d, e) {a + b*sin(2*pi*c*x)+d*cos(2*pi*e*x) }

curve(f(x, a=co2["a"], b=co2["b"], c=co2["c"], d=co2["d"], e=co2["e"]), add=TRUE ,lwd=2, col="red")

NLS uygun 2

Kırmızı eğri verilere daha iyi uyar. İle nlsfonksiyonu, size uygun olduğunu düşünüyorum modelinde koyabilirsiniz.

Ya da belki forecastpaketi kullanabilirsin . Aşağıdaki örnekte, zaman serisinin Ocak 2010'da başladığını varsaydım:

library(forecast)

Degrees.ts <- ts(Degrees, start=c(2010,1), frequency=12)

Degree.trend <- auto.arima(Degrees.ts)

degrees.forecast <- forecast(Degree.trend, h=12, level=c(80,95), fan=F)

plot(degrees.forecast, las=1, main="", xlab="Time", ylab="Degrees")

ARİMA

Veriler deterministik olduğundan, hiçbir güven bandı gösterilmez.


4
Burada doğrusal olmayan en küçük kareler için hiçbir neden yoktur, makul bir şekilde çalışmayacaktır. Günahı (2 * pi * ToY), cos (2 * pi * ToY) önceden hesaplayın ve lm()diğer tahminciler gibi onları besleyin . Başka bir deyişle, lm()hiç bir trigonometri görmek gerekmez. Bununla birlikte, işaretli asimetriyi iyi yakalamak için başka bir modele ihtiyacınız olabilir. Normal bir R kullanıcısı değilim ama bu yaklaşımı başka yerlerde sıklıkla kullandım (bkz. Stata-journal.com/sjpdf.html?articlenum=st0116 ).
Nick Cox

@ NickCox Teşekkürler Nick, bu çok faydalı bir tavsiye. Cevabımı biraz sonra güncelleyeceğim.
COOLSerdash

Glen daha hızlıydı :)
COOLSerdash

1
@ COOLserdash Nick Cox'un yorumunu orada bile görmedim; Ben cevabımı oluştururken geldi. (Herhangi bir Fourier serisi
gördüyseniz

2
@Glen_b'in de belirttiği gibi, bu evrensel olarak bilinmeyen standart bir yaklaşımdır.
Nick Cox,
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.