Làm thế nào để tìm một sự phù hợp tốt cho mô hình bán hình sin trong R?


37

Tôi muốn giả sử rằng nhiệt độ mặt nước biển của Biển Baltic là cùng năm này qua năm khác, và sau đó mô tả điều đó bằng một mô hình hàm / tuyến tính. Ý tưởng tôi có là chỉ nhập năm dưới dạng số thập phân (hoặc num_months / 12) và tìm hiểu xem nhiệt độ sẽ như thế nào trong khoảng thời gian đó. Ném nó vào hàm lm () trong R, nó không nhận ra dữ liệu hình sin nên nó chỉ tạo ra một đường thẳng. Vì vậy, tôi đặt hàm sin () trong dấu ngoặc I () và thử một vài giá trị để khớp với hàm theo cách thủ công và nó gần với những gì tôi muốn. Nhưng biển ấm lên nhanh hơn vào mùa hè và sau đó hạ nhiệt chậm hơn vào mùa thu ... Vì vậy, mô hình đã sai trong năm đầu tiên, sau đó trở nên chính xác hơn sau một vài năm, và trong tương lai tôi đoán nó sẽ trở nên nhiều hơn và lại càng sai.

Làm cách nào tôi có thể lấy R để ước tính mô hình cho tôi, vì vậy tôi không phải tự đoán số? Chìa khóa ở đây là tôi muốn nó tạo ra các giá trị tương tự năm này qua năm khác, không chỉ đúng trong một năm. Nếu tôi biết nhiều hơn về toán học, có lẽ tôi có thể dự đoán nó như một thứ giống như Poisson hoặc Gaussian thay vì sin (), nhưng tôi cũng không biết làm thế nào để làm điều đó. Bất kỳ trợ giúp để đến gần hơn với một câu trả lời tốt sẽ được đánh giá rất cao.

Đây là dữ liệu tôi sử dụng và mã để hiển thị kết quả cho đến nay:

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

Câu trả lời:


44

Nó có thể được thực hiện với hồi quy tuyến tính -

Bạn chỉ cần cả thuật ngữ và ở mỗi tần số.cossincos

Lý do tại sao bạn có thể sử dụng thuật ngữ và trong hồi quy tuyến tính để xử lý tính thời vụ với bất kỳ biên độ và pha nào là do nhận dạng lượng giác sau :sincos

Sóng hình sin 'chung' với biên độ và pha , , có thể được viết dưới dạng kết hợp tuyến tính trong đó và sao cho và . Chúng ta hãy xem hai cái này tương đương nhau:φ Một tội lỗi ( x + φ ) một tội lỗi x + b cos x một b Một = AφAsin(x+φ)asinx+bcosxab sinφ=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+φ).

Đây là mô hình 'cơ bản':

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

[bắn tỉa]

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)

phù hợp với tội lỗi

Chỉnh sửa: Lưu ý quan trọng - thuật ngữ hoạt động vì thời gian của chức năng đã được thiết lập sao cho một khoảng thời gian = 1 đơn vị . Nếu khoảng thời gian khác với 1, giả sử khoảng thời gian là , thì bạn cần thay thế.t ω ( 2 π / ω )2πttω(2π/ω)t

Đây là mô hình với sóng hài thứ hai:

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

[bắn tỉa]

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)

tội lỗi phù hợp với 2

... và cứ thế, 6*pi*ToYv.v ... Nếu có một chút nhiễu trong dữ liệu thì có lẽ tôi sẽ dừng với mô hình thứ hai này.

Với đủ thuật ngữ, bạn có thể điều chỉnh chính xác các chuỗi định kỳ không đối xứng và thậm chí lởm chởm, nhưng kết quả phù hợp có thể 'ngọ nguậy'. Đây là một hàm bất đối xứng (đó là răng cưa - răng cưa) được thêm vào phiên bản thu nhỏ của hàm tuần hoàn của bạn), với các hài bậc ba (đỏ) và thứ tư (xanh lục). Sự phù hợp màu xanh lá cây trung bình gần hơn một chút nhưng "ngọ nguậy" (ngay cả khi sự phù hợp đi qua mọi điểm, sự phù hợp có thể rất lung lay giữa các điểm).

tội lỗi phù hợp với 3 & 4

Tính định kỳ ở đây có nghĩa là chỉ có 12 df có sẵn cho một mô hình theo mùa trong dữ liệu. Với việc chặn trong mô hình, bạn chỉ có đủ mức độ tự do cho 11 thông số theo mùa bổ sung. Vì bạn đang thêm hai thuật ngữ với mỗi điều hòa, nên điều hòa cuối cùng bạn có thể phù hợp sẽ chỉ cho phép bạn một trong số đó cho điều khoản cuối cùng, điều hòa thứ sáu (và điều đó phải là một ; thuật ngữ sẽ là tất cả- bằng không, trong khi cos xen kẽ giữa 1 và -1).tội lỗicossin

Nếu bạn muốn phù hợp mượt mà hơn phương pháp này tạo ra trên loạt không trơn tru, bạn có thể muốn xem xét phù hợp spline định kỳ .

Tuy nhiên, một cách tiếp cận khác là sử dụng các hình nộm theo mùa, nhưng cách tiếp cận sin / cos thường tốt hơn nếu đó là một chức năng định kỳ trơn tru.

Cách tiếp cận theo mùa này cũng có thể thích ứng với các tình huống mà tính thời vụ đang thay đổi, chẳng hạn như sử dụng lượng giác hoặc thời vụ giả với các mô hình không gian trạng thái.


Mặc dù cách tiếp cận mô hình tuyến tính được thảo luận ở đây rất đơn giản để sử dụng, một ưu điểm của phương pháp hồi quy phi tuyến của @ COOLSerdash là nó có thể xử lý một phạm vi rộng hơn nhiều tình huống - bạn không phải thay đổi nhiều trước khi gặp tình huống tuyến tính hồi quy không còn phù hợp nhưng bình phương tối thiểu phi tuyến vẫn có thể được sử dụng (có một khoảng thời gian không xác định sẽ là một trường hợp như vậy).


Tuyệt vời! Cảm ơn bạn, tôi thực sự nên cố gắng tìm hiểu thêm về các phương pháp để đối phó với tần số. Tôi không hiểu tại sao phần cos là cần thiết, nhưng biết nguyên tắc làm cho nó dễ thực hiện.
GaRyu

@COOLSerdash - thực sự, tôi ước bạn đã xóa câu trả lời của mình (thực sự tôi đã nâng cấp nó); nó có lợi thế làm việc trong một loạt các tình huống rộng lớn hơn nhiều; điều chỉnh một số điều về vấn đề và bạn có thể mất tuyến tính - và sau đó phương pháp của tôi là vô ích, nhưng cách của bạn vẫn hoạt động. Tôi nghĩ có rất nhiều điều để nói về việc có thể làm theo cách đó.
Glen_b -Reinstate Monica

@Glen_b Ah xin lỗi, tôi nghĩ rằng bài đăng của bạn khiến tôi trở nên dư thừa vì tôi không sử dụng cách xử lý vấn đề tiêu chuẩn. Tôi đã hoàn tác nó.
COOLSerdash

@GaRyu xem bản chỉnh sửa của tôi, gần đầu câu trả lời của tôi, nơi tôi đưa ra một phác thảo về lý do tại sao thêm vào thực hiện thủ thuật. cos
Glen_b -Reinstate Monica

1
Đó không phải là tôi .... Bạn nói bù pha như thể nó đặt tên cho những gì đang diễn ra, và nó có tính toán học. Nhưng đối với bạn, điểm mấu chốt có nhiều khả năng là ngày 31 tháng 12/1 tháng 1 là một nguồn gốc tùy ý trong thời gian của năm do độ trễ trong phản ứng nhiệt độ với các biến đổi trong nhận phóng xạ. Vì vậy, bù pha là một tên ở đây cho một cái gì đó khí hậu quá, thời gian của nhiệt độ tối thiểu và tối đa liên quan đến hệ thống ghi âm của bạn. (Đó là một chi tiết nhỏ nhưng tôi thích định lượng thời gian trong năm trong 12 tháng là 1/24, 3/24, ..., 23/24.)
Nick Cox

10

Nhiệt độ bạn cung cấp trong câu hỏi của bạn lặp lại chính xác hàng năm. Tôi nghi ngờ điều này không thực sự đo nhiệt độ trong bốn năm. Trong ví dụ của bạn, bạn sẽ không cần một mô hình, vì nhiệt độ chỉ lặp lại chính xác. Nhưng nếu không, bạn có thể sử dụng nlshàm để khớp với đường cong hình sin:

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

Phù hợp với NLS

Nhưng sự phù hợp không phải là rất tốt, đặc biệt là vào lúc đầu. Dường như dữ liệu của bạn không thể được mô hình đầy đủ bằng một đường cong hình sin đơn giản. Có lẽ một hàm lượng giác phức tạp hơn sẽ thực hiện thủ thuật?

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 phù hợp với 2

Các đường cong màu đỏ phù hợp với dữ liệu tốt hơn. Với nlschức năng, bạn có thể đưa vào mô hình mà bạn nghĩ là phù hợp.

Hoặc có lẽ bạn có thể sử dụng các forecastgói. Trong ví dụ dưới đây, tôi đã giả sử rằng chuỗi thời gian bắt đầu vào tháng 1 năm 2010:

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

ARIMA

Bởi vì dữ liệu mang tính quyết định, không có dải tin cậy nào được hiển thị.


4
Không có lý do cho các hình vuông nhỏ nhất phi tuyến ở đây, không phải là nó sẽ không hoạt động tốt. Tính toán sin (2 * pi * ToY), cos (2 * pi * ToY) trước và đưa chúng vào lm()giống như bất kỳ dự đoán nào khác. Nói cách khác, lm()không cần phải xem bất kỳ lượng giác nào cả. Tuy nhiên, bạn có thể cần một mô hình khác để nắm bắt tốt sự bất đối xứng được đánh dấu. Tôi không phải là người dùng R thông thường nhưng tôi thường sử dụng phương pháp này ở nơi khác (xem stata-journal.com/sjpdf.html?articlenum=st0116 ).
Nick Cox

@NickCox Cảm ơn Nick, đó là lời khuyên rất hữu ích. Tôi sẽ cập nhật câu trả lời của tôi trong một chút.
COOLSerdash

Glen đã nhanh hơn :)
COOLSerdash

1
@COOLserdash Tôi thậm chí không thấy bình luận của Nick Cox ở đó; nó đến trong khi tôi đang tạo ra câu trả lời của mình (Cách tiếp cận này khá rõ ràng nếu bạn đã xem bất kỳ loạt Fourier nào.)
Glen_b -Reinstate Monica

2
Như @Glen_b ngụ ý, đây là một cách tiếp cận tiêu chuẩn, chỉ không được biết đến phổ biến.
Nick Cox
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.