2015-07-19 36 views
1

我是使用'nls'的新手,并且在查找启动参数时遇到问题。我读过几篇文章,并尝试过各种参数和公式构造,但我一直在收到错误。Fit'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)) 
+0

我加了你的功能的其它功能类型的一些意见以及下面作为一个答案。请让我知道这是否回答你的问题,或者你是否需要任何额外的信息!这是一个相当广泛的话题,所以我不确定我是否发布了你所需要的内容...... – Cleb

回答

2

它已经有一段时间,你问的问题,但也许你仍然有兴趣在一些评论:

至少你fit2正常工作时,一个不同的启动参数(见代码和情节如下) 。我认为fit3就是一个“太复杂”的模型,因为这些数据基本上只是一个线性趋势。这意味着两个参数通常足以很好地描述数据(见第二幅图)。

因此,作为一个一般的提示:当您获得

在初始参数奇异梯度矩阵估计

可以

1)变化的起始值/你的初始参数估计

和/或

2)尝试通过查找通常会导致故障的冗余参数来简化模型。

我也强烈建议您总是先将数据与最初的猜测一起绘制出来(也请查看this question)。

下面是该结果的情节为您fitfit2并在下面的代码中给出由我定义的第三个功能:

enter image description here

正如你所看到的,几乎没有什么区别在你的fit2和具有变量z和一个额外指数的函数之间。两个参数似乎足以很好地描述系统(也可以用上图中的黑线表示相当好)。如果您希望通过某个数据点拟合一条线,则还可以检出this answer

那么现在如何使用具有两个自由参数和变量z,一个指数项和一个可变偏移量的函数的线性函数?如下图所示。又没有太大的差别:

enter image description here

如何残差比较?

> 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')) 
+1

对于延迟回复此答案表示歉意。这是一个非常好的回复,对我来说很有帮助,能够更好地理解nls。非常感谢! – user3262756