在R中使用lm,nls和nls2进行正弦曲线拟合

问题描述 投票:1回答:1

我获取了数据(电机适应= y,取决于延迟= t),我希望它看起来像一个正弦波。我正在尝试(1)在数据中拟合正弦曲线,并(2)估算最佳模型/参数。我读了几篇文章hereherehere,但我仍在挣扎。

1)首先我尝试使用lm

CODE

  t<-c(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
  y<-c(0.310 ,0.630 ,0.430 ,0.245, 0.650 ,0.085 ,0.370, 0.560 ,0.250, 0.520)
reslm <- lm(y ~ sin(pi/2*t)+ cos(pi/2*t)) #my period is supposed to be 4, so period equals to pi/2
summary(reslm)
rg<-(max(y)-min(y)/2)
plot(y~t)
lines(fitted(reslm)~t,col=4,lty=2) 

输出

lm(formula = y ~ sin(pi/2 * t) + cos(pi/2 * t))

Residuals:
     Min       1Q   Median       3Q      Max 
-0.32450 -0.13956 -0.00325  0.14819  0.24450 

Coefficients:
              Estimate Std. Error t value Pr(>|t|)    
(Intercept)   0.404375   0.067993   5.947 0.000572 ***
sin(pi/2 * t) 0.005125   0.095190   0.054 0.958567    
cos(pi/2 * t) 0.001125   0.095190   0.012 0.990900    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.2107 on 7 degrees of freedom
Multiple R-squared:  0.0004303, Adjusted R-squared:  -0.2852 
F-statistic: 0.001507 on 2 and 7 DF,  p-value: 0.998

GRAPH

enter image description here

问题

-我非常困惑,我该如何改变振幅以及帕氏位移?

-如何使用这种方法来提高身材?

2)然后我尝试使用nls

使用公式y(t)= A <sinω+ Phi)+ C其中A是振幅,Ω是周期,Phi是相移,C是中线。

CODE

t<-c(0, 1, 2, 3, 4, 5, 6, 7, 8, 9) y<-c(0.310 ,0.630 ,0.430 ,0.245, 0.650 ,0.085 ,0.370, 0.560 ,0.250, 0.520) A<- (max(y)-min(y)/2) C<-((max(y)+min(y))/2) res1<- nls(y ~ A*sin(omega*t+phi)+C, data=data.frame(t,y), start=list(A=A,omega=pi/2,phi=0,C=C)) summary(res1) co <- coef(res1) resid(res1) sum(resid(res1)^2) fit <- function(x, a, b, c, d) {a*sin(b*x+c)+d} # Plot result plot(x=t, y=y) curve(fit(x, a=co["A"], b=co["omega"], c=co["phi"], d=co["C"]), add=TRUE ,lwd=2, col="steelblue")

输出

Formula: y ~ A * sin(omega * t + phi) + C

Parameters:
       Estimate Std. Error t value Pr(>|t|)    
A       0.21956    0.03982   5.513   0.0015 ** 
omega   2.28525    0.07410  30.841 7.72e-08 ***
phi   -32.57364    0.40375 -80.678 2.44e-10 ***
C       0.41146    0.02926  14.061 8.07e-06 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.09145 on 6 degrees of freedom

Number of iterations to convergence: 18 
Achieved convergence tolerance: 9.705e-06

GRAPH

enter image description here

问题

-此方法似乎效果更好。但是如何使用这种方法来改善拟合度呢?我尝试手动更改一些参数,但是例如更改相移(phi)并不会做太多或导致错误(请参阅第3部分)。

3)然后我尝试使用nls和nsl2,以便调整模型

CODE

###nls2 t<-c(0, 1, 2, 3, 4, 5, 6, 7, 8, 9) y<-c(0.310 ,0.630 ,0.430 ,0.245, 0.650 ,0.085 ,0.370, 0.560 ,0.250, 0.520) A <- (max(y)-min(y)/2) C<-((max(y)+min(y))/2) pp <- expand.grid(omega=(c(2.094395, 1.570796, 1.256637)), phi=(-1:1), A=A, C=C) # omega = 2*pi/3, pi/2 , 2*pi/5 View(pp) pp1<-data.frame(pp) res2<- nls2(y ~ A*sin(omega*t+phi)+C, data=data.frame(t,y), start=pp1, algorithm = "brute-force") res2 summary(res2) co <- coef(res2) resid(res2) sum(resid(res2)^2) fit <- function(x, a, b, c, d) {a*sin(b*x+c)+d} # Plot result plot(x=t, y=y) curve(fit(x, a=co["A"], b=co["omega"], c=co["phi"], d=co["C"]), add=TRUE ,lwd=2, col="steelblue") #optimisation res3<-nls2(y ~ A*sin(omega*t+phi)+C, start = res2) res3 summary(res3) co3 <- coef(res3) resid(res3) sum(resid(res3)^2) fit <- function(x, a, b, c, d) {a*sin(b*x+c)+d} # Plot result plot(x=t, y=y) curve(fit(x, a=co3["A"], b=co["omega"], c=co3["phi"], d=co3["C"]), add=TRUE ,lwd=2, col="steelblue")

输出

第一次尝试(nls2 model1)

model: y ~ A * sin(omega * t + phi) + C data: data.frame(t, y) omega phi A C 2.0944 0.0000 0.6075 0.3675 residual sum-of-squares: 0.8545 Number of iterations to convergence: 9 Achieved convergence tolerance: NA > summary(res2) Formula: y ~ A * sin(omega * t + phi) + C Parameters: Estimate Std. Error t value Pr(>|t|) omega 2.09440 0.08453 24.776 2.84e-07 *** phi 0.00000 0.46494 0.000 1.0000 A 0.60750 0.17851 3.403 0.0144 * C 0.36750 0.12044 3.051 0.0225 * --- Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1 Residual standard error: 0.3774 on 6 degrees of freedom Number of iterations to convergence: 9 Achieved convergence tolerance: NA

GRAPH

enter image description here

第二次尝试(nls2 model2)

Nonlinear regression model model: y ~ A * sin(omega * t + phi) + C data: <environment> omega phi A C 2.2852 -1.1577 0.2196 0.4115 residual sum-of-squares: 0.05018 Number of iterations to convergence: 12 Achieved convergence tolerance: 8.075e-06 > summary(res3) Formula: y ~ A * sin(omega * t + phi) + C Parameters: Estimate Std. Error t value Pr(>|t|) omega 2.28524 0.07410 30.841 7.72e-08 *** phi -1.15769 0.40375 -2.867 0.0285 * A 0.21956 0.03982 5.513 0.0015 ** C 0.41146 0.02926 14.061 8.07e-06 *** --- Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1 Residual standard error: 0.09145 on 6 degrees of freedom Number of iterations to convergence: 12 Achieved convergence tolerance: 8.075e-06

GRAPH

enter image description here

问题

-所以在这里我似乎误解了nls2在做什么,因为我发现与第2部分完全相同的结果...我仍然不知道哪个参数是最好的...我该怎么做?

4)然后,我尝试使用nls,以通过遍历几个参数来调整我的模型

CODE

t<-c(0, 1, 2, 3, 4, 5, 6, 7, 8, 9) y<-c(0.310 ,0.630 ,0.430 ,0.245, 0.650 ,0.085 ,0.370, 0.560 ,0.250, 0.520) A <- (max(y)-min(y)/2) C<-((max(y)+min(y))/2) pp <- expand.grid(omega=(c(2.094395, 1.570796, 1.256637)), phi=(-1:1), A=A, C=C) # omega = 2*pi/3, pi/2 , 2*pi/5 #View(pp) fit_AIC<- vector() fit_BIC<- vector() coef_A<- vector() coef_ome<- vector() coef_phi<- vector() coef_C<- vector() RSS<-vector() for (ii in 1:nrow(pp)) { res<- nls(y ~ A*sin(omega*t+phi)+C, data=data.frame(t,y), start=list(A=pp$A[ii],omega=pp$omega[ii],phi=pp$phi[ii],C=pp$C[ii]), trace = TRUE) fit_AIC[ii]<-AIC(res) fit_BIC[ii]<-BIC(res) coef_A[ii]<- coef(res)[1] coef_ome[ii]<- coef(res)[2] coef_phi[ii]<- coef(res)[3] coef_C[ii]<- coef(res)[4] RSS<-sum(resid(res)^2) } results<-data.frame(RSS, fit_AIC, fit_BIC, coef_A, coef_ome, coef_phi, coef_C) View(results)

输出

我遇到错误...

1.405742 : 0.607500 2.094395 -1.000000 0.367500 0.1448148 : 0.1563179 2.1441802 -0.9937729 0.4172079 ... 0.05018035 : 0.2195573 2.2852482 -1.1577097 0.4114573 2.085664 : 0.607500 1.570796 1.000000 0.367500 0.3104012 : 0.01321257 1.60518024 0.83201816 0.40437498 0.3098916 : 0.0180852 3.0888764 -5.9933691 0.4060743 Error in nls(y ~ A * sin(omega * t + phi) + C, data = data.frame(t, y), : le pas 0.000488281 est devenu inférieur à 'minFactor' de 0.000976562 RSS fit_AIC fit_BIC coef_A coef_ome coef_phi coef_C 1 0.05018035 -14.568398 -13.055473 0.21955754 2.2852455 -1.1576955 0.4114573 2 0.05018035 2.753153 4.266079 0.07487110 0.8575642 0.2299909 0.3916769 3 0.05018035 2.753153 4.266079 0.07487109 0.8575736 0.2299951 0.3916763 4 0.05018035 -14.568398 -13.055473 0.21955763 2.2852443 -1.1576894 0.4114573 5 0.05018035 -14.568398 -13.055473 0.21955729 2.2852490 -32.5736406 0.4114573 6 0.05018035 2.753153 4.266079 0.07487105 0.8575619 0.2300021 0.3916770 7 0.05018035 -14.568398 -13.055473 0.21955735 2.2852482 -1.1577097 0.4114573

问题

-所以此错误似乎是因为我的初始参数错误。它是否正确?但是,如果大多数参数不起作用,该如何估算最佳参数?

-此外,尽管参数不同,我也不明白为什么RSS总是相同的

-为什么在模型不同的情况下为什么只观察2种不同的AIC和2种不同的BIC?

任何帮助将不胜感激,谢谢

我获取了数据(电机适应= y,取决于延迟= t),我希望它看起来像一个正弦波。我正在尝试(1)在数据中拟合正弦曲线,并(2)估算最佳模型/参数。我...

r trigonometry lm nls
1个回答
0
投票
© www.soinside.com 2019 - 2024. All rights reserved.