NLS 曲线拟合奇异矩阵误差

NLS Curve Fit Singular matrix error

我需要帮助拟合 nls 并找到不会导致奇异矩阵的初始估计。我将不胜感激任何帮助。

via_data$Concentration <- c(0.197, 0.398, 0.792, 1.575,
                            3.154, 6.270, 12.625, 25.277,
                            25.110, 49.945, 74.680)
via_data$Viability <- c(100, 94.62, 96.21, 87.53, 
                        80,  62.22,  39.11, 
                        30.80,  30, 22, 2.56) 
x <- via_data$Concentration
y <- via_data$Viability
fit <- nls(y ~((1/(1+Epsup/x)^Bup)*(1/(1+Epsdn/x)^Bdn)), start=list(Epsup=0, Bup=1, Epsdn=10, Bdn=-5), trace=T)

Error in nlsModel(formula, mf, start, wts) : 
  singular gradient matrix at initial parameter estimates

谢谢, 克里纳

下面 st 是您的起始值,除了我们使用 Epsup=1 来避免在 0 处退化。fo 是公式。为了防止将负数提高到幂,我们将 Epsup 替换为 sqrt(Epsup^2) 并且类似地替换 Epsdn - 这增加了 EpsupEspdn 不能的假设消极的。 (这与使用 abs(Epsup) 相同;但是,nlxb 在其导数 table 中没有 abs。)接下来使用 nls2 在网格上生成值边界 st/1010*stnls2 将生成这些和 return 一个 "nls" 对象,其中包含找到的最佳对象。现在将其用作 nlmrt 包的 nlxb 的起始值。它比 nls 更好地处理难题。 nlxb 没有 return 一个 "nls" 对象(尽管包确实有 wrapnls 运行 nlxb 然后运行 ​​nls 但是我们不从 nlxb 获取直接输出),因此再次将其输入 nls2 以创建一个 "nls" 对象,允许我们使用 fitted 方法。我们绘制结果拟合。

library(nlmrt)
library(nls2)

st <- c(Epsup=1, Bup=1, Epsdn=10, Bdn=-5)
fo <- y ~ (1/(1+sqrt(Epsup^2)/x)^Bup)*(1/(1+sqrt(Epsdn^2)/x)^Bdn)

fit.nls2 <- nls2(fo, start = data.frame(rbind(st/10, 10*st)), alg = "brute")
fit.nlxb <- nlxb(fo, data = data.frame(x, y), start = coef(fit.nls2))

给出以下内容:

> fit.nlxb
nlmrt class object: x 
residual sumsquares =  171.2  on  11 observations
    after  19    Jacobian and  25 function evaluations
  name            coeff          SE       tstat      pval      gradient    JSingval   
Epsup            10.7464         10.95     0.9814     0.3591   6.855e-05        1584  
Bup              1.15049        0.5928      1.941    0.09345    0.001839       120.2  
Epsdn            642.754         908.5     0.7075     0.5021  -1.298e-06       1.406  
Bdn             -1.13885        0.6315     -1.804     0.1143    0.004964    0.005443 

并绘图以直观地评估拟合度:

fit.nlxb.nls <- nls2(fo, start = coef(fit.nlxb))
plot(y ~ x)
lines(fitted(fit.nlxb.nls) ~ x)

注意:我们使用了这个输入:

via_data <- data.frame(Concentration = c(0.197, 0.398, 0.792, 1.575,
     3.154, 6.270, 12.625, 25.277, 25.110, 49.945, 74.680),
Viability = c(100, 94.62, 96.21, 87.53, 80,  62.22,  39.11, 
                        30.80,  30, 22, 2.56))
x <- via_data$Concentration
y <- via_data$Viability