R 中 nls() 函数的正确语法

Right syntax for nls() function in R

我是 R 的新手,我正在尝试使用 nls 函数拟合曲线。 我将首先使用 dgamma 函数生成一条曲线 y,然后我想使用 nls 对其进行拟合。 这是我的玩具示例。

´´´
x <- 1:250
y <- dgamma(x,2,0.02)
df <- data.frame(x=x,y=y)

nls(y~ dgamma(x,a,b),data=df,start =  list(a =2,b =0.4))
´´´

我得到的错误是

numericDeriv(form[[3L]], names(ind), env) 错误: 评估模型时产生的缺失值或无穷大 另外: 警告信息: 在 dgamma(x, a, b) 中:产生 NaNs

我做错了什么?

谢谢

1) nls 这不是语法错误。该算法不收敛。问题是:

  • dgamma 产生大 and/or 小数字导致数值不稳定

  • nls 往往会出现零残差数据的问题,即精确拟合。如果您使用的是 R 4.1,目前是 R 的开发版本,那么添加 nls 参数 control = nls.control(scaleOffset = 1) 可能有助于避免此类问题(参见 https://stat.ethz.ch/R-manual/R-devel/library/stats/html/nls.control.html )。下面我们设法在没有 scaleOffset 的情况下实现收敛,因此它可以在当前版本的 R 上运行。

使用样条拟合创建更多点,例如 1000,然后拟合 log(y) 而不是 y。使用该结果来拟合原始方程,继续使用附加点。

x <- 1:250
y <- dgamma(x, 2, 0.02)

xx <- seq(1, 250, length = 1000)
spl <- spline(x, y, xout = xx)

fo.log <- log(y) ~ dgamma(x, a, b, log = TRUE)
fm.log <- nls(fo.log, data = spl, start = list(a = 2, b = 0.4))

fo <- y ~ dgamma(x, a, b)
fm <- nls(fo, spl, start = coef(fm.log))
fm

给予:

Nonlinear regression model
  model: y ~ dgamma(x, a, b)
   data: spl
   a    b 
2.00 0.02 
 residual sum-of-squares: 4.399e-19

Number of iterations to convergence: 1 
Achieved convergence tolerance: 7.806e-08

2) optim optim 通常适用于非线性最小二乘问题。有了它,我们就可以直接得到一个合适的,而无需上面的变通方法。生成的警告在达到收敛时可以忽略(输出中的convergence = 0)。

rss <- function(p, x, y) sum((y - dgamma(x, p[["a"]], p[["b"]]))^2)
optim(c(a = 2, b = 0.4), rss, x = x, y = y)

给予:

$par
        a         b 
1.9974423 0.0199842 

$value
[1] 5.209388e-09

$counts
function gradient 
      61       NA 

$convergence
[1] 0

$message
NULL