3
I have searched a lot, in several forums and in many pages about parameters estimation via function optim
of R and found nothing on how to add the gradient function in a script, so that the derivatives are calculated via some function of R, _deriv()_
or _deriv3()_
or via package _NumDeriv_
or package _Deriv_
. I need to calculate the gradient in order to try to improve my estimation process and it is impossible to do the derivatives by hand because my likelihood log function is very extensive.
I can do the derivatives on _Maple 16_
, but would like to know how to obtain the gradient in the _R_
in a more automated way. The code below is a script for estimating Birnbaum-Saunders univariate parameters with two parameters, in case I manage to implement the gradient in this script I could implement in my most complicated code!
When compiling the code below I have sometimes obtained negative parameters, which is absurd, because _alpha_
, _beta_
and _t_
are positive. I imagine that with the gradient this may no longer occur.
library(VGAM)
alpha<-2
beta <-1
truevalue <- c(alpha,beta)
n=1000
N=300
m=matrix(ncol=2,nrow=N)
for (i in 1:N){
x <- rnorm(n,mean = 0,sd=sqrt((alpha^2)/4))
t <- beta*(1+2*x^2+2*x*sqrt(1+x^2)) #t possui distribuição birnbaum-Saunders com parâmetros alpha e beta
#t <- rbisa(n, alpha, beta)
#sum(1*(t<0))
#Função Densidade da distribuição birnbaum-saunders
f <-function(theta){
alpha <- abs(theta[1])
beta <- abs(theta[2])
d <- (1/(2*alpha*beta*sqrt(2*pi)))*(sqrt(beta/t)+(beta/t)^(3/2))*exp(- (1/(2*alpha^2))*((t/beta)+(beta/t)-2))
return(d)
}
#Forma 1 da log verossimilhança
# log.ver <- function(theta){
# alpha <- abs(theta[1])
# beta <- abs(theta[2])
# l <- sum(log(f(theta)))
# return(l)
# }
#Forma 2 da log verossimilhança
log.ver <- function(theta){
alpha <- abs(theta[1])
beta <- abs(theta[2])
l <- sum(log((1/(2*alpha*beta*sqrt(2*pi)))*(sqrt(beta/t)+ (beta/t)^(3/2))*exp(-(1/(2*alpha^2))*((t/beta)+(beta/t)-2))))
return(l)
}
alpha_0 <- 3
beta_0 <- 4
start <- c(alpha_0,beta_0)
opt <- optim(start,log.ver,method="BFGS",hessian = F,control=list(fnscale=-1))
m[i,]=opt$par
}
#Calculating the average of each column of the array of parameters m
mest=colMeans(m)
#calculating the standard deviation of each column of the array of parameters m
dest=apply(m,2,sd)
#root mean square error in the calculation of each column of the array of parameters m in relation to the true value of the parameter
eqm=function(x,opt){
N=length(x)
sqrt(sum(((x-opt)^2))/N)}
#Estimated mean squared error of each parameter
eqmest=c(eqm(x=m[,1],opt=alpha),
eqm(x=m[,2],opt=beta))
# Table with the true values of the parameters and the average
# Standard deviation and mean square error of the estimated parameters
tab=data.frame(truevalue,mean=mest,sd=dest,eqm=eqmest)
tab
I really appreciate the help!
Thank you @Fernandocorrêa, regarding your answer 1, note that in my code I add in function Optim the term control=list(fnscale=-1), That means I’m doing a maximization. Regarding your answer 2, I fully agree, however, as you can notice, after some corrections I posted in my reply the estimation process even without the gradient is not bad. This is not my problem, because this code is a test, I really need to adjust the gradient as I explained in my question to solve the estimation in other models. But I appreciate your help!
– fsbmat