Thank you for providing this platform for Appolo users. I have a question about a LC-MMNL model used for identifying ANA behaviour.
Setting
Choices are allocated to two classes, the first class is the ANA class where only cost and ASC parameters are freely estimated and other attribute parameters are fixed at zero. All parameters in the second class are freely estimated and are assumed to be normally distributed.
Questions
(1) I estimated the model using the code below and a error message popped up: Error in apollo_avgInterDraws(P[[paste0("Class_", s)]], apollo_inputs, : SPECIFICATION ISSUE - No Inter-individuals draws to average over!
Could you let me know what can be the issue?
(2) I see in the manual example that you also assumed a normal distribution for the parameter delta_a. Is there a reason for this?
Codes
Code: Select all
# ################################################################# #
#### LOAD LIBRARY AND DEFINE CORE SETTINGS ####
# ################################################################# #
### Clear memory
rm(list = ls())
### Load Apollo library
library(apollo)
### Initialise code
apollo_initialise()
### Set core controls
apollo_control = list(
modelName ="LC_MMNL_ANA2_taxASC",
modelDescr ="LC_MMNL_ANA2_taxASC",
mixing = TRUE, #if no random then turn it off
indivID ="id",
nCores = 4
)
# ################################################################# #
#### LOAD DATA AND APPLY ANY TRANSFORMATIONS ####
# ################################################################# #
database = read.csv("R_ANAanalysis.csv",header=TRUE)
database= subset(database, database$Version==1|Version==3)
# ################################################################# #
#### DEFINE MODEL PARAMETERS ####
# ################################################################# #
### Vector of parameters, including any that are kept fixed in estimation
apollo_beta = c(asc1 = 0,
asc3_a = 0,
asc3_b_mu = 0,
asc3_b_sig = 0,
fleet_a = 0,
fleet_b_mu = 0,
fleet_b_sig = 0,
seasonal_a = 0,
seasonal_b_mu = 0,
seasonal_b_sig = 0,
plastic_a = 0,
plastic_b_mu = 0,
plastic_b_sig = 0,
buildings_a = 0,
buildings_b_mu = 0,
buildings_b_sig = 0,
devices_a = 0,
devices_b_mu = 0,
devices_b_sig = 0,
fund_a = 0,
fund_b_mu = 0,
fund_b_sig = 0,
nature_a = 0,
nature_b_mu = 0,
nature_b_sig = 0,
medicine_a = 0,
medicine_b_mu = 0,
medicine_b_sig = 0,
tax_a = 0,
log_tax_b_mu = -3,
log_tax_b_sig = 1,
gamma_age_a = 0,
gamma_male_a = 0,
gamma_edu_a = 0,
gamma_child_a = 0,
gamma_income_a = 0,
gamma_climate_a = 0,
gamma_urgent_a = 0,
gamma_PernotNHS_a = 0,
gamma_age_b = 0,
gamma_male_b = 0,
gamma_edu_b = 0,
gamma_child_b = 0,
gamma_income_b = 0,
gamma_climate_b = 0,
gamma_urgent_b = 0,
gamma_PernotNHS_b = 0,
delta_a = 0,
delta_b = 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("delta_a", "asc1",
"fleet_a","seasonal_a","plastic_a","buildings_a","devices_a","fund_a","nature_a","medicine_a",
"gamma_age_a" ,
"gamma_male_a",
"gamma_edu_a",
"gamma_child_a",
"gamma_income_a",
"gamma_climate_a",
"gamma_urgent_a",
"gamma_PernotNHS_a"
)
# ################################################################# #
#### DEFINE RANDOM COMPONENTS ####
# ################################################################# #
### Set parameters for generating draws
apollo_draws = list(
interDrawsType="mlhs",
interNDraws=500,
interUnifDraws=c(),
interNormDraws=c("draws_fleet", "draws_seasonal", "draws_plastic",
"draws_buildings","draws_devices", "draws_fund","draws_nature","draws_medicine","draws_tax","draws_asc3"
),
intraDrawsType="mlhs",
intraNDraws=0,
intraUnifDraws=c(),
intraNormDraws=c()
)
### Create random parameters
apollo_randCoeff = function(apollo_beta, apollo_inputs){
randcoeff = list()
randcoeff[["fleet_b"]] = fleet_b_mu + fleet_b_sig*draws_fleet
randcoeff[["seasonal_b"]] = seasonal_b_mu + seasonal_b_sig*draws_seasonal
randcoeff[["plastic_b"]] = plastic_b_mu + plastic_b_sig*draws_plastic
randcoeff[["buildings_b"]] = buildings_b_mu + buildings_b_sig*draws_buildings
randcoeff[["devices_b"]] = devices_b_mu + devices_b_sig*draws_devices
randcoeff[["fund_b"]] = fund_b_mu + fund_b_sig*draws_fund
randcoeff[["nature_b"]] = nature_b_mu + nature_b_sig*draws_nature
randcoeff[["medicine_b"]] = medicine_b_mu + medicine_b_sig*draws_medicine
randcoeff[["tax_b"]] = -exp(log_tax_b_mu + log_tax_b_sig*draws_tax)
randcoeff[["asc3_b"]] = asc3_b_mu + asc3_b_sig*draws_asc3
return(randcoeff)
}
# ################################################################# #
#### DEFINE LATENT CLASS COMPONENTS ####
# ################################################################# #
apollo_lcPars=function(apollo_beta, apollo_inputs){
lcpars = list()
lcpars[["fleet"]] = list(fleet_a, fleet_b)
lcpars[["seasonal"]] = list(seasonal_a, seasonal_b)
lcpars[["plastic"]] = list(plastic_a, plastic_b)
lcpars[["buildings"]] = list(buildings_a, buildings_b)
lcpars[["devices"]] = list(devices_a, devices_b)
lcpars[["fund"]] = list(fund_a, fund_b)
lcpars[["nature"]] = list(nature_a, nature_b)
lcpars[["medicine"]] = list(medicine_a, medicine_b)
lcpars[["tax"]] = list(tax_a, tax_b)
lcpars[["asc3"]] = list(asc3_a, asc3_b)
#add membership function
V=list()
V[["class_a"]] = delta_a + gamma_age_a*D_age + gamma_male_a*male + gamma_edu_a*degree + gamma_child_a*has_children +
gamma_income_a*D_Lowincome + gamma_climate_a*D_Crn_climate + gamma_urgent_a*urgent_threat +
gamma_PernotNHS_a*D_pers_Notnhs_res
V[["class_b"]] = delta_b + gamma_age_b*D_age + gamma_male_b*male + gamma_edu_b*degree + gamma_child_b*has_children +
gamma_income_b*D_Lowincome + gamma_climate_b*D_Crn_climate + gamma_urgent_b*urgent_threat +
gamma_PernotNHS_b*D_pers_Notnhs_res
classAlloc_settings = list(
classes = c(class_a=1, class_b=2),
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(alt1=1, alt2=1,alt3=1),
avail = list(alt1=1, alt2=1,alt3=1),
choiceVar = choice
)
### Loop over classes
for(s in 1:2){
### Compute class-specific utilities
V=list()
V[['alt1']] = asc1 + fleet[[s]]*replace_fleet1 + seasonal[[s]]*seasonal1 + plastic[[s]]*less_plastic1 + buildings[[s]]*new_buildings1 +
devices[[s]]*return_devices1 + fund[[s]]*fund1 + nature[[s]]*improve_nature1 + medicine[[s]]*green_medicine1 + tax[[s]]*tax1
V[['alt2']] = asc1 + fleet[[s]]*replace_fleet2 + seasonal[[s]]*seasonal2 + plastic[[s]]*less_plastic2 + buildings[[s]]*new_buildings2 +
devices[[s]]*return_devices2 + fund[[s]]*fund2 + nature[[s]]*improve_nature2 + medicine[[s]]*green_medicine2 + tax[[s]]*tax2
V[['alt3']] = asc3[[s]]
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)
Best wishes,
Hangjian Wu