Як знайти гарну форму для напівсинусоїдальної моделі в R?


37

Я хочу припустити, що температура поверхні Балтійського моря однакова з року в рік, а потім описати це за допомогою функціональної / лінійної моделі. У мене була ідея просто ввести рік у вигляді десяткового числа (або число_місяць / 12) і дізнатися, якою повинна бути температура в цей час. Указавши функцію lm () в R, він не розпізнає синусоїдальні дані, тому він просто створює пряму лінію. Тому я поставив функцію sin () в дужку I () і спробував кілька значень, щоб вручну підходити до функції, і це наближається до того, що я хочу. Але море влітку прогрівається швидше, а потім восени остигає повільніше ... Тож модель помиляється перший рік, потім стає правильнішою через пару років, а потім у майбутньому я думаю, що стає більше і знову не так.

Як я можу змусити R оцінити модель для мене, щоб мені не довелося самостійно вгадувати числа? Ключовим тут є те, що я хочу, щоб він давав однакові значення рік за роком, а не був правильним протягом одного року. Якби я знав більше про математику, можливо, я міг би оцінити це як щось на зразок Пуассона чи Гаусса замість гріха (), але я також не знаю, як це зробити. Будемо дуже вдячні за будь-яку допомогу наблизитися до гарної відповіді.

Ось дані, які я використовую, і код для відображення результатів поки що:

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

Відповіді:


44

Це можна зробити за допомогою лінійної регресії -

Вам просто потрібні як і cos термін на кожній частоті.sincos

Причина, за якою ви можете використовувати термін та cos в лінійній регресії для обробки сезонності з будь-якою амплітудою та фазою, пояснюється такою тригонометричною тотожністю :sincos

"Загальна" синусоїда з амплітудою і фазою φ , A sin ( x + φ ) може бути записана як лінійна комбінація a sin x + b cos x, де a і b такі, що A = AφAsin(x+φ)asinx+bcosxab іsinφ=bA=a2+b2 . Подивимось, що два рівносильні:sinφ=ba2+b2

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

Ось "основна" модель:

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

[сніп]

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)

гріх придатний

Редагувати: Важлива примітка - термін працює, тому що період функції встановлено так, що один період = 1 одиниця t . Якщо період відрізняється від 1, скажімо, період є ω , то вам потрібно ( 2 π / ω )2πttω натомість.(2π/ω)t

Ось модель з другою гармонікою:

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

[сніп]

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)

гріх підходить 2

... і так далі, і 6*pi*ToYт. д. Якби в даних було невеликий шум, я, мабуть, зупинився б на цій другій моделі.

З достатньою кількістю термінів ви можете точно підходити до асиметричних і рівних зубчастих періодичних послідовностей, але отримані підходи можуть «хитатися». Ось асиметрична функція (це пилок - пилянка), додана до масштабованої версії вашої періодичної функції) із третьою (червоною) та четвертою (зеленою) гармоніками. Зелене прилягання в середньому трохи ближче, але "хитливо" (навіть коли припадок проходить через кожну точку, пристосування може бути дуже хитким між точками).

гріх підходить 3 і 4

cossin

Якщо ви хочете, щоб пристосування були більш плавними, ніж такий підхід у негладких серіях, ви можете розглянути періодичні пристосування .

Ще один підхід полягає у використанні сезонних муляжів, але підхід sin / cos часто краще, якщо це плавна періодична функція.

Такий підхід до сезонності також може адаптуватися до ситуацій, коли сезонність змінюється, наприклад, використання тригонометричної або манекенової сезонності з державними просторовими моделями.


Хоча лінійний підхід, що обговорюється тут, простий у використанні, одна з переваг нелінійного регресійного підходу @ COOLSerdash полягає в тому, що він може вирішувати набагато ширший спектр ситуацій - вам не доведеться сильно змінюватись, перш ніж опинитися в ситуації, коли лінійний регресія більше не підходить, але все ж можуть використовуватися нелінійні найменші квадрати ( один із таких випадків був би невідомим періодом ).


Дивовижно! Дякую, я дійсно повинен спробувати дізнатися більше про методи боротьби з частотами. Я не зовсім розумію, для чого потрібна частина cos, але знаючи принцип, це легко здійснити.
ГаРю

@COOLSerdash - насправді, я б хотів, щоб ви не видалили свою відповідь (дійсно я її схвалив); вона має перевагу працювати в набагато більш широкому спектрі обставин; перегляньте кілька речей щодо проблеми, і ви можете втратити лінійність - і тоді мій підхід марний, але ваш все одно працює. Я думаю, що можна сказати багато за те, що змогли це зробити так.
Glen_b -Встановіть Моніку

@Glen_b Вибачте, я подумав, що ваш пост зробив мій зайвим, оскільки я не використовував стандартний спосіб вирішення проблеми. Я це визначив.
COOLSerdash

@GaRyu див. Мою редакцію біля верхньої частини моєї відповіді, де я даю контур того, чому додавати в cosробить трюк.
Glen_b -Встановіть Моніку

1
Це був не я .... Ви кажете, що фаза зрушена так, ніби це назвало те, що відбувається, і це робить математично. Але для вас ключовим моментом є більше ймовірність того, що 31 грудня / 1 січня є довільним походженням для часу року, враховуючи відставання в температурній реакції на зміни в опроміненні. Тож зміщення фаз - це назва і для чогось кліматологічного, часу мінімальної та максимальної температури щодо вашої системи запису. (Це незначна деталь, але я віддаю перевагу кількісному визначенню часу року на 12 місяців як 1/24, 3/24, ..., 23/24.)
Нік Кокс

10

Температура, яку ви вказали у своєму питанні, повторюється рівно щороку. Я підозрюю, що це насправді не вимірюються температури протягом чотирьох років. У вашому прикладі вам не знадобиться модель, оскільки температури просто точно повторюються. Але в іншому випадку ви можете скористатися nlsфункцією для встановлення синусоїди:

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 підходить

Але підходить не дуже добре, особливо на початку. Здається, що ваші дані не можуть бути адекватно змодельовані простою синусоїдою. Може, більш складна тригонометрична функція виконає трюк?

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 підходить 2

Червона крива краще відповідає даних. За допомогою nlsфункції ви можете поставити модель, яку ви вважаєте за потрібну.

А може, ви могли б скористатися forecastпакетом. У наведеному нижче прикладі я припустив, що часовий ряд розпочався в січні 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")

АРІМА

Оскільки дані детерміновані, діапазони довіри не відображаються.


4
Тут немає ніяких причин для нелінійних найменших квадратів, не те, що вони не працюватимуть досить добре. Заздалегідь обчисліть гріх (2 * пі * ToY), cos (2 * pi * ToY) і подайте їх так lm()само, як і будь-які інші прогнози. Іншими словами, lm()зовсім не потрібно бачити ніякої тригонометрії. Однак вам може знадобитися інша модель, щоб добре засвоїти позначену асиметрію. Я не звичайний користувач R, але часто використовував такий підхід в іншому місці (див. Stata-journal.com/sjpdf.html?articlenum=st0116 ).
Нік Кокс

@NickCox Спасибі Нік, це дуже корисна порада. Я трохи оновлю свою відповідь.
COOLSerdash

Глен був швидшим :)
COOLSerdash

1
@COOLserdash Я навіть не побачив коментаря Ніка Кокса там; це прийшло, коли я формував свою відповідь. (Цей підхід досить очевидний, якщо ви бачили будь-які серії Фур'є.)
Glen_b -Встановіть Моніку

2
Як випливає з @Glen_b, це стандартний підхід, просто не загальновідомий.
Нік Кокс
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.