2013-11-20 202 views
7

我是一個初學者,在曲線擬合和Stackoverflow上的幾個帖子真的幫助了我。在R中使用lm和nls的正弦曲線擬合

我試圖使用lmnls來擬合我的數據的正弦曲線,但是這兩種方法都顯示出奇怪的擬合,如下所示。任何人都可以指出我出錯的地方。我會懷疑有時間做的事情,但無法做到。我的數據可以從here訪問。 plot

data <- read.table(file="900days.txt", header=TRUE, sep="") 
time<-data$time 
temperature<-data$temperature 

#lm fitting 
xc<-cos(2*pi*time/366) 
xs<-sin(2*pi*time/366) 
fit.lm<-lm(temperature~xc+xs) 
summary(fit.lm) 
plot(temp~time, data=data, xlim=c(1, 900)) 
par(new=TRUE) 
plot(fit.lm$fitted, type="l", col="red", xlim=c(1, 900), pch=19, ann=FALSE, xaxt="n", 
yaxt="n") 

#nls fitting 
fit.nls<-nls(temp~C+alpha*sin(W*time+phi), 
    start=list(C=27.63415, alpha=27.886, W=0.0652, phi=14.9286)) 
summary(fit.nls) 
plot(fit.nls$fitted, type="l", col="red", xlim=c(1, 900), pch=19, ann=FALSE, xaxt="n", 
axt="n") 
+0

'fit.lm'屬於類「lm」,所以有一個繪圖方法。 'plot(fit.lm,type .....)'可能更符合你的要求。 –

+0

「366」來自公式2 * pi * time/366的意義是什麼? – Vinterwoo

回答

9

這是因爲NA的值已從要修改的數據中移除(並且您的數據有相當多的數據);因此,當您繪製fit.lm$fitted時,繪圖方法將該系列的索引解釋爲「x」值以對其進行繪製。

試試這個[注意我是如何改變的變量名,以防止衝突與功能timedata(讀this後)]:

Data <- read.table(file="900days.txt", header=TRUE, sep="") 
Time <- Data$time 
temperature <- Data$temperature 

xc<-cos(2*pi*Time/366) 
xs<-sin(2*pi*Time/366) 
fit.lm <- lm(temperature~xc+xs) 

# access the fitted series (for plotting) 
fit <- fitted(fit.lm) 

# find predictions for original time series 
pred <- predict(fit.lm, newdata=data.frame(Time=Time))  

plot(temperature ~ Time, data= Data, xlim=c(1, 900)) 
lines(fit, col="red") 
lines(Time, pred, col="blue") 

這給了我:

enter image description here

這可能是你所希望的。

+0

我只是想知道如何改進,使曲線實際上符合最高溫度值。 – Eddie

+0

@Eddie我不確定你的意思。你能澄清嗎? –

+1

再次感謝@Andy Barbour,我希望藍色曲線通過一些最大值(例如,在第一個峯值29.5攝氏度)。目前,預測的最高峯(​​藍色曲線)約在28.8攝氏度左右。我不確定如何在lm中對此進行優化。對於nls,我認爲我可以通過改變我的初始參數值(這也是一個棘手的部分)來實現這一點。 :) – Eddie

4

如何選擇一個X和Ÿ,而這樣做你的線圖,而不是隻選擇Y.

plot(time,predict(fit.nls),type="l", col="red", xlim=c(1, 900), pch=19, ann=FALSE, xaxt="n", 
yaxt="n") 

還兼具lmnls只是給你的擬合點。所以你必須估計其餘的點以便繪製一條曲線,一條線圖。由於您使用的是nlslm,因此功能predict也許有用。

1

不知道這可能會幫助 - 我只得到了類似的使用配合正弦:

y = amplitude * sin(pi * (x - center)/width) + Offset 

amplitude = 2.0009690806953033E+00 
center = -2.5813588834888215E+01 
width = 1.8077550471975817E+02 
Offset = 2.6872265116104828E+01 

Fitting target of lowest sum of squared absolute error = 3.6755174406241423E+01 

Degrees of freedom (error): 90 
Degrees of freedom (regression): 3 
Chi-squared: 36.7551744062 
R-squared: 0.816419142696 
R-squared adjusted: 0.810299780786 
Model F-statistic: 133.415731033 
Model F-statistic p-value: 1.11022302463e-16 
Model log-likelihood: -89.2464811027 
AIC: 1.98396768304 
BIC: 2.09219299292 
Root Mean Squared Error (RMSE): 0.625309918107 

amplitude = 2.0009690806953033E+00 
     std err squared: 1.03828E-02 
     t-stat: 1.96374E+01 
     p-stat: 0.00000E+00 
     95% confidence intervals: [1.79853E+00, 2.20340E+00] 
center = -2.5813588834888215E+01 
     std err squared: 2.98349E+01 
     t-stat: -4.72592E+00 
     p-stat: 8.41245E-06 
     95% confidence intervals: [-3.66651E+01, -1.49621E+01] 
width = 1.8077550471975817E+02 
     std err squared: 3.54835E+00 
     t-stat: 9.59680E+01 
     p-stat: 0.00000E+00 
     95% confidence intervals: [1.77033E+02, 1.84518E+02] 
Offset = 2.6872265116104828E+01 
     std err squared: 5.15458E-03 
     t-stat: 3.74289E+02 
     p-stat: 0.00000E+00 
     95% confidence intervals: [2.67296E+01, 2.70149E+01] 

Coefficient Covariance Matrix 
[ 0.02542366 0.01786683 -0.05016085 -0.00652111] 
[ 1.78668314e-02 7.30548346e+01 -2.18160818e+01 1.24965136e-01] 
[ -5.01608451e-02 -2.18160818e+01 8.68860810e+00 -1.27401806e-02] 
[-0.00652111 0.12496514 -0.01274018 0.0126217 ] 

詹姆斯·菲利普斯 [email protected]

+1

謝謝@詹姆斯菲利普斯。確實如此。你可能想檢查這篇文章http://stats.stackexchange.com/questions/60500/how-to-find-a-good-fit-for-semi-sinusoidal-model-in-r – Eddie

0

或者,你可以從你的數據中消除在NAS在看完後:

data <- subset(data, !is.na(temperature)) 

然後,打印時,您可以將X軸設定爲縮減數據集合的時間點:

plot(temp~time, data=data, xlim=c(1, 900)) 
lines(x=time, y=fit.lm$fitted, col="red") 

這條曲線不會像@ andy-barbour生成的曲線那麼平滑,但它可以在捏合中工作。