【问题标题】:Error in nonlinear least squeares in R - Logistic and Gompertz curvesR - Logistic 和 Gompertz 曲线中的非线性最小平方误差
【发布时间】:2023-03-31 06:40:01
【问题描述】:

我正在研究变量 y 的模型,我打算在其中使用时间作为解释变量。我选择了 Gompertz 和逻辑曲线作为候选者,但是当我尝试估计系数时(同时使用 nls 和 nls2),我最终会得到不同的错误(奇异性或步长因子降低到“minFactor”以下)。我真的很感激任何帮助。这是我的代码和 info 对象的 deput 版本。

我根据http://www.metla.fi/silvafennica/full/sf33/sf334327.pdf中的条件选择了初始值

library(nls2)

> dput(info)
structure(list(y = c(0.308, 0.279, 0.156, 0.214, 0.224, 0.222, 
0.19, 0.139, 0.111, 0.17, 0.155, 0.198, 0.811, 0.688, 0.543, 
0.536, 0.587, 0.765, 0.667, 0.811, 0.587, 0.617, 0.586, 0.633, 
2.231, 2.202, 1.396, 1.442, 1.704, 2.59, 2.304, 3.026, 2.7, 3.275, 
3.349, 3.936, 9.212, 8.773, 6.431, 6.983, 7.169, 9.756, 10.951, 
13.938, 14.378, 18.406, 24.079, 28.462, 51.461, 46.555, 39.116, 
43.982, 41.722), t = 1:53), class = c("tbl_df", "tbl", "data.frame"
), row.names = c(NA, -53L))

summary(gomp_nls <- nls2(y ~ alpha*exp(-beta*exp(-gamma*t)), 
                 data = info, 
                 start = list(alpha = 40, beta = 4.9, gamma = 0.02), 
                 algorithm = "default")
        )

summary(logist_nls <- nls2(y ~ alpha/(1+beta*exp(-gamma*t)), 
                          data = info, 
                          start = list(alpha = 40, beta = 128, gamma = 0.02), 
                          algorithm = "default"))
        )

感谢您的帮助

【问题讨论】:

  • 这些是 sigmoid 增长的模型。您的数据没有显示为 sigmoid 的迹象。请尝试拟合一个简单的指数增长模型。
  • 嗨,在这个数据集中,y 是移民到一个国家,所以它不可能是指数的,它必须达到一个饱和点
  • 统计数据并不神奇。如果您的数据没有显示饱和点的迹象,则模型将无法找到它。 (这个讨论属于 stats.stackexchange.com 网站,而不是编程网站。)

标签: r nls non-linear-regression convergence


【解决方案1】:

nls2"default" 算法是使用nls。您想指定"brute-force" 或其他算法之一来查找初始值。起始值应该是两行的数据框,这样它将填充以潜在起始值定义的超立方体。

然后它将计算每个起始值的残差平方和,并返回公式给出最小平方和的起始值。

如果您发现nls2 返回的结果在您定义的区域的边界,则放大该区域并重试。 (如果返回的起始值足够好,您可能不需要这一步。)

最后用你找到的起始值运行nls

library(nls2)

## 1

fo1 <- y ~ alpha*exp(-beta*exp(-gamma*t))
st1 <- data.frame(alpha = c(10, 100), beta = c(1, 100), gamma = c(0.01, 0.20))
fm1.0 <- nls2(fo1, data = info, start = st1, algorithm = "brute-force")

fm1 <- nls(fo1, data = info, start = coef(fm1.0))

## 2

fo2 <- y ~ alpha/(1+beta*exp(-gamma*t))
st2 <- data.frame(alpha = c(10, 1000), beta = c(1, 10000), gamma = c(0.01, 0.20))
fm2.0 <- nls2(fo2, data = info, start = st2, algorithm = "brute-force")

fm2 <- nls(fo2, data = info, start = coef(fm2.0))

# plot both fits

plot(y ~ t, info)
lines(fitted(fm1) ~ t, info, col = "blue")
lines(fitted(fm2) ~ t, info, col = "red")

注意

请注意,对于显示的数据,这两个 2 参数指数模型拟合得相当好,所以如果您只对它呈指数上升的范围感兴趣,那么这些可能是可以考虑的替代方案。 (下面第一个更好,因为系数彼此更相似。第二个可能有缩放问题。)

fm3 <- nls(y ~ a * exp(b/t), info, start = c(a = 1, b = 1))
fm4 <- nls(y ~ a * t^b, info, start = c(a = .001, b = 6))

【讨论】:

    猜你喜欢
    • 2018-12-27
    • 1970-01-01
    • 2012-02-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多