如何使用nlsLM避免“误差:初始参数估计时的奇异梯度矩阵”?

时间:2018-07-31 15:48:32

标签: r nls model-fitting

这是我的第一篇文章,所以我希望我正确地介绍了所有内容,并感谢您提供的任何帮助。

我正在尝试对收集的一组原始数据拟合曲线。数据为S型,应通过Shae-Ackers模型(通常用于生物学)解释。在查看本网站上的其他示例之后,我最初尝试使用“ nls”功能进行此操作。但是,我收到以下错误:

  

“误差:初始参数估计值处的奇异梯度矩阵”。

随后,我尝试使用“ nlsLM”功能。据我从该站点上的其他问题了解到,这应该使用替代算法来拟合我的模型,从而避免出现错误。但是,我仍然遇到相同的错误:

  

“误差:初始参数估计值处的奇异梯度矩阵”。

这是我当前正在尝试使用的代码:

library("minpack.lm") 
library("nls2")

L = c(0, 0.0001, 0.0005, 0.001, 0.005, 
0.01, 0.05, 0.1, 0.5, 1, 5, 10, 50) # X- values, inducer concentration.
Fluo = c(23.10263117,
     21.5111054,
     25.01080225,
     32.63906667,
     82.6671047,
     287.1788694,
     812.2339928,
     1308.71973,
     2822.260637,
     3675.085354,
     4634,
     4399.131349,
     4096.759224) # Y-values, fluorescence measurement.

model <- nlsLM(Fluo ~ Fmax*((k1 + k3C0*((L^n)/(kd^n + L^n)))/(1 + k1 + k2C0*((L^n)/(kd^n + L^n)) + k3C0*((L^n)/(kd^n + L^n)))),
           start = c(k1 = 0.009,k2C0 = 37.5,k3C0 = 3.4,kd = 0.09,n = 2.8,Fmax = 7650), algorithm = "LM", trace = TRUE)

plot(log10(L), log10(Fluo), main = "data")
lines(log10(L), log10(fitted(model)), col = "red", lty = 2)  

我提供的初始估计值应该非常接近我要寻找的值,因为这些值先前已在文献中针对我要拟合的系统进行了报道。

所以我的总体问题是:
1.有什么方法可以找到替代的起始估算值,从而避免出现此错误?
2.我可以使用除'nls'或'nlsLM'以外的其他功能来拟合模型吗? (我也看过'nls.lm',但不确定如何正确实现)。

非常感谢您的帮助,如果需要,我很乐意提供其他信息!

1 个答案:

答案 0 :(得分:0)

问题不是要使用哪个优化程序。问题在于模型参数无法识别。

让右侧为:

rhs <- function(k1, k2C0, k3C0, kd, n, Fmax, L) {
  r <- L^n / (kd^n + L^n)
  Fmax*((k1 + k3C0 * r)/(1 + k1 + k2C0*r + k3C0*r))
}

然后请注意,这两个对rhs的调用给出了相同的值(除了0,它退化了):

st <- c(k1 = 0.009, k2C0 = 37.5, k3C0 = 3.4, 
  kd = 0.09, n = 2.8, Fmax = 7650)

rhs1 <- with(as.list(st), rhs(k1, k2C0, k3C0, kd, n, Fmax, L))

r <- with(as.list(st), L^n/(kd^n+L^n))
rhs2 <- with(as.list(st), rhs(2*k1, (k2C0 * r - k1 - r * k3C0)/r, 2*k3C0, 
 kd, n, Fmax/2, L))

all.equal(rhs1[-1], rhs2[-1])
## [1] TRUE

奇异值

我们可以看到奇异值,我们看到最小的两个奇异值非常小,甚至第三个最小的奇异值也比最大的小几个数量级,因此我们将必须修复2或3个参数为了应用任何优化算法。

library(nls2)
fm2 <- nls2(Fluo ~ rhs(k1, k2C0, k3C0, kd, n, Fmax, L), st = st, alg = "brute")
svd(fm2$m$Rmat())[-2]

给予:

$`d`
[1] 1.815654e+04 2.063566e+03 4.100935e+02 4.992959e+01 1.234634e-06
[6] 1.526028e-09

$v
              [,1]          [,2]          [,3]          [,4]          [,5]
[1,] -9.993013e-01  0.0373287823  0.0014810192  1.127961e-03 -2.744777e-09
[2,]  9.184235e-05  0.0058555553 -0.0879560839  3.069373e-03 -9.960997e-01
[3,] -1.388630e-03 -0.0755201221  0.9926417526 -3.431623e-02 -8.820121e-02
[4,]  3.726825e-02  0.9958422212  0.0744652781 -3.692667e-02 -8.316237e-04
[5,]  2.458570e-03  0.0341651105  0.0371291870  9.987232e-01 -2.370720e-09
[6,] -1.845720e-06 -0.0000361664  0.0004803576 -1.661631e-05  2.309941e-03
              [,6]
[1,] -1.187056e-06
[2,]  2.343452e-03
[3,] -2.763882e-04
[4,]  1.622277e-06
[5,] -1.799465e-11
[6,]  9.999972e-01

修复参数

例如,如果将2、5和6(k2C0,n,Fmax)固定为问题中给定的起始值,则会得到以下结果(也显示为图中蓝色的拟合值)。

fm <- with(as.list(st), nls(Fluo ~ rhs(k1, k2C0, k3C0, kd, n, Fmax, L), 
  start = st[-c(2, 5:6)]))

给予:

Nonlinear regression model
  model: Fluo ~ rhs(k1, k2C0, k3C0, kd, n, Fmax, L)
   data: parent.frame()
      k1     k3C0       kd 
 0.04214 49.21873  2.02506 
 residual sum-of-squares: 1737050

Number of iterations to convergence: 8 
Achieved convergence tolerance: 1.947e-06

注意

如果您愿意使用其他公式,则该公式仅具有4个参数(问题中为6),可以提供合理的拟合度。最后显示为红色拟合。

顺便说一句,在问题log10(Fluo)中针对log10(L)作图,但最小化log10(Flou)的平方和-log10(rhs(...))与最小化log10(Flou)不相同Flou的平方和-rhs(...),尽管答案可能很接近。

fm2 <- nls(Fluo ~ L^d / (a + b * L^c), 
 start = c(a = 10e-5, b = 10e-5, c = 1, d = 1))

plot(Fluo ~ L)
lines(fitted(fm) ~ L, col = "blue")
lines(fitted(fm2) ~ L, col = "red")
legend("bottomright", legend = c("fm", "fm2"),
  col = c("blue", "red"), lty = 1, lwd = 2)

screenshot