Fit 'nls': 初始参数估计处的奇异梯度矩阵

Fit 'nls': singular gradient matrix at initial parameter estimates

我是 'nls' 的新手,在查找起始参数时遇到问题。我已经阅读了几篇文章并尝试了各种参数和公式构造,但我总是出错。

这是我正在做的事情的一个小例子,如果有人能给我一些提示,我将不胜感激!

# Data to which I want to fit a non-linear function
x <- c(0,  4, 13, 30, 63, 92)
y <- c(0.00000000, 0.00508822, 0.01103990, 0.02115466, 0.04036655, 0.05865331)
z <- 0.98

# STEPS:
# 1 pool, z fixed. This works.
fit <- nls(y ~ z * ((1 - exp(-k1*x))),
           start=list(k1=0))


# 2 pool model, z fixed
fit2 <- nls(y ~ z * (1 - exp(-k1*x)) + (1 - exp(-k2*x)),
            start=list(k1=0, k2=0)) # Error: singular gradient matrix at initial parameter estimates


# My goal: 2 pool model, z free
fit3 <- nls(y ~ z * (1 - exp(-k1*x)) + (1 - exp(-k2*x)),
            start=list(z=0.5, k1=0, k2=0)) 

你问这个问题已经有一段时间了,但也许你仍然对一些评论感兴趣:

至少你的 fit2 在改变起始参数时工作正常(见下面的代码和图表)。我猜 fit3 只是一个 "too complicated" 模型,因为这些数据基本上遵循线性趋势。这意味着两个参数通常足以合理地描述数据(参见第二个图)。

所以作为一般提示:当您获得

singular gradient matrix at initial parameter estimates

你可以

1) 改变起始 values/your 初始参数估计值

and/or

2) 尝试通过查找通常会引起麻烦的冗余参数来简化模型。

我还强烈建议始终先绘制数据和您的初始猜测(另请检查 )。

这是一个图表,显示了您的 fitfit2 和我定义的第三个函数的结果,代码如下:

如您所见,fit2 与具有变量 z 和一个附加指数的函数之间几乎没有区别。两个参数似乎足以合理地描述系统(也有一个已经很好地用上图中的黑线表示)。如果您随后想通过某个数据点拟合一条线,您还可以查看 .

那么当我们使用一个带有两个自由参数的线性函数和一个带有变量 z、一个指数项和一个变量偏移量的函数时,它现在看起来像什么?如下图所示;同样没有太大区别:

残差如何比较?

> fit
Nonlinear regression model
  model: y ~ zfix * ((1 - exp(-k1 * x)))
   data: parent.frame()
       k1 
0.0006775 
 residual sum-of-squares: 1.464e-05

> fit2
Nonlinear regression model
  model: y ~ zfix * (1 - exp(-k1 * x)) + (1 - exp(-k2 * x))
   data: parent.frame()
        k1         k2 
-0.0006767  0.0014014 
 residual sum-of-squares: 9.881e-06

> fit3
Nonlinear regression model
  model: y ~ Z * (1 - exp(-k1 * x))
   data: parent.frame()
       Z       k1 
0.196195 0.003806 
 residual sum-of-squares: 9.59e-06

> fit4
Nonlinear regression model
  model: y ~ a * x + b
   data: parent.frame()
        a         b 
0.0006176 0.0019234 
 residual sum-of-squares: 6.084e-06

> fit5
Nonlinear regression model
  model: y ~ z * (1 - exp(-k1 * x)) + k2
   data: parent.frame()
       z       k1       k2 
0.395106 0.001685 0.001519 
 residual sum-of-squares: 5.143e-06

正如人们所猜测的那样,只有一个自由参数的拟合给出了最差的结果,而具有三个自由参数的拟合给出了最好的结果;然而,并没有太大的区别(在我看来)。

这是我使用的代码:

x <- c(0,  4, 13, 30, 63, 92)
y <- c(0.00000000, 0.00508822, 0.01103990, 0.02115466, 0.04036655, 0.05865331)
zfix <- 0.98

plot(x,y)

# STEPS:
# 1 pool, z fixed. This works.
fit <- nls(y ~ zfix * ((1 - exp(-k1*x))), start=list(k1=0))
xr = data.frame(x = seq(min(x),max(x),len=200))
lines(xr$x,predict(fit,newdata=xr))

# 2 pool model, z fixed
fit2 <- nls(y ~ zfix * (1 - exp(-k1*x)) + (1 - exp(-k2*x)), start=list(k1=0, k2=0.5))
lines(xr$x,predict(fit2,newdata=xr), col='red')

# 3 z variable
fit3 <- nls(y ~ Z * (1 - exp(-k1*x)), start=list(Z=zfix, k1=0.2))
lines(xr$x,predict(fit3,newdata=xr), col='blue')

legend('topleft',c('fixed z, single exp', 'fixed z, two exp', 'variable z, single exp'), 
       lty=c(1,1,1),
       lwd=c(2.5,2.5,2.5),
       col=c('black', 'red','blue'))

#dev.new()
plot(x,y)

# 4 fit linear function a*x + b
fit4 <- nls(y ~ a *x + b, start=list(a=1, b=0.))
lines(xr$x,predict(fit4,newdata=xr), col='blue')

fit5 <- nls(y ~ z * (1 - exp(-k1*x)) + k2,  start=list(z=zfix, k1=0.1, k2=0.5))
lines(xr$x,predict(fit5,newdata=xr), col='red')

legend('topleft',c('linear approach', 'variable z, single exp, offset'), 
       lty=c(1,1),
       lwd=c(2.5,2.5),
       col=c('blue', 'red'))