nls() :“初始参数估计的误差奇异梯度矩阵”

nls() : “Error singular gradient matrix at initial parameter estimates ”

我看了很多类似的问题,但还是找不到答案。 这是我用来校准以下方程式的一些数据:

set.seed(100)
i <- sort(rexp(n = 100,rate = 0.01))
Tr <- sort(runif(n = 100,min = 5,max = 100))

k_start <- 3259
u_start <- 0.464
t0_start <- 38
n_start <- -1

i_test <- k_start*Tr^u_start * (5 + t0_start)^n_start

m <- nls(i~(k * Tr^u / (5+t0)^n), start = list(k = k_start, u = u_start,
                                               t0 = t0_start, n = n_start))

当我使用 nlsLM 时出现了同样的错误:

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

对于初始值,我尝试使用 Python 中校准的值,但仍然出现相同的错误。

还有另一种使用该等式的方法,如下所示: 但是,结果还是一样的错误。

d_start <- 43

m <- nls(i ~ (k * Tr^u / d),
         start = list(k = k_start, u = u_start,d=d_start))

当我只使用分子时它起作用了,但这不是我需要的。 非常感谢任何帮助。

在第一个nls中,右边只依赖于k、t0和n k / (5+t0)^n 所以它被过度参数化,因为一个参数可以表示 它们的综合作用。在第二个 nls 中,右侧仅取决于 在 k 和 d 到 k / d 上,所以问题再次被过度参数化并且 一个参数就可以代表它们的综合效果。

摆脱多余的参数并使用收敛的线性模型获取起始值。

fit.lm <- lm(log(i) ~ log(Tr))
co <- coef(fit.lm)
fit <- nls(i ~ k * Tr ^ u, start = list(k = exp(co[[1]]), u = co[[2]]))
fit
## Nonlinear regression model
##   model: i ~ k * Tr^u
##    data: parent.frame()
##         k         u 
## 0.0002139 3.0941602 
##  residual sum-of-squares: 79402
##
## Number of iterations to convergence: 43 
## Achieved convergence tolerance: 5.354e-06

互惠模式

下面我们拟合了一个“倒数模型”,它具有相同数量的参数,但根据作为残差平方和的偏差测量更适合。较低的值表示更适合。

# reciprocal model
fit.recip <- nls(i ~ 1/(a + b * log(Tr)), start = list(a = 1, b = 1))

deviance(fit)
## [1] 79402.17
deviance(fit.recip)
## [1] 25488.1

图形

下面我们绘制了 fit(红色)和 fit.recip(蓝色)模型。

plot(i ~ Tr)
lines(fitted(fit) ~ Tr, col = "red")
lines(fitted(fit.recip) ~ Tr, col = "blue")
legend("topleft", legend = c("fit", "fit.recip"), lty = 1, col = c("red", "blue"))

(剧情后续)

线性

请注意,plinear 算法可以用作替代算法来拟合上面的 fit 模型,以避免必须为 k 提供起始值。它还有一个额外的好处,即在这种情况下它需要的迭代次数要少得多(14 对 45)。对于 plinear,公式应省略线性参数 k,因为它由算法隐含,并将报告为 .lin

nls(i ~ Tr ^ u, start = list(u = co[[2]]), algorithm = "plinear")
## Nonlinear regression model
##   model: i ~ Tr^u
##    data: parent.frame()
##         u      .lin 
## 3.0941725 0.0002139 
##  residual sum-of-squares: 79402
##
## Number of iterations to convergence: 14 
## Achieved convergence tolerance: 3.848e-06