I am trying to estimate a latent class choice model on my data where I have two alternatives in my stated choice experiment – electric vehicle and conventional vehicle. However, I am not able to estimate a three or a four class model. I am able to estimate a two class model. I think I have specified the model correctly but I get two kinds of errors. Sometimes it says “No covariance matrix to compute “ and sometimes it says “hessian is singular”. Can you please take a look at the code and see if there is some issue with my code?
Code: Select all
rm(list = ls())
##install.packages("apollo")
# ################################################################# #
#### LOAD LIBRARY AND DEFINE CORE SETTINGS ####
# ################################################################# #
### Load Apollo library
library(apollo)
# ################################################################# #
#### LOAD DATA AND APPLY ANY TRANSFORMATIONS ####
# ################################################################# #
database = read.csv(file.choose(),header=TRUE)
### Initialise code
apollo_initialise()
### Set core controls
apollo_control = list(
modelName ="3ClassLatentClassChoiceModel",
modelDescr ="3ClassLatentClassChoiceModel",
indivID ="Person_ID",
mixing = FALSE,
nCores = 8,
outputDirectory = "output"
)
apollo_beta = c(
asc_EV = 0,
asc_CV = 0,
beta_pp_a = 0, beta_pp_b = 0, beta_pp_c = 0,
beta_oc_a = 0, beta_oc_b = 0, beta_oc_c = 0,
beta_ct_a = 0, beta_ct_b = 0, beta_ct_c = 0,
beta_rn_a = 0, beta_rn_b = 0, beta_rn_c = 0,
beta_cf_a = 0, beta_cf_b = 0, beta_cf_c = 0,
beta_em_a = 0, beta_em_b = 0, beta_em_c = 0,
beta_priorityLanes_a = 0, beta_priorityLanes_b = 0, beta_priorityLanes_c = 0,
beta_freeParking_a = 0, beta_freeParking_b = 0, beta_freeParking_c = 0,
beta_tollExemption_a = 0, beta_tollExemption_b = 0, beta_tollExemption_c = 0,
delta_a = 0, delta_b = 0, delta_c = 0,
gamma_gender_a = 0, gamma_gender_b = 0, gamma_gender_c = 0,
gamma_age_a = 0, gamma_age_b = 0, gamma_age_c = 0,
gamma_incomeLow_a = 0, gamma_incomeLow_b = 0, gamma_incomeLow_c = 0,
gamma_incomeLowMiddle_a = 0, gamma_incomeLowMiddle_b = 0, gamma_incomeLowMiddle_c = 0,
gamma_incomeHighMiddle_a = 0, gamma_incomeHighMiddle_b = 0, gamma_incomeHighMiddle_c = 0,
gamma_incomeHigh_a = 0, gamma_incomeHigh_b = 0, gamma_incomeHigh_c = 0,
gamma_knowledgeLow_a = 0, gamma_knowledgeLow_b = 0, gamma_knowledgeLow_c = 0,
gamma_knowledgeMid_a = 0, gamma_knowledgeMid_b = 0, gamma_knowledgeMid_c = 0,
gamma_knowledgeHigh_a = 0, gamma_knowledgeHigh_b = 0, gamma_knowledgeHigh_c = 0,
gamma_dailyDistanceLow_a = 0, gamma_dailyDistanceLow_b = 0, gamma_dailyDistanceLow_c = 0,
gamma_dailyDistanceMid_a = 0, gamma_dailyDistanceMid_b = 0, gamma_dailyDistanceMid_c = 0,
gamma_dailyDistanceHigh_a = 0, gamma_dailyDistanceHigh_b = 0, gamma_dailyDistanceHigh_c = 0,
gamma_longDistanceLow_a = 0, gamma_longDistanceLow_b = 0, gamma_longDistanceLow_c = 0,
gamma_longDistanceMid_a = 0, gamma_longDistanceMid_b = 0, gamma_longDistanceMid_c = 0,
gamma_longDistanceHigh_a = 0, gamma_longDistanceHigh_b = 0, gamma_longDistanceHigh_c = 0,
gamma_voCoded_a = 0, gamma_voCoded_b = 0, gamma_voCoded_c = 0,
gamma_Cluster1_a = 0, gamma_Cluster1_b = 0, gamma_Cluster1_c = 0,
gamma_Cluster2_a = 0, gamma_Cluster2_b = 0, gamma_Cluster2_c = 0,
gamma_Cluster3_a = 0, gamma_Cluster3_b = 0, gamma_Cluster3_c = 0,
gamma_Cluster4_a = 0, gamma_Cluster4_b = 0, gamma_Cluster4_c = 0
# sigma_panel_a = 0, sigma_panel_b = 0, sigma_panel_c = 0,
)
### Vector with names (in quotes) of parameters to be kept fixed at their starting value in apollo_beta, use apollo_beta_fixed = c() if none
apollo_fixed = c(
# "asc_CV_a", "asc_CV_b", "asc_CV_c",
"asc_CV",
"beta_tollExemption_a", "beta_tollExemption_b", "beta_tollExemption_c",
"delta_a",
"gamma_gender_a",
"gamma_age_a",
"gamma_incomeLow_a", "gamma_incomeLowMiddle_a", "gamma_incomeHighMiddle_a", "gamma_incomeHigh_a", "gamma_incomeLow_b", "gamma_incomeLow_c",
"gamma_knowledgeLow_a", "gamma_knowledgeMid_a", "gamma_knowledgeHigh_a", "gamma_knowledgeLow_b", "gamma_knowledgeLow_c",
"gamma_dailyDistanceLow_a", "gamma_dailyDistanceMid_a", "gamma_dailyDistanceHigh_a", "gamma_dailyDistanceLow_b", "gamma_dailyDistanceLow_c",
"gamma_longDistanceLow_a", "gamma_longDistanceMid_a", "gamma_longDistanceHigh_a", "gamma_longDistanceLow_b", "gamma_longDistanceLow_c",
"gamma_voCoded_a",
"gamma_Cluster1_a", "gamma_Cluster2_a", "gamma_Cluster3_a", "gamma_Cluster4_a", "gamma_Cluster1_b", "gamma_Cluster1_c"
)
# ################################################################# #
#### DEFINE LATENT CLASS COMPONENTS ####
# ################################################################# #
apollo_lcPars = function(apollo_beta, apollo_inputs){
lcpars = list()
# lcpars[["asc_EV"]] = list(asc_EV_a, asc_EV_b, asc_EV_c)
# lcpars[["asc_CV"]] = list(asc_CV_a, asc_CV_b, asc_CV_c)
lcpars[["beta_pp"]] = list(beta_pp_a, beta_pp_b, beta_pp_c)
lcpars[["beta_oc"]] = list(beta_oc_a, beta_oc_b, beta_oc_c)
lcpars[["beta_ct"]] = list(beta_ct_a, beta_ct_b, beta_ct_c)
lcpars[["beta_rn"]] = list(beta_rn_a, beta_rn_b, beta_rn_c)
lcpars[["beta_cf"]] = list(beta_cf_a, beta_cf_b, beta_cf_c)
lcpars[["beta_em"]] = list(beta_em_a, beta_em_b, beta_em_c)
lcpars[["beta_priorityLanes"]] = list(beta_priorityLanes_a, beta_priorityLanes_b, beta_priorityLanes_c)
lcpars[["beta_freeParking"]] = list(beta_freeParking_a, beta_freeParking_b, beta_freeParking_c)
lcpars[["beta_tollExemption"]] = list(beta_tollExemption_a, beta_tollExemption_b, beta_tollExemption_c)
V=list()
V[["class_a"]] = delta_a + gamma_gender_a*genderCoded + gamma_age_a*ageAvg + gamma_incomeLow_a*incomeLow + gamma_incomeLowMiddle_a*incomeLowMiddle + gamma_incomeHighMiddle_a*incomeHighMiddle + gamma_incomeHigh_a*incomeHigh + gamma_dailyDistanceLow_a*dailyDistanceLow + gamma_dailyDistanceMid_a*dailyDistanceMiddle + gamma_dailyDistanceHigh_a*dailyDistanceHigh + gamma_longDistanceLow_a*longDistanceLow + gamma_longDistanceMid_a*longDistanceMiddle + gamma_longDistanceHigh_a*longDistanceHigh + gamma_knowledgeLow_a*knowledgeLow + gamma_knowledgeMid_a*knowledgeMiddle + gamma_knowledgeHigh_a*knowledgeHigh + gamma_voCoded_a*evoCoded + gamma_Cluster1_a*(Cluster1) + gamma_Cluster2_a*(Cluster2) + gamma_Cluster3_a*(Cluster3) + gamma_Cluster4_a*(Cluster4)
V[["class_b"]] = delta_b + gamma_gender_b*genderCoded + gamma_age_b*ageAvg + gamma_incomeLow_b*incomeLow + gamma_incomeLowMiddle_b*incomeLowMiddle + gamma_incomeHighMiddle_b*incomeHighMiddle + gamma_incomeHigh_b*incomeHigh + gamma_dailyDistanceLow_b*dailyDistanceLow + gamma_dailyDistanceMid_b*dailyDistanceMiddle + gamma_dailyDistanceHigh_b*dailyDistanceHigh + gamma_longDistanceLow_b*longDistanceLow + gamma_longDistanceMid_b*longDistanceMiddle + gamma_longDistanceHigh_b*longDistanceHigh + gamma_knowledgeLow_b*knowledgeLow + gamma_knowledgeMid_b*knowledgeMiddle + gamma_knowledgeHigh_b*knowledgeHigh + gamma_voCoded_b*evoCoded + gamma_Cluster1_b*(Cluster1) + gamma_Cluster2_b*(Cluster2) + gamma_Cluster3_b*(Cluster3) + gamma_Cluster4_b*(Cluster4)
V[["class_c"]] = delta_c + gamma_gender_c*genderCoded + gamma_age_c*ageAvg + gamma_incomeLow_c*incomeLow + gamma_incomeLowMiddle_c*incomeLowMiddle + gamma_incomeHighMiddle_c*incomeHighMiddle + gamma_incomeHigh_c*incomeHigh + gamma_dailyDistanceLow_c*dailyDistanceLow + gamma_dailyDistanceMid_c*dailyDistanceMiddle + gamma_dailyDistanceHigh_c*dailyDistanceHigh + gamma_longDistanceLow_c*longDistanceLow + gamma_longDistanceMid_c*longDistanceMiddle + gamma_longDistanceHigh_c*longDistanceHigh + gamma_knowledgeLow_c*knowledgeLow + gamma_knowledgeMid_c*knowledgeMiddle + gamma_knowledgeHigh_c*knowledgeHigh + gamma_voCoded_c*evoCoded + gamma_Cluster1_c*(Cluster1) + gamma_Cluster2_c*(Cluster2) + gamma_Cluster3_c*(Cluster3) + gamma_Cluster4_c*(Cluster4)
classAlloc_settings = list(
classes = c(class_a=1, class_b=2, class_c=3),
utilities = V
)
lcpars[["pi_values"]] = apollo_classAlloc(classAlloc_settings)
return(lcpars)
}
# ################################################################# #
#### GROUP AND VALIDATE INPUTS ####
# ################################################################# #
apollo_inputs = apollo_validateInputs()
# ################################################################# #
#### DEFINE MODEL AND LIKELIHOOD FUNCTION ####
# ################################################################# #
apollo_probabilities=function(apollo_beta, apollo_inputs, functionality="estimate"){
### Attach inputs and detach after function exit
apollo_attach(apollo_beta, apollo_inputs)
on.exit(apollo_detach(apollo_beta, apollo_inputs))
### Create list of probabilities P
P = list()
### Define settings for MNL model component that are generic across classes
mnl_settings = list(
alternatives = c(EV=1, CV=2),
avail = list(EV=1, CV=1),
choiceVar = choiceVehicle
)
### Loop over classes
for(s in 1:3){
### Compute class-specific utilities
V=list()
V[["EV"]] = asc_EV + beta_pp[[s]]*(ppEV/100) + beta_oc[[s]]*ocEV + beta_ct[[s]]*ctEV/60 + beta_rn[[s]]*rEV/100 + beta_cf[[s]]*(cfEV*10) + beta_em[[s]]*(eEV*10) + beta_priorityLanes[[s]]*priorityLanes + beta_freeParking[[s]]*freeParking + beta_tollExemption[[s]]*tollExemption
V[["CV"]] = asc_CV + beta_pp[[s]]*(ppCV/100) + beta_oc[[s]]*ocCV + beta_rn[[s]]*rCV/100 + beta_em[[s]]*(eCV*10)
mnl_settings$utilities = V
mnl_settings$componentName = paste0("Class_",s)
### Compute within-class choice probabilities using MNL model
P[[paste0("Class_",s)]] = apollo_mnl(mnl_settings, functionality)
### Take product across observation for same individual
P[[paste0("Class_",s)]] = apollo_panelProd(P[[paste0("Class_",s)]], apollo_inputs ,functionality)
### Average across inter-individual draws within classes
# P[[paste0("Class_",s)]] = apollo_avgInterDraws(P[[paste0("Class_",s)]], apollo_inputs, functionality)
}
### Compute latent class model probabilities
lc_settings = list(inClassProb = P, classProb=pi_values)
P[["model"]] = apollo_lc(lc_settings, apollo_inputs, functionality)
# ### Average across inter-individual draws in class allocation probabilities
# P[["model"]] = apollo_avgInterDraws(P[["model"]], apollo_inputs, functionality)
### Prepare and return outputs of function
P = apollo_prepareProb(P, apollo_inputs, functionality)
return(P)
}
# ################################################################# #
#### MODEL ESTIMATION AND OUTPUT ####
# ################################################################# #
### Estimate model
model = apollo_estimate(apollo_beta, apollo_fixed, apollo_probabilities, apollo_inputs, estimate_settings = list(maxIterations= 300))
### Show output in screen
apollo_modelOutput(model)
### Save output to file(s)
apollo_saveOutput(model)