Rの半正弦波モデルに適したものを見つける方法は?


37

バルト海の海面温度は毎年同じであると仮定し、関数/線形モデルで説明します。私が考えていたのは、年を10進数(またはnum_months / 12)として入力し、その時間についての温度を取得することでした。Rのlm()関数にそれを投げると、正弦データを認識しないため、直線を生成します。そこで、sin()関数をI()ブラケットに入れて、いくつかの値を試して関数を手動でフィットさせました。しかし、海は夏には早く暖まり、秋にはゆっくりと冷却します...ですから、最初の年はモデルが間違っていて、数年後にはより正確になり、将来的にはより多くなると思いますそしてさらに間違っています。

モデルを推定するためにRを取得するにはどうすればよいですか?したがって、自分で数値を推測する必要はありませんか?ここで重要なのは、1年間だけでなく、毎年同じ値を生成することです。数学についてもっと知っていれば、sin()の代わりにポアソンやガウスのようなものと推測できるかもしれませんが、その方法もわかりません。良い答えに近づくための助けをいただければ幸いです。

ここに私が使用するデータと、これまでの結果を表示するコードを示します。

# 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

線形回帰でおよび項を使用して、振幅と位相の季節性を処理できる理由は、次の三角関数の同一性のためです。コスcos

振幅および位相、の '一般的な'正弦波は、線形結合として記述できます。 ここ、とは、と。2つが同等であることを見てみましょう。φ AのX + φ X + B COS X 、A 、B A = AφAバツ+φaバツ+bcosバツabφ=BA=a2+b2φ=ba2+b2

aバツ+bcosバツ=a2+b2aa2+b2バツ+ba2+b2cosバツ=A[バツcosφ+cosバツφ]=Aバツ+φ

「基本」モデルは次のとおりです。

 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期間= 1単位のなるように設定されているため機能します。周期が1と異なる場合、周期がである場合代わりにが必要です。2πttω2π/ωt

次に、2次高調波を含むモデルを示します。

 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などなど。データにわずかなノイズがあった場合は、おそらくこの2番目のモデルで停止します。

十分な項があると、非対称の周期的なシーケンスでさえも正確にフィットできますが、結果のフィットは「揺れ」ます。これのこぎりは、3番目(赤)と4番目(緑)の高調波を持つ非対称関数(周期関数のスケーリングバージョンに追加された鋸歯状波- )です。緑色のフィットは、平均して少し近くなりますが、「波状」です(フィットがすべてのポイントを通過する場合でも、フィットはポイント間で非常に波状になります)。

sin fit 3&4

ここでの周期性とは、データの季節モデルに利用可能なdfが12個しかないことを意味します。モデルの切片では、11個の追加の季節パラメーターに対して十分な自由度しかありません。各高調波に2つの項を追加しているため、最後に適合できる高調波では、最後の項のうちの1つ、第6高調波のみが許可されます(その1つはなければならず、項はすべて-ゼロ、cosは1と-1の間を交互に切り替えます。cos

このアプローチが滑らかでないシリーズで生成するよりも滑らかなフィットが必要な場合は、周期的なスプラインフィットを調べてください。

さらに別のアプローチは、季節のダミーを使用することですが、sin / cosアプローチは、滑らかな周期関数であれば、多くの場合より優れています。

季節性に対するこの種のアプローチは、状態空間モデルで三角季節性またはダミー季節性を使用するなど、季節性が変化する状況にも適応できます。


ここで説明する線形モデルのアプローチは簡単に使用できますが、@ COOLSerdashの非線形回帰アプローチの利点の1つは、より広範囲の状況に対応できることです。線形の状況になる前に変更する必要はありません。回帰はもはや適切ではありませんが、非線形最小二乗を使用することができます(未知の周期を持つことはそのような場合の1つです)。


驚くばかり!ありがとう、私は本当に周波数に対処する方法についてもっと学ぼうとするべきです。cosパーツが必要な理由はよくわかりませんが、原則を知っていると実装が簡単になります。
-GaRyu

@COOLSerdash-実際、あなたの答えを削除していなかったならいいのですが(実際、私はそれを支持しました)。はるかに幅広い状況で作業できるという利点があります。問題についていくつかのことを微調整すると、直線性が失われる可能性があります-そして、私のアプローチは役に立たないが、あなたのものはまだ機能します。そのようにすることができると言うことはたくさんあると思います。
Glen_b

@Glen_b申し訳ありませんが、問題を処理する標準的な方法を使用しなかったため、あなたの投稿が私のものを冗長にしたと思いました。元に戻しました。
COOLSerdash

@GaRyuは、私の編集の答えの上部近くにあり、追加するのがうまくいかない理由の概要を示しています。cos
Glen_b

1
それは私ではありませんでした.... 位相オフセットは、それが何が起こっているかを指名したかのように言い、数学的に行います。しかし、あなたにとって重要な点は、12月31日/ 1月1日が、放射線の受信の変動に対する温度応答の遅れを考えると、時間の任意の起源である可能性が高いことです。位相オフセットは、ここでも気候学的なものの名前であり、記録システムに対する最低温度と最高温度のタイミングです。(これは些細なことですが、私は12か月間の時間を1 / 24、3 / 24、...、23/24として定量化することを好みます。)
Nick Cox

10

質問で指定した温度は、毎年正確に繰り返されます。これは実際には4年間の温度測定ではないと思われます。この例では、温度は正確に繰り返されるため、モデルは必要ありません。ただし、そうでない場合は、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年1月に始まったと想定しています。

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
ここでは、非線形最小二乗の理由はなく、合理的にうまく機能しないわけではありません。前もってsin(2 * pi * ToY)、cos(2 * pi * ToY)を計算しlm()、他の予測子と同じようにそれらを入力します。言い換えれば、lm()三角法をまったく見る必要はありません。ただし、マークされた非対称性をうまくキャプチャするには別のモデルが必要になる場合があります。私は通常のRユーザーではありませんが、このアプローチは他の場所でよく使用しています(stata-journal.com/sjpdf.html?articlenum=st0116を参照)。
ニックコックス

@NickCoxニックに感謝、それは非常に役立つアドバイスです。回答を少し更新します。
COOLSerdash

グレンは速かった:)
COOLSerdash

1
@COOLserdashニックコックスのコメントすら見られませんでした。答えを生成しているときに来ました。(フーリエ級数を見たことがあるなら、このアプローチは非常に明白です。)
Glen_b -Reinstate Monica

2
@Glen_bが示すように、これは標準的なアプローチであり、広く知られているわけではありません。
ニックコックス
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.