Google Sheets 拟合模型是检索 nls() 起始参数的有效位置吗?

Is a Google Sheets fit model a valid place to retrieve starting parameters for nls()?

我正在尝试使用 nls() 函数将 R 中形式为 y = a*e^(x*b) 的指数模型拟合到我在下面 运行 的数据中。我在这里和其他地方读到我需要为 ab 提供模型合理的参数,但是获取这些起始参数的方式似乎非常多变,许多建议的方法都是方法我找不到详细说明。一个建议说您可以将数据复制到 Excel 电子表格中,在图表上拟合模型,然后调整参数,直到它看起来与数据相当吻合。好吧,我进入Google Sheets,根据下面的数据插入图表,然后选择Customize > Series > Trendline (exponential),它给我一个公式5.51e^0.015x。我可以将这些有效值用作我的起始参数吗? Google Sheets 是否有效地产生了这些,或者我需要做修补方法,还是尝试其他方法?我一遍又一遍地阅读了选择合适的起始值的重要性,因此我们将不胜感激。我的教育背景没有涵盖非线性模型。

x       y
19.005  5.49
18.19   6
19.59   5.885
19.93   8.96
17.615  13.85
18.795  2.72
19.11   8.09
19.885  8.11
15.76   6.66
16.48   6.27
15.805  5.375
15.825  3.06
15.985  7.795
15.755  6.255
15.485  5.925
15.475  9.925
16.45   6.055
16.285  5.24
15.92   11.15
16.775  5.57
16.075  3.275
16.475  5.635
16.825  4.72
16.28   2.035
17.26   6.07
17.245  4.9
17.98   8.06
17.35   6.94
18.22   7.8
16.27   12.2
17.555  7.335
16.98   5.76
17.415  7.51
17.5    6.18

对于问题中显示的数据,我们可以只使用 b = 1 的起始值。如果我们使用 nlsplinear 算法,则不需要起始值线性参数,a。在这种情况下,不应在公式中指定 a,因为它已经暗示了。它将在输出中报告为 .lin。在代码的第一行中,我们对 DF 进行排序,给出 DFs 以便于以后绘图。

DFs <- DF[order(DF$x), ]
fo <- y ~ exp(b * x)
fm <- nls(fo, DFs, start = list(b = 1), algorithm = "plinear")

但是,如果 nls 不适用于其他一些数据,那么由于 y 是严格正的,我们可以对双方进行对数以获得线性模型 fm0 可以是适合 lm 以获得 b 的起始值。使用上面的 plinear 算法可以避免必须为 a 指定起始值。 DFsfo来自上面。

fm0 <- lm(log(y) ~ x, DFs)
fm2 <- nls(fo, DFs, start = list(b = coef(fm0)[[2]]), algorithm = "plinear")
fm2

## Nonlinear regression model
##   model: y ~ exp(b * x)
##    data: DFs
##       b    .lin 
## 0.02819 4.10908 
##  residual sum-of-squares: 205.6
##
## Number of iterations to convergence: 3 
## Achieved convergence tolerance: 2.073e-06

plot(y ~ x, DFs)
lines(fitted(fm2) ~ x, DFs, col = "red")

备注

可复制形式的输入:

Lines <- "x       y
19.005  5.49
18.19   6
19.59   5.885
19.93   8.96
17.615  13.85
18.795  2.72
19.11   8.09
19.885  8.11
15.76   6.66
16.48   6.27
15.805  5.375
15.825  3.06
15.985  7.795
15.755  6.255
15.485  5.925
15.475  9.925
16.45   6.055
16.285  5.24
15.92   11.15
16.775  5.57
16.075  3.275
16.475  5.635
16.825  4.72
16.28   2.035
17.26   6.07
17.245  4.9
17.98   8.06
17.35   6.94
18.22   7.8
16.27   12.2
17.555  7.335
16.98   5.76
17.415  7.51
17.5    6.18"
DF <- read.table(text = Lines, header = TRUE)

我写了一个与@G.Grothendieck 类似的答案...总的来说,您可以 使用Google 表格,或者Excel,或其他一些工具,以获取 nls() 的起始值,但没有必要。

我使用 dd <- read.table(header=TRUE, text="x y\n19.005 5.49 ...")

加载了您的数据

适合log-linear模型

m1 <- lm(log(y)~x,data=dd)
cc <- coef(m1)
## (Intercept)           x 
##   1.1404581   0.0399405 

log-linear 模型实际上并没有给出与 nls() 完全相同的答案(尽管对于初始值来说已经足够好了),因为它对误差分布做出了不同的隐式假设(log-linear 假设方差在对数尺度上是常数 ,而 non-linear 拟合假设方差在原始尺度上是常数,除非您另有说明)。

log-link GLM

另一个有用的替代方法是 广义 线性模型拟合高斯响应和对数 link。这实际上适合与 nls()

完全相同的模型
m2 <- glm(y~x, family=gaussian(link="log"), data=dd)
cc2 <- coef(m2)
## (Intercept)           x 
##  1.41320439  0.02819136 

...如果将这些系数值与 nls() 找到的系数值进行比较,您可以看到...

s <- list(a=exp(cc2[[1]]), b= cc2[[2]])
m3 <- nls(y~a*exp(b*x), data=dd, start=s)
coef(m3)

一些不同的预测和可视化方法...

par(las=1,bty="l")
plot(y~x,data=dd)
lines(dd$x,exp(predict(m1)))
lines(dd$x,exp(cc[1])*exp(cc[2]*dd$x), col=2,lty=2)

lines(dd$x, predict(m2,type="response"), col=3)
lines(dd$x, exp(cc2[1])*exp(cc2[2]*dd$x), col=4,lty=2)
legend("topright",col=1:4,lty=rep(1:2,2),
       c("lm(log) predict","lm(log) formula","glm predict","glm formula"))
dev.off()