【问题标题】:Errors in nls() - singular gradient or NaNs producednls() 中的错误 - 产生奇异梯度或 NaN
【发布时间】:2021-04-06 21:07:48
【问题描述】:

我正在尝试将我的光合作用数据拟合到一个 nls 函数,它是一个非矩形双曲线函数。到目前为止,我在为 nls 获取正确的起始值方面遇到了一些问题,因此,我遇到了很多错误,例如“奇异梯度”、“产生的 NaN”或“步长因子 0.000488281 降低到 0.000976562 的“minFactor”以下'。您能否就找到最佳起始值提出一些建议?提前致谢!

代码和数据如下:

#Dataframe
PPFD <- c(0,0,0,50,50,50,100,100,100,200,200,200,400,400,400,700,700,700,1000,1000,1000,1500,1500,1500)
Cultivar <- c(-0.7,-0.8,-0.6,0.6,0.5,0.8,2.0,2.0,2.3,3.6,3.7,3.7,5.7,5.5,5.8,9.7,9.6,10.0,14.7,14.4,14.9,20.4,20.6,20.9)
NLRC <-data.frame(PPFD,Cultivar)

#nls regression
reg_nrh <- nls(Cultivar ~ (1/(2*Theta))*(AQY*PPFD+Am-sqrt((AQY*PPFD+Am)^2-4*AQY*Theta*Am*PPFD))-Rd, data = NLRC, start=list(Am = max(NLRC$Cultivar)-min(NLRC$Cultivar), AQY = 0.05, Rd=-min(NLRC$Cultivar), Theta = 1))

#estimated parameters for plotting
Amnrh <- coef(reg_nrh)[1]
AQYnrh <- coef(reg_nrh)[2]
Rdnrh <- coef(reg_nrh)[3]
Theta <- coef(reg_nrh)[4]

#plot
plot(NLRC$PPFD, NLRC$Cultivar, main = c("Cultivar"), xlab="", ylab="", ylim=c(-2,40),cex.lab=1.2,cex.axis=1.5,cex=2)+mtext(expression("PPFD ("*mu*"mol photons "*m^-2*s^-1*")"),side=1,line=3.3,cex=1.5)+mtext(expression(P[net]*" ("*mu*"mol "*CO[2]*" "*m^-2*s^-1*")"),side=2,line=2.5,cex=1.5)

#simulated value
ppfd = seq(from = 0, to = 1500)
pnnrh <- (1/(2*Theta))*(AQYnrh*ppfd+Amnrh-sqrt((AQYnrh*ppfd+Amnrh)^2-4*AQYnrh*Theta*Amnrh*ppfd))- Rdnrh
lines(ppfd, pnnrh, col="Green")

【问题讨论】:

    标签: r non-linear-regression


    【解决方案1】:

    如果我们

    1. 取0的最大值和sqrt内的表达式,避免取负平方根
    2. 将 Theta 修复为 0.8
    3. 使用 lm 获取 AQY 和 Am 的起始值

    然后收敛

    Theta <- 0.8
    fm <- lm(Cultivar ~ PPFD, NLRC)
    st <- list(AQY = coef(fm)[[2]], Rd = -min(NLRC$Cultivar), Am = coef(fm)[[1]])
    fo <- Cultivar ~ 
      (1/(2*Theta))*(AQY*PPFD+Am-sqrt(pmax(0, (AQY*PPFD+Am)^2-4*AQY*Theta*Am*PPFD)))-Rd
    reg <- nls(fo, data = NLRC, start = st)
    
    deviance(reg)  # residual sum of squares
    ## [1] 5.607943
    
    plot(Cultivar ~ PPFD, NLRC)
    lines(fitted(reg) ~ PPFD, NLRC, col = "red")
    

    (图片后续)

    请注意,下面的第一个模型只有两个参数,但残差平方和较低(越低越好)。

    reg2 <- nls(Cultivar ~ a * PPFD^b, NLRC, start = list(a = 1, b = 1))
    deviance(reg2)
    ## [1] 5.098796
    

    这些具有较高的残差平方和,但确实具有非常简单的优点。

    deviance(fm) # fm defined above
    ## [1] 6.938648
    
    fm0 <- lm(Cultivar ~ PPFD + 0, NLRC) # same as fm except no intercept
    deviance(fm0)
    ## [1] 7.381632
    

    【讨论】:

    • 感谢您对我的问题的精彩解释!虽然 theta 应该是 0.8~0.9,但我想我可以根据你的建议找到合适的起始值。真的很感激!
    • 已对其进行修改以将 Theta 固定为 0.8(尽管将其固定为 Theta = -2 实际上会产生更小的残差平方和)。
    • 最终,我没有使用固定的 theta,而是在感兴趣的范围(0.8 到 0.99)内制作了一个包含“theta”序列的向量,并将它们用作“for 循环”的索引根据 AIC 的结果找到最佳的 theta 值。估计的 theta 不仅可以很好地拟合情节,而且可以得到更好的统计结果。感谢您的代码和建议,以帮助我思考这种方法!
    猜你喜欢
    • 2017-09-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-13
    • 1970-01-01
    • 2023-02-02
    • 2023-04-03
    • 2014-08-27
    相关资源
    最近更新 更多