【问题标题】:nls() : “Error singular gradient matrix at initial parameter estimates ”nls() :“初始参数估计时的误差奇异梯度矩阵”
【发布时间】:2021-02-12 20:54:00
【问题描述】:

我已经阅读了许多类似的问题,但仍然找不到答案。 以下是我用来校准以下方程式的一些数据:

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 时出现同样的错误:

nlsModel(formula, mf, start, wts) 中的错误:初始参数估计处的奇异梯度矩阵

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

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

d_start <- 43

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

当我只使用分子时它可以工作,但这不是我需要的。 任何帮助将不胜感激。

【问题讨论】:

    标签: r nonlinear-optimization nls


    【解决方案1】:

    在第一个 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
    

    【讨论】:

    • 太棒了!谢谢!我认为它解决了我遇到的问题。但是,如果我想使用所有原始参数(即使它太多),您不会认为有办法运行nls
    • 有无数种解决方案。例如,您可以为 t0 和 n 选择任意值,然后求解 k 和 u。虽然看起来很没有意义。还添加了另一个模型(图中的蓝线),它具有较低的残差平方和,并且在视觉上也更适合。
    猜你喜欢
    • 1970-01-01
    • 2014-08-27
    • 1970-01-01
    • 1970-01-01
    • 2018-07-11
    • 1970-01-01
    • 1970-01-01
    • 2023-04-03
    • 2019-01-08
    相关资源
    最近更新 更多