R nls singular gradient

前端 未结 2 1670
时光说笑
时光说笑 2020-12-29 15:17

I\'ve tried searching the other threads on this topic but none of the fixes are working for me. I have the results of a natural experiment and I want to show the number of c

2条回答
  •  有刺的猬
    2020-12-29 15:57

    1) linearize to get starting values You need better starting values:

    # starting values
    fm0 <- nls(log(y) ~ log(f(x, a, b)), dat2, start = c(a = 1, b = 1))
    
    nls(y ~ f(x, a, b), dat2, start = coef(fm0))
    

    giving:

    Nonlinear regression model
      model: y ~ f(x, a, b)
       data: x
            a         b 
    4214.4228   -0.8106 
     residual sum-of-squares: 2388
    
    Number of iterations to convergence: 6 
    Achieved convergence tolerance: 3.363e-06
    

    1a) Similarly we could use lm to get the initial value by writing

    y ~ a * exp(b * x)
    

    as

    y ~ exp(log(a) + b * x)
    

    and taking logs of both to get a model linear in log(a) and b:

    log(y) ~ log(a) + b * x
    

    which can be solved using lm:

    fm_lm <- lm(log(y) ~ x, dat2)
    st <- list(a = exp(coef(fm_lm)[1]), b = coef(fm_lm)[2])
    nls(y ~ f(x, a, b), dat2, start = st)
    

    giving:

    Nonlinear regression model
      model: y ~ f(x, a, b)
       data: dat2
           a        b 
    4214.423   -0.811 
     residual sum-of-squares: 2388
    
    Number of iterations to convergence: 6 
    Achieved convergence tolerance: 3.36e-06
    

    1b) We can also get it to work by reparameterizing. In that case a = 1 and b = 1 will work provided we transform the initial values in line with the parameter transformation.

    nls(y ~ exp(loga + b * x), dat2, start = list(loga = log(1), b = 1))
    

    giving:

    Nonlinear regression model
      model: y ~ exp(loga + b * x)
       data: dat2
      loga      b 
     8.346 -0.811 
     residual sum-of-squares: 2388
    
    Number of iterations to convergence: 20 
    Achieved convergence tolerance: 3.82e-07
    

    so b is as shown and a = exp(loga) = exp(8.346) = 4213.3

    2) plinear Another possibility that is even easier is to use alg="plinear" in which case starting values are not needed for the parameters entering linearly. In that case the starting value of b=1 in the question seems sufficient.

    nls(y ~ exp(b * x), dat2, start = c(b = 1), alg = "plinear")
    

    giving:

    Nonlinear regression model
      model: y ~ exp(b * x)
       data: dat2
            b      .lin 
      -0.8106 4214.4234 
     residual sum-of-squares: 2388
    
    Number of iterations to convergence: 11 
    Achieved convergence tolerance: 2.153e-06
    

提交回复
热议问题