2015-07-19 64 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