【问题标题】:Sine curve fit using lm and nls in R在 R 中使用 lm 和 nls 进行正弦曲线拟合
【发布时间】:2013-12-04 23:04:36
【问题描述】:

我是曲线拟合的初学者,Stackoverflow 上的几篇文章对我很有帮助。

我尝试使用 lmnls 将正弦曲线拟合到我的数据中,但两种方法都显示出奇怪的拟合,如下所示。谁能指出我哪里出错了。我会怀疑与时间有关,但无法正确处理。我的数据可以从here 访问。

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

【问题讨论】:

  • fit.lm 属于 "lm" 类,因此有一个绘图方法。 plot(fit.lm, type.....) 可能是你想要的更多。
  • 公式 2*pi*time/366 中的“366”有什么意义/来自哪里?

标签: r curve-fitting


【解决方案1】:

在绘制线图时选择 X 和 Y 怎么样,而不是只选择 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 函数可能有用。

【讨论】:

    【解决方案2】:

    这是因为 NA 值已从要拟合的数据中删除(并且您的数据中有很多);因此,当您绘制 fit.lm$fitted 时, plot 方法将该系列的索引解释为“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")
    

    这给了我:

    这可能是您所希望的。

    【讨论】:

    • 我只是想知道如何细化以使曲线真正适合最高温度值。
    • @Eddie 我不确定你的意思。你能澄清一下吗?
    • 再次感谢@Andy Barbour,我希望蓝色曲线通过一些最大值(例如,在第一个峰值时为 29.5 摄氏度)。目前,预测的最高峰(​​蓝色曲线)在 28.8 摄氏度左右。我不确定如何在 lm 中改进它。对于 nls,我想我可以通过更改我的初始参数值来实现这一点(这也是一个棘手的部分)。 :)
    • 那么我想你会想使用'weights' 字段;但是,您可能希望通过stats.stackexchange.com 询问
    • 这仅在一个周期= 1个t单位时有效,如果一个周期不是1个t单位,是否可以调整它。还是有其他方法可以做到这一点?我正在尝试为这些数据绘制曲线:t&lt;-c(1,16,32,46,60,75,91,105, 121, 136, 152, 166, 182, 197, 213, 228, 244, 258, 274,289, 305, 319, 335, 350) y&lt;-c(0.07675029,0.06820963,0.05715293,0.05327944,0.05299214,0.05741750,0.07288807,0.11433698,0.26188523,0.35214251,0.46357182,0.55140384,0.59743720,0.60758298,0.59527024,0.55041092,0.46916025,0.39096330,0.27733599,0.20236358,0.12148088,0.08689101,0.08020721,0.07943709)
    【解决方案3】:

    不确定这是否有帮助 - 我只使用正弦得到了类似的拟合:

    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 ]
    

    詹姆斯·菲利普斯 zunzun@zunzun.com

    【讨论】:

    【解决方案4】:

    或者,您可以在读取数据后从数据中消除 NA:

    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 产生的那样平滑,但它会在紧要关头发挥作用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-01-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-02
      • 2018-06-04
      相关资源
      最近更新 更多