[R] nlm, hessian, and derivatives in obj function?
Arne Henningsen
ahenningsen at email.uni-kiel.de
Thu Oct 23 13:05:30 CEST 2003
Hi,
I don't know much about non-linear models, but there is another possibility to
fit these models:
1) get some starting values for the parameters
2) take the derivatives of the model with respect to the parameters at the
point of the starting values of the parameters
3) perform a linear estimation of this linearized model (using systemfit) to
get new parameter estimates
4) got to step 2) and take these new parameter estimates in place of the
starting values
5) iterate this until the parameters stay stable from one to the next
iteration
This has three advantages:
1) It is not much work to write these function since systemfit already exists
2) If the model is linear in parameters, it is identical to the linearized
model and, thus, the first iteration leads directly to the optimum
3) You get get the SEs from the last iteration of systemfit
Does this approach also have disadvantages (e.g. non-convergence of parameters
in many cases)?
Best wishes,
Arne
On Saturday 18 October 2003 01:54, Jeff D. Hamann wrote:
> I've been working on a new package and I have a few questions regarding the
> behaviour of the nlm function. I've been (for better or worse) using the
> nlm function to fit a linear model without suppling the hessian or gradient
> attributes in the objective function. I'm curious as to why the nlm
> requires 31 iterations (for the linear model), and then it doesn't work
> when I try to add the derivative information. I know using nlm for a linear
> model isn't the "optimal" method, but I would like to make sure the
> parameter estimates and the se's are matching before I attempt more
> difficult problems.
>
> rm(list=ls(all=TRUE))
> print( "running nlsystemfit models test at end...")
> data( kmenta )
> attach( kmenta )
> ##demand2 <- q ~ d0 + d1 * p + d2 * d
> supply2 <- q ~ s0 + s1 * p + s2 * f + s3 * a
> ##system2 <- list( demand2, supply2 )
> ##labels <- list( "Demand", "Supply" )
> ##inst <- ~ d + f + a
> ##sv2 <- c(d0=3,s2=2.123,d2=4,s0=-2.123,s3=4.234,d1=4.234,s1=0.234)
> sv2 <- c(s0=-2.123,s1=0.234,s2=2.123,s3=4.234)
>
> obj <- function( s, eqn, data, parmnames )
> {
> ## get the values of the parameters
> for( i in 1:length( parmnames ) )
> {
> name <- names( parmnames )[i]
> val <- s[i]
> storage.mode( val ) <- "double"
> assign( name, val )
> }
>
> lhs <- as.matrix( eval( as.formula( eqn )[[2]] ) )
> rhs <- as.matrix( eval( as.formula( eqn )[[3]] ) )
> resid <- crossprod( lhs - rhs )
>
> ## just how does this work...
> attr( obj, "value" ) <- resid
> attr( obj, "gradient" ) <- attr( eval( deriv3( eqn, names(
> parmnames ) ) ), "gradient" )
>
> }
>
> res <- nlm( obj, sv2, hessian=T, eqn=supply2, data=kmenta, parmnames=sv2,
> check.analyticals=T)
>
> I haven't been able to get nlm to function as I keep getting the following
> error message:
>
> Error in nlm(obj, sv2, hessian = T, eqn = supply2, data = kmenta, parmnames
> = sv2, :
> invalid function value in 'nlm' optimizer
>
>
> If I perform the fit without the derivative information, I get the correct
> estimates,
>
> $minimum
> [1] 92.55106
>
> $estimate
> [1] 58.2754312 0.1603666 0.2481333 0.2483023
>
> $gradient
> [1] 8.552542e-08 9.087699e-06 5.716032e-06 2.163105e-06
>
> $hessian
> [,1] [,2] [,3] [,4]
> [1,] 40.000 4000.762 3865.0 420.00
> [2,] 4000.762 401486.918 386045.8 42007.76
> [3,] 3865.000 386045.812 379593.1 39762.40
> [4,] 420.000 42007.764 39762.4 5740.00
>
> $code
> [1] 1
>
> $iterations
> [1] 31
>
> I was under the impression that you could also obtain the se of the
> parameter estimates using the sqrt( diag( res$hessian ) ), but I haven't
> been able to reproduce the se computed by the Jacobian
>
> se <- sqrt( mse * diag( solve( crossprod( J ) ) ) ) # gives the correct
> results...
> hse <- sqrt( ( res$minimum / 8 ) * diag( solve( res$hessian ) ) ) # gives
> similar results, but why 8?
>
> I've tried to put the functionality to include the jacobian and hessian in
> the objective function for nlm without success as I don't know what the
> form of the functions will be ahead of time.
>
> and get the se from the sqrt( diag( hessian ) ), but it's nowhere close?
>
> Jeff.
>
> ---
> Jeff D. Hamann
> Hamann, Donald and Associates, Inc.
> PO Box 1421
> Corvallis, Oregon USA 97339-1421
> (office) 541-754-1428
> (cell) 541-740-5988
> jeff_hamann at hamanndonald.com
> www.hamanndonald.com
>
> ______________________________________________
> R-help at stat.math.ethz.ch mailing list
> https://www.stat.math.ethz.ch/mailman/listinfo/r-help
--
Arne Henningsen
Department of Agricultural Economics
Christian-Albrechts-University Kiel
24098 Kiel, Germany
Tel: +49-431-880-4445
Fax: +49-431-880-1397
ahenningsen at email.uni-kiel.de
http://www.uni-kiel.de/agrarpol/ahenningsen/
More information about the R-help
mailing list