optim in r :non finite finite difference error - r

I have a simple likelihood function (from a normal dist with mean=0) that I want to maximize. optim keeps giving me this error:
Error in optim(par = phi, fn = loglike, estimates = estimates, NULL, hessian = TRUE, : non-finite finite-difference value [1]
Here is my data and likelihood function:
y = [ -0.01472 0.03942 0.03592 0.02776 -0.00090 ]
C = a varcov matrix:
1.66e-03 -0.000120 -6.780e-06 0.000102 -4.000e-05
-1.20e-04 0.001387 7.900e-05 -0.000140 -8.000e-05
-6.78e-06 0.000079 1.416e-03 -0.000070 8.761e-06
1.02e-04 -0.000140 -7.000e-05 0.001339 -6.000e-05
-4.00e-05 -0.000080 8.761e-06 -0.000060 1.291e-03
my log likelihood function is:
lglkl = -.5*(log(det(v)) + (t(y)%%vi%%y))` where v = phi*I + C and vi=inverse(v) and I= 5*5 Identity matrix.
I am trying to get the mle estimate for "phi". I thought this would be a simple optimization problem but am struggling. Would really appreciate any help. Thanks in advance. My code is below:
loglike <- function(phi,y) {
v = phi*I + C
vi = solve(v)
loglike = -.5*(log(det(v)) + (t(y)%*%vi%*%y))
return(-loglike)
}
phi = 0
parm <- optim(par=phi,fn=loglike,y=y,NULL,hessian = TRUE, method="L-BFGS-B",lower=0,upper=1000)

The error you ran into is because ϕ becomes negative beyond a certain number of iterations (which indicates that the constraints are not being applied correctly by the algorithm). Also, the solution does not converge to a single value but jumps between a few small values before reaching a situation where the updated covariance matrix is no-longer positive definite. At that stage you get det(v) < 0 and log[det(v)] is undefined. The optim algorithm bails out at that stage.
To see what's happening, play with the maxit and ndeps parameters in the code below.
require("matrixcalc")
#-------------------------------------------------
# Log-likelihood function
#-------------------------------------------------
loglike <- function(phi, y) {
# Shift the covariance matrix
print(paste("phi = ", phi))
#v = phi*I + (1 - phi)*C
v = phi*I + C
stopifnot(is.positive.definite(v))
# Invert shifted matrix
vi = solve(v)
# Compute log likelihood
loglike = -.5*(log(det(v)) + (t(y) %*% vi %*% y))
print(paste("L = ", loglike))
return(-loglike)
}
#-------------------------------------------------
# Data
#-------------------------------------------------
y = c(-0.01472, 0.03942, 0.03592, 0.02776, -9e-04)
C = structure(c(0.00166, -0.00012, -6.78e-06, 0.000102, -4e-05, -0.00012,
0.001387, 7.9e-05, -0.00014, -8e-05, -6.78e-06, 7.9e-05,
0.001416, -7e-05, 8.761e-06, 0.000102, -0.00014, -7e-05,
0.001339, -6e-05, -4e-05, -8e-05, 8.761e-06, -6e-05, 0.001291),
.Dim = c(5L, 5L ))
#--------
# Initial parameter
#--------
I = diag(5)
phi = 50
#--------
# Minimize
#--------
parm <- optim(par = phi, fn = loglike, y = y, NULL, hessian = TRUE,
method = "L-BFGS-B", lower = 0.0001, upper = 1000,
control = list(trace = 3,
maxit = 1000,
ndeps = 1e-4) )

Related

Fit Variance gamma to data

I am using R studio to estimate paramters for data under Variance Gamma. I want to fit this data to the data and find estimates of parameters. The code I have is
x<-c(1291,849,238,140,118,108,87,70,63,58,50,47,21,21,19)
library(VarianceGamma)
init<-c(0,0.5,0,0.5)
vgFit(x, freq = NULL, breaks = NULL, paramStart = init, startMethod = "Nelder-Mead", startValues = "SL", method = "Nelder-Mead", hessian = FALSE, plots = TRUE)
The error I got was:
Error in optim(paramStart, llsklp, NULL, method = startMethodSL, hessian = FALSE, :
function cannot be evaluated at initial parameters
I am not sure what the issue is?
The error might suggest divergence. Based on your previous questions, I'm wildly guessing the x is the raw number of the stock values. So a log-transformation may be necessary before modelling the change per time unit (ex. daily returns).
x <- c(1291,849,238,140,118,108,87,70,63,58,50,47,21,21,19)
dx <- log(x)[2:length(dx)] - log(x)[1:(length(dx)-1)]
vgFit(dx)
#Parameter estimates:
# vgC sigma theta nu
# 0.16887 0.03128 -0.47164 0.27558
We may want to compare with simulated data. I implemented two methods and they seem equivalent for large observation number nt.
Method 2 is according to below:
#Simulating VG as a time-fixed Brownian Motion
set.seed(1)
nt = 15 #number of observations
T = nt - 1 #total time
dt = rep(T/(nt-1), nt-1) #fixed time increments
r = 1 + 0.16887 #interest rate
vgC = (r-1)
sigma = 0.03128
theta = -0.47164
nu = 0.27558
V_ = rep(NA,nt) #Simulations for log stock value
V_[1] = 7.163172 #log(x[1])
V2_ = V_ #alternative simulation method
for(i in 2:nt)
{#method 1: by VarianceGamma package
V_[i] <- V_[i-1] + rvg(1,vgC=vgC*dt[i-1], sigma=sigma, theta=theta, nu=nu)
#method 2: by R built-in packages
gamma_i<-rgamma(1, shape=dt[i-1]/nu, scale = nu)
normal<-rnorm(1, mean=0, sd=sigma*sqrt(gamma_i))
V2_[i] <- V2_[i-1] + vgC*dt[i-1] + theta*gamma_i + normal
}
# Visual comparison
x11(width=4,height=4)
plot(x, xlab='Time',ylab='Stock value',type='l')
lines(exp(V_), col='red')
lines(exp(V2_), col='blue')
legend('topright',legend=c('Observed','Method1','Method2'),fill=c('black','red','blue'))
The resulting parameters suggest unstable estimations due to small sample size nt:
#The real parameter:
c(vgC*dt[1], sigma, theta, nu).
# vgC sigma theta nu
# 0.16887 0.03128 -0.47164 0.27558
#Parameter estimates for 1st data set:
dV = V_[2:nt] - V_[1:(nt-1)]
vgFit(dV)
# vgC sigma theta nu
#-0.9851 0.3480 1.2382 2.0000
#Parameter estimates for 2nd data set:
dV2 = V2_[2:nt] - V2_[1:(nt-1)]
vgFit(dV2)
# vgC sigma theta nu
#-0.78033 0.07641 0.52414 0.11840
In addition, the rvg function is assuming fixed time increments. We can relax that hypothesis by #Louis Marascio's answer using log-likelihood approach.
#Simulating VG as a time-changed Brownian Motion
set.seed(1)
nt = 100 #Increase the number of observations!
T = nt-1
dt = runif(nt-1) #random time increments
dt = dt/sum(dt)*T
r = 1 + 0.16887
vgC = (r-1)
sigma = 0.03128
theta = -0.47164
nu = 0.27558
V_ = rep(NA,nt) #simulations for log stock value
V_[1] = 7.163172
for(i in 2:nt)
{V_[i] <- V_[i-1] + rvg(1,vgC=vgC*dt[i-1], sigma=sigma, theta=theta, nu=nu)
}
dV = V_[2:nt] - V_[1:(nt-1)]
# -log-likelihood function with different time increments
ll = function(par){
if(par[2]>0 & par[4]>0)
{tem = 0
for (i in 1:(length(dV)))
{tem = tem - log(dvg(dV[i], vgC = par[1]*dt[i], sigma=par[2], theta=par[3], nu = par[4]))
}
return (tem)
}
else return(Inf)}
Indeed, the results show better estimation by relaxing the fixed time assumption:
#The real parameters:
c(vgC, sigma, theta, nu)
# vgC sigma theta nu
# 0.16887 0.03128 -0.47164 0.27558
#Assuming fixed time increments
vgFit(dV)$param*c(1/mean(dt),1,1,1)
# vgC sigma theta nu
#-0.2445969 0.3299023 -0.0696895 1.5623556
#Assuming different time increments
optim(vgFit(dV)$param*c(1/mean(dt),1,1,1),ll,
method = c("Nelder-Mead", "BFGS", "CG", "L-BFGS-B", "SANN", "Brent")[5])
# vgC sigma theta nu
# 0.16503125 0.03241617 -0.50193694 0.28221985
Finally, the confidence intervals for the estimated parameters may be obtained by multiple simulations:
set.seed(1)
out = NULL
for (j in 1:100) #100 simulations
{V_ = rep(NA,nt)
V_[1] = 7.163172
for(i in 2:nt)
{V_[i] <- V_[i-1] + rvg(1,vgC=vgC*dt[i-1], sigma=sigma, theta=theta, nu=nu)
}
dV = V_[2:nt] - V_[1:(nt-1)]
#to skip divergence
tem <- try(vgFit(dV)$param)
if (inherits(tem, "try-error")) next
out = rbind(out,tem)
}
apply(out,2,mean)
# vgC sigma theta nu
#-0.8735168 0.1652970 0.4737270 0.9821458
apply(out,2,sd)
# vgC sigma theta nu
#2.8935938 0.3092993 2.6833866 1.3161695

Error in as.vector(data) : no method for coercing this S4 class to a vector

I am trying to run a O-garch model, the code seem to be right and on mac it works, but when it is run on windows it doesn not work giving me the following error message:
Error in as.vector(data) :
no method for coercing this S4 class to a vector
seems that there is a problem with the loop.
Thanks in advance.
graphics.off() # clean up graphic window
#install.packages("fGarch")
library(rmgarch)
library(tseries)
library(stats)
library(fGarch)
library(rugarch)
library(quantmod)
getSymbols(Symbols = c('PG','CVX','CSCO'),from="2005-01-01", to="2020-04-17",
env=parent.frame(),
reload.Symbols = FALSE,
verbose = FALSE,
warnings = TRUE,
src="yahoo",
symbol.lookup = TRUE,
auto.assign = getOption('getSymbols.auto.assign', TRUE))
Pt=cbind(PG$PG.Adjusted,CVX$CVX.Adjusted,CSCO$CSCO.Adjusted)
rt = 100 * diff(log(Pt))
rt=na.omit(rt)
rm(CSCO,CVX,PG)
rt_ts=ts(rt)
n=nrow(rt_ts)
N=ncol(rt_ts)
#O-GARCH:
Sigma = cov(rt_ts); # Covariance matrix
P = cor(rt_ts) # correlation matrix
# spectral decomposition
SpectralDec = eigen(Sigma, symmetric=TRUE)
V = SpectralDec$vectors # eigenvector matrix
V
lambda = SpectralDec$values # eigenvalues
lambda
Lambda = diag(lambda) # Eigenvalues on the diagonal
print(Sigma - V %*% Lambda %*% t(V), digits = 3) # Sigma - V Lambda V' = 0
print(V %*% t(V), digits = 3) # V'V = I
print(t(V) %*% V, digits = 3) # VV' = I
f = ts(as.matrix(rt_ts) %*% V);
cov(f) # diagonal matrix with lambda on the diagonal
ht.f = matrix(0, n, N)
for (i in 1:N)
{
fit = garchFit(~ garch(1,1), data =f[, i], trace = FALSE);
summary(fit);
ht = volatility(fit, type = "h");
ht.f[, i] = ht;
}
ht.f=ts(ht.f) ```
I had the exact same problem with the volatility line. Apparently the fGarch library doesn't get along with the quantmod library. Maybe try reseting RStidio and install all but quantmod library
That was the only way I got it to work

objective function in optim evaluates to length 2 not 1

I do not even know if any of my equations are right, but I did this and its saying the objective function in optim evaluates to length 2 not 1. I am trying to estimate lambda and alfa using mle and log likelihood.
set.seed(1001)
q <- 1:5000
mean(q)
sd(q)
ll <- function(lambda = 0.5, alpha = 3.5) {
n <- 5000
(-n) * alpha * log(lambda) +
n * log(gamma(alpha)) - ((alpha - 1) * sum(log(q))) +
lambda * sum(q)
}
MLE <- optim(c(0.5, 3.5),
fn = ll,
method = "L-BFGS-B",
lower = 0.00001,
control = list(fnscale = -1),
hessian = T
)
There are several places to make your optim fly:
you should define your ll as a function of one argument (instead of two arguments, otherwise you will have the error "objective function in optim evaluates to length 2 not 1"), since within optim, your initial value x0 will be pass to objective function fn
ll<-function(x){
n<-5000
lambda <- x[1]
alfa <- x[2]
(-n)*alfa*log(lambda)+n*log(gamma(alfa))-((alfa-1)*sum(log(q)))+lambda*sum(q)
}
In optim, the dimension of lower bound lower should be the same as x0, e.g.,
MLE = optim(c(0.5,3.5),
fn = ll,
method = "L-BFGS-B",
lower = c(1e-5,1e-5),
control = list(fnscale = -1),
hessian = FALSE
)

mle2 (bbmle) parameter estimates on boundary, NaNs produced in object#vcov

I'm trying to run a MLE for an infectious disease compartmental transmission model (SEIR, in my case SSEIR) with the mle2 command, trying to fit a curve of predicted number of weekly deaths to that of observed weekly deaths similar to this:
plot of predicted vs observed weekly deaths.
However, the parameter estimates seem to always be on the (sensible) boundaries I provide and SEs, z-values, p-values are NA.
I set up the SEIR model and then solve it with the ode solver. Using that model output and the observed data, I calculate a negative log likelihood, which I then submit to the mle2 function.
When I first set it up, there were multiple errors that stopped the script from running, but now that those are resolved, I cannot seem to find the root of why the fitting doesn't work.
I am certain that the boundaries I set for the parameter estimation are sensible. The parameters are transition rates between compartments and are therefore defined as (for example) delta = 1/duration of infectiousness, so there are very real biological boundaries on what the parameters can be.
I am aware that I am trying to fit a lot of parameters with not that much data, but the same problem persists when I try only fitting one, so that cannot be the root of it.
library(deSolve)
library(bbmle)
#data
gdta <- c(0, 36.2708172419082, 1.57129615346629, 28.1146409459558, 147.701669719614, 311.876708482584, 512.401145459178, 563.798275104372, 470.731269976821, 292.716043742125, 153.604156195608, 125.760068922451, 198.755685044427, 143.847282793854, 69.2693867232681, 42.2093135487066, 17.0200426587424)
#build seir function
seir <- function(time, state, parameters) {
with(as.list(c(state, parameters)), {
dS0 <- - beta0 * S0 * (I/N)
dS1 <- - beta1 * S1 * (I/N)
dE <- beta0 * S0 * (I/N) + beta1 * S1 * (I/N) - delta * E
dI <- delta * E - gamma * I
dR <- gamma * I
return(list(c(dS0, dS1, dE, dI, dR)))
})
}
# build function to run seir, include ode solver
run_seir <- function(time, state, beta0, beta1, delta, gamma, sigma, N, startInf) {
parameters <- c(beta0, beta1, delta, gamma)
names(parameters) <- c("beta0", "beta1", "delta", "gamma")
init <- c(S0 = (N - startInf)*(sigma) ,
S1 = (N - startInf) * (1-sigma),
E = 0,
I = startInf,
R = 0)
state_est <- as.data.frame(ode(y = init, times = times, func = seir, parms = parameters))
return(state_est)
}
times <- seq(0, 16, by = 1) #sequence
states <- c("S0", "S1", "E", "I", "R")
# run the run_seir function to see if it works
run_seir(time = times, state= states, beta0 = 1/(1.9/7), beta1 = 0.3*(1/(1.9/7)), delta = 1/(4.1/7), gamma = 1/(4.68/7), sigma = 0.7, N = 1114100, startInf = 100)
#build calc likelihood function
calc_likelihood <- function(times, state, beta0, beta1, delta, gamma, sigma, N, startInf, CFR) {
model.output <- run_seir(time, state, beta0, beta1, delta, gamma, sigma, N, startInf)
LL <- sum(dpois(round(as.numeric(gdta)), (model.output$I)/(1/delta)*CFR, log = TRUE))
print(LL)
return(LL)
}
# run calc_likelihood function
calc_likelihood(time = times, state = states, beta0 = 1/(1.9/7), beta1 = 0.3*(1/(1.9/7)), delta = 1/(4.1/7), gamma = 1/(4.68/7), sigma = 0.7, N = 1114100, startInf = 100, CFR = 0.02)
#MLE
#parameters that are supposed to be fixed
fixed.pars <- c(N=1114100, startInf=100, CFR = 0.02)
#parameters that mle2 is supposed to estimate
free.pars <- c(beta0 = 1/(1.9/7), beta1 = 0.3*(1/(1.9/7)),
delta = 1/(4.1/7), gamma = 1/(4.68/7), sigma = 0.7)
#lower bound
lower_v <- c(beta0 = 0, beta1 = 0, delta = 0, gamma = 0, sigma = 0)
#upper bound
upper_v <- c(beta0 = 15, beta1 = 15, delta = 15, gamma = 15, sigma = 1)
#sigma = 1, this is not a typo
#mle function - need to use L-BFGS-B since we need to include boundaries
test2 <- mle2(calc_likelihood, start = as.list(free.pars), fixed = as.list(fixed.pars),method = "L-BFGS-B", lower = lower_v, upper = upper_v)
summary(test2)
After I run mle2, I get a warning saying:
Warning message:
In mle2(calc_likelihood, start = as.list(free.pars), fixed = as.list(fixed.pars), :
some parameters are on the boundary: variance-covariance calculations based on Hessian may be unreliable
and if I look at summary(test2):
Warning message:
In sqrt(diag(object#vcov)) : NaNs produced
Based on the research I've done so far, I understand that the second error might be due to the estimates being on the boundaries, so my question really is how to address the first one.
If I run mle2 with only lower boundaries, I get parameter estimates in the millions, which cannot be correct.
I am fairly certain that my model specification for the SEIR is correct, but after staring at this code and trying to resolve this issue for a week, I'm open to any input on how to make the fitting work.
Thanks,
JJ

GARCH estimation using maximum likelihood

I'm trying to estimate a GARCH (1,1) model using maximum likelihood with simulated data. This is what I got:
library(fGarch)
set.seed(1)
garch11<-garchSpec(model = list())
x<-garchSim(garch11, n = 1000)
y <- t(x)
r <- y[1, ]
### Calculate Residuals
CalcResiduals <- function(theta, r)
{
n <- length(r)
omega<-theta[1]
alpha11<-theta[2]
beta11<-theta[3]
sigma.sqs <- vector(length = n)
sigma.sqs[1] <- 0.02
for (i in 1:(n-1)){
sigma.sqs[i+1] <- omega + alpha11*(r[i]^2) + beta11*sigma.sqs[i]
}
return(list(et=r, ht=sigma.sqs))
}
###Calculate the log-likelihood
GarchLogl <- function(theta, r){
res <- CalcResiduals(theta,r)
sigma.sqs <- res$ht
r <- res$et
return(-sum(dnorm(r[-1], mean = 0, sd = sqrt(sigma.sqs[-1]), log = TRUE)))
}
fit2 <- nlm(GarchLogl, # function call
p = rep(1,3), # initial values = 1 for all parameters
hessian = FALSE, # also return the hessian matrix
r = r , # data to be used
iterlim = 500) # maximum iteration
Unfortunately I get the following error message and no results
There were 50 or more warnings (use warnings() to see the first 50)
1: In sqrt(sigma.sqs[-1]) : NaNs produced
2: In nlm(GarchLogl, p = rep(1, 3), hessian = FALSE, data <- r, ... :
NA/Inf durch größte positive Zahl ersetzt
Do you have any idea whats wrong with my code? Thanks a lot!

Resources