Home > database >  Using the MLE and NLS functions in R for a nonlinear model
Using the MLE and NLS functions in R for a nonlinear model

Time:09-30

I'm having some issues being able to implement an MLE and NLS model for some estimation that I am trying to perform. The model is as follows

Y=A*(K^b_1)*(L^b_2) e

Where e is just the error term and B and D are input variables. The goal is to try to estimate b_1 and b_2. My first equation is, how would I put this into the nls function as when I try to do this I get the following error

prod.nls<-nls(Y~A*(K^Beta_1)*(L^Beta_2), start =list(A = 2, Beta_1= 2, Beta_2=2))
Error in numericDeriv(form[[3L]], names(ind), env) : 
  Missing value or an infinity produced when evaluating the model

My other question is the model above can be rewritten in terms of logs, log(Y)= log(A) b_1log(K) b_2log(L)

I omit the error term as it becomes irreverent and the A is just a scalar so I leave it out as well. However when I place that model into R using the mle function I get an error as follows,

prod.mle<-mle(log(Y)~log(K) log(L))
Error in minuslogl() : could not find function "minuslogl"
In addition: Warning messages:
1: In formals(fun) : argument is not a function
2: In formals(fun) : argument is not a function

A small table of values from the dataset is provided below to be able to reproduce these errors. Thank you for the help ahead of time.

Y K L
26971.71 32.46371 3013256.014
330252.5 28.42238 135261574.9
127345.3 5.199048 39168414.92
3626843 327.807 1118363069
37192.73 16.01538 9621912.503

CodePudding user response:

1) Try removing A and just optimizing with the other 2 parameters. Then use the result as starting values to reoptimize. In the second application of nls we use the plinear algorithm which does not require starting values for parameters that enter linearly. When plinear is used the right hand side should be a matrix such that a linear parameter multiplies each column. In this case we only have one column.

fo <- Y ~ cbind(A = (K^Beta_1) * (L^Beta_2))
st <- list(Beta_1 = 2, Beta_2 = 2)
fm0 <- nls(fo, DF, start = st)

fm1 <- nls(fo, DF, start = coef(fm0), alg = "plinear"); fm1

giving:

Nonlinear regression model
  model: Y ~ cbind(A = (K^Beta_1) * (L^Beta_2))
   data: DF
 Beta_1  Beta_2  .lin.A 
0.25399 0.81422 0.03572 
 residual sum-of-squares: 2.468e 09

Number of iterations to convergence: 7 
Achieved convergence tolerance: 6.56e-06

2) If we take logs of both sides then the formula is linear in all parameters assuming we use log(A) rather than A as one parameter thus we can use lm. Note that that is not an exactly equivalent problem to the original problem although it may be close enough for you. Below we use it as an alternative way to get starting values.

fm2 <- lm(log(Y) ~ log(K)   log(L), DF)
co2 <- coef(fm2)
st2 <- list(Beta_1 = co2[[2]], Beta_2 = co2[[3]])
fm3 <- nls(fo, DF, start = st2, alg = "plinear"); fm3

giving:

Nonlinear regression model
  model: Y ~ cbind(A = (K^Beta_1) * (L^Beta_2))
   data: DF
Beta_1 Beta_2 .lin.A 
0.2540 0.8143 0.0357 
 residual sum-of-squares: 2.468e 09

Number of iterations to convergence: 6 
Achieved convergence tolerance: 3.744e-06

Note

The input DF in reproducible form is:

DF <- structure(list(Y = c(26971.71, 330252.5, 127345.3, 3626843, 37192.73
), K = c(32.46371, 28.42238, 5.199048, 327.807, 16.01538), L = c(3013256.014, 
135261574.9, 39168414.92, 1118363069, 9621912.503)), 
class = "data.frame", row.names = c(NA, -5L))
  • Related