Page 1 of 1
LCCM model with two choice models
Posted: 18 Mar 2022, 17:12
by jaimlk77
Hi
I am trying to estimate a LCCM with two choice models in each latent class. Is that possible to estimate in Apollo?
As shown in the attached subset of the R code. I am trying to wrap two MNLs in latent classes. However, I keep getting the following error:
Error in apollo_lc(lc_settings, apollo_inputs, functionality) :
Arguments 'inClassProb' and 'classProb' for model component "LC" must have the same length.
I thought using the apollo_combineModels would resolve this issue but that did not help. Does anyone have any suggestions on how I can resolve this issue?
Thanks,
Jai
### Loop over classes
for(s in 1:2){
### Compute class-specific utilities
V_1[["alt_1"]] = asc_1_1[[s]] + b_age_num_1_1[[s]] * (age_num == 1) + b_age_num_2_1[[s]] * (age_num == 2) + b_gender_1[[s]] * (gender_num == 1)
V_1[["alt_2"]] = asc_2_1[[s]] + b_age_num_1_1[[s]] * (age_num == 1) + b_age_num_2_1[[s]] * (age_num == 2) + b_gender_1[[s]] * (gender_num == 1)
V_1[["alt_3"]] = asc_3_1[[s]] + b_age_num_1_1[[s]] * (age_num == 1) + b_age_num_2_1[[s]] * (age_num == 2) + b_gender_1[[s]] * (gender_num == 1)
V_1[["alt_4"]] = asc_4_1[[s]]
mnl_settings_1$utilities = V_1
mnl_settings_1$componentName = paste0("model1_Class_",s)
### Compute within-class choice probabilities using MNL model
P[[paste0("model1_Class_",s)]] = apollo_mnl(mnl_settings_1, functionality)
V_2 = list()
V_2[["alt_1"]] = asc_1_2[[s]] + b_age_num_1_2[[s]] * (age_num == 1) + b_age_num_2_2[[s]] * (age_num == 2) + b_gender_2[[s]] * (gender_num == 1)
V_2[["alt_2"]] = asc_2_2[[s]] + b_age_num_1_2[[s]] * (age_num == 1) + b_age_num_2_2[[s]] * (age_num == 2) + b_gender_2[[s]] * (gender_num == 1)
V_2[["alt_3"]] = asc_3_2[[s]] + b_age_num_1_2[[s]] * (age_num == 1) + b_age_num_2_2[[s]] * (age_num == 2) + b_gender_2[[s]] * (gender_num == 1)
V_2[["alt_4"]] = asc_4_2[[s]]
mnl_settings_2$utilities = V_2
mnl_settings_2$componentName = paste0("model2_Class_",s)
### Compute within-class choice probabilities using MNL model
P[[paste0("model2_Class_",s)]] = apollo_mnl(mnl_settings_2, functionality)
}
Re: LCCM model with two choice models
Posted: 21 Mar 2022, 18:28
by stephanehess
Hi
could you please post the entire apollo_probabilities function for your example?
Thanks
Stephane
Re: LCCM model with two choice models
Posted: 22 Mar 2022, 06:36
by jaimlk77
Hi
Please see the entire apollo_probabilities below.
Thanks,
Jai
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()
### List of utilities: these must use the same names as in mnl_settings, order is irrelevant
V_1 = list()
### Define settings for MNL model component
mnl_settings_1 = list(
alternatives = c(alt_1 = 1, alt_2 = 2, alt_3 = 3, alt_4 = 4),
avail = list(alt_1 = 1, alt_2 = 1, alt_3 = 1, alt_4 = 1),
choiceVar = actual_veh_change_fall19_fall20)
### Define settings for MNL model component
mnl_settings_2 = list(
alternatives = c(alt_1 = 1, alt_2 = 2, alt_3 = 3, alt_4 = 4),
avail = list(alt_1 = 1, alt_2 = 1, alt_3 = 1, alt_4 = 1),
choiceVar = expect_change_fall20_summer20)
### Loop over classes
for(s in 1:2){
### Compute class-specific utilities
V_1[["alt_1"]] = asc_1_1[[s]] + b_age_num_1_1[[s]] * (age_num == 1) + b_age_num_2_1[[s]] * (age_num == 2) + b_gender_1[[s]] * (gender_num == 1)
V_1[["alt_2"]] = asc_2_1[[s]] + b_age_num_1_1[[s]] * (age_num == 1) + b_age_num_2_1[[s]] * (age_num == 2) + b_gender_1[[s]] * (gender_num == 1)
V_1[["alt_3"]] = asc_3_1[[s]] + b_age_num_1_1[[s]] * (age_num == 1) + b_age_num_2_1[[s]] * (age_num == 2) + b_gender_1[[s]] * (gender_num == 1)
V_1[["alt_4"]] = asc_4_1[[s]]
mnl_settings_1$utilities = V_1
mnl_settings_1$componentName = paste0("model1_Class_",s)
### Compute within-class choice probabilities using MNL model
P[[paste0("model1_Class_",s)]] = apollo_mnl(mnl_settings_1, functionality)
V_2 = list()
V_2[["alt_1"]] = asc_1_2[[s]] + b_age_num_1_2[[s]] * (age_num == 1) + b_age_num_2_2[[s]] * (age_num == 2) + b_gender_2[[s]] * (gender_num == 1)
V_2[["alt_2"]] = asc_2_2[[s]] + b_age_num_1_2[[s]] * (age_num == 1) + b_age_num_2_2[[s]] * (age_num == 2) + b_gender_2[[s]] * (gender_num == 1)
V_2[["alt_3"]] = asc_3_2[[s]] + b_age_num_1_2[[s]] * (age_num == 1) + b_age_num_2_2[[s]] * (age_num == 2) + b_gender_2[[s]] * (gender_num == 1)
V_2[["alt_4"]] = asc_4_2[[s]]
mnl_settings_2$utilities = V_2
mnl_settings_2$componentName = paste0("model2_Class_",s)
### Compute within-class choice probabilities using MNL model
P[[paste0("model2_Class_",s)]] = apollo_mnl(mnl_settings_2, functionality)
}
### Compute latent class model probabilities
lc_settings = list(inClassProb = P, classProb=pi_values)
P[["lc_model"]] = apollo_lc(lc_settings, apollo_inputs, functionality)
### Take product across observation for same individual
# P = apollo_panelProd(P, apollo_inputs, functionality)
#P = apollo_combineModels(P, apollo_inputs, functionality)
### Prepare and return outputs of function
P = apollo_prepareProb(P, apollo_inputs, functionality)
return(P)
}
Re: LCCM model with two choice models
Posted: 22 Mar 2022, 10:19
by stephanehess
Hi
you'll need to call apollo_combineModels inside the loop over classes, so that your two MNL models are combined inside the class.
But I think you also need to change some names for that to work. Can you try the following:
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()
### List of utilities: these must use the same names as in mnl_settings, order is irrelevant
V_1 = list()
### Define settings for MNL model component
mnl_settings_1 = list(
alternatives = c(alt_1 = 1, alt_2 = 2, alt_3 = 3, alt_4 = 4),
avail = list(alt_1 = 1, alt_2 = 1, alt_3 = 1, alt_4 = 1),
choiceVar = actual_veh_change_fall19_fall20)
### Define settings for MNL model component
mnl_settings_2 = list(
alternatives = c(alt_1 = 1, alt_2 = 2, alt_3 = 3, alt_4 = 4),
avail = list(alt_1 = 1, alt_2 = 1, alt_3 = 1, alt_4 = 1),
choiceVar = expect_change_fall20_summer20)
### Loop over classes
for(s in 1:2){
P_temp=list()
### Compute class-specific utilities
V_1[["alt_1"]] = asc_1_1[[s]] + b_age_num_1_1[[s]] * (age_num == 1) + b_age_num_2_1[[s]] * (age_num == 2) + b_gender_1[[s]] * (gender_num == 1)
V_1[["alt_2"]] = asc_2_1[[s]] + b_age_num_1_1[[s]] * (age_num == 1) + b_age_num_2_1[[s]] * (age_num == 2) + b_gender_1[[s]] * (gender_num == 1)
V_1[["alt_3"]] = asc_3_1[[s]] + b_age_num_1_1[[s]] * (age_num == 1) + b_age_num_2_1[[s]] * (age_num == 2) + b_gender_1[[s]] * (gender_num == 1)
V_1[["alt_4"]] = asc_4_1[[s]]
mnl_settings_1$utilities = V_1
mnl_settings_1$componentName = paste0("model1_Class_",s)
### Compute within-class choice probabilities using MNL model
P_temp[[paste0("model1_Class_",s)]] = apollo_mnl(mnl_settings_1, functionality)
V_2 = list()
V_2[["alt_1"]] = asc_1_2[[s]] + b_age_num_1_2[[s]] * (age_num == 1) + b_age_num_2_2[[s]] * (age_num == 2) + b_gender_2[[s]] * (gender_num == 1)
V_2[["alt_2"]] = asc_2_2[[s]] + b_age_num_1_2[[s]] * (age_num == 1) + b_age_num_2_2[[s]] * (age_num == 2) + b_gender_2[[s]] * (gender_num == 1)
V_2[["alt_3"]] = asc_3_2[[s]] + b_age_num_1_2[[s]] * (age_num == 1) + b_age_num_2_2[[s]] * (age_num == 2) + b_gender_2[[s]] * (gender_num == 1)
V_2[["alt_4"]] = asc_4_2[[s]]
mnl_settings_2$utilities = V_2
mnl_settings_2$componentName = paste0("model2_Class_",s)
### Compute within-class choice probabilities using MNL model
P_temp[[paste0("model2_Class_",s)]] = apollo_mnl(mnl_settings_2, functionality)
P[[paste0("Class_",s)]] = apollo_combineModels(P_temp,functionality)
}
### Compute latent class model probabilities
lc_settings = list(inClassProb = P, classProb=pi_values)
P[["lc_model"]] = apollo_lc(lc_settings, apollo_inputs, functionality)
### Take product across observation for same individual
P = apollo_panelProd(P, apollo_inputs, functionality)
#P = apollo_combineModels(P, apollo_inputs, functionality)
### Prepare and return outputs of function
P = apollo_prepareProb(P, apollo_inputs, functionality)
return(P)
}
Re: LCCM model with two choice models
by stephanehess » Mon Mar 21, 2022 7:28 pm
Hi
could you please post the entire apollo_probabilities function for your example?
Thanks
Stephane
LCCM model with two choice models
by jaimlk77 » Fri Mar 18, 2022 6:12 pm
Hi
I am trying to estimate a LCCM with two choice models in each latent class. Is that possible to estimate in Apollo?
As shown in the attached subset of the R code. I am trying to wrap two MNLs in latent classes. However, I keep getting the following error:
Error in apollo_lc(lc_settings, apollo_inputs, functionality) :
Arguments 'inClassProb' and 'classProb' for model component "LC" must have the same length.
I thought using the apollo_combineModels would resolve this issue but that did not help. Does anyone have any suggestions on how I can resolve this issue?
Thanks,
Jai
### Loop over classes
for(s in 1:2){
### Compute class-specific utilities
V_1[["alt_1"]] = asc_1_1[[s]] + b_age_num_1_1[[s]] * (age_num == 1) + b_age_num_2_1[[s]] * (age_num == 2) + b_gender_1[[s]] * (gender_num == 1)
V_1[["alt_2"]] = asc_2_1[[s]] + b_age_num_1_1[[s]] * (age_num == 1) + b_age_num_2_1[[s]] * (age_num == 2) + b_gender_1[[s]] * (gender_num == 1)
V_1[["alt_3"]] = asc_3_1[[s]] + b_age_num_1_1[[s]] * (age_num == 1) + b_age_num_2_1[[s]] * (age_num == 2) + b_gender_1[[s]] * (gender_num == 1)
V_1[["alt_4"]] = asc_4_1[[s]]
mnl_settings_1$utilities = V_1
mnl_settings_1$componentName = paste0("model1_Class_",s)
### Compute within-class choice probabilities using MNL model
P[[paste0("model1_Class_",s)]] = apollo_mnl(mnl_settings_1, functionality)
V_2 = list()
V_2[["alt_1"]] = asc_1_2[[s]] + b_age_num_1_2[[s]] * (age_num == 1) + b_age_num_2_2[[s]] * (age_num == 2) + b_gender_2[[s]] * (gender_num == 1)
V_2[["alt_2"]] = asc_2_2[[s]] + b_age_num_1_2[[s]] * (age_num == 1) + b_age_num_2_2[[s]] * (age_num == 2) + b_gender_2[[s]] * (gender_num == 1)
V_2[["alt_3"]] = asc_3_2[[s]] + b_age_num_1_2[[s]] * (age_num == 1) + b_age_num_2_2[[s]] * (age_num == 2) + b_gender_2[[s]] * (gender_num == 1)
V_2[["alt_4"]] = asc_4_2[[s]]
mnl_settings_2$utilities = V_2
mnl_settings_2$componentName = paste0("model2_Class_",s)
### Compute within-class choice probabilities using MNL model
P[[paste0("model2_Class_",s)]] = apollo_mnl(mnl_settings_2, functionality)
}
Re: LCCM model with two choice models
Posted: 03 Feb 2023, 15:30
by punyabeet
Hi Prof Stephane
Thanks for the apollo forum. I tried to estimate LCCM with two choice models in each latent class with a similar specification as above. However, I keep getting the following error:
Error in apollo_validate(classAlloc_settings, modelType, functionality, :
Some of the names of the classes for model component 'classAlloc' do not match!
I think I have made an error in defining the latent class components. Can you please point out the mistake in the R code snippet?
# ################################################################# #
#### DEFINE MODEL PARAMETERS ####
# ################################################################# #
### Vector of parameters, including any that are kept fixed in estimation
apollo_beta = c(asc_1_1 = 0,
asc_2_1 = 0,
asc_3_1 = 0,
asc_1_2 = 0,
asc_2_2 = 0,
asc_3_2 = 0,
b_tt_a = 0,
b_tt_b = 0,
delta_a_1 = 0,
delta_a_2 = 0,
delta_b_1 = 0,
delta_b_2 = 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_b_1", "delta_b_2", "asc_3_1", "asc_3_2")
# ################################################################# #
#### DEFINE LATENT CLASS COMPONENTS ####
# ################################################################# #
apollo_lcPars=function(apollo_beta, apollo_inputs){
lcpars = list()
lcpars[["b_tt_1"]] = list(b_tt_a, b_tt_b)
lcpars[["b_tt_2"]] = list(b_tt_a, b_tt_b)
V_1 = list()
V_1[["class_a"]] = delta_a_1
V_1[["class_b"]] = delta_b_1
V_2 = list()
V_2[["class_a"]] = delta_a_2
V_2[["class_b"]] = delta_b_2
### Settings for class allocation models
classAlloc_settings = list(
classes = c(class_a=1, class_b=2),
utilities = V
)
### Settings for class allocation models
classAlloc_settings = list(
classes = c(class_a = 1, class_b = 2),
utilities = c(V_1, V_2),
avail = 1
)
lcpars[["pi_values"]] = apollo_classAlloc(classAlloc_settings)
return(lcpars)
}
Many thanks for considering my request.
Punya
Re: LCCM model with two choice models
Posted: 28 Feb 2023, 22:38
by dpalma
Hi Punya,
Your code is using two class allocation functions. What I believe you want is a single allocation function, and within each class to have two choices. Below is an example that does so.
The example uses the example database apollo_timeUseData, and it estimates a latent class model with two classes. Within each class, there are two choices: to engage in leasure (yes/no), and to engage in work (yes/no). Each choice has different parameters inside each class. You can try using this structure for your application.
Cheers
David
Code: Select all
# ################################################################# #
#### LOAD LIBRARY AND DEFINE CORE SETTINGS ####
# ################################################################# #
### Initialise
rm(list = ls())
library(apollo)
apollo_initialise()
### Set core controls
apollo_control = list(
modelName = "LC_twoChoices",
modelDescr = "LC models with 2 classes and two choices inside each",
indivID = "indivID"
)
# ################################################################# #
#### LOAD DATA AND APPLY ANY TRANSFORMATIONS ####
# ################################################################# #
### Loading data from package
### if data is to be loaded from a file (e.g. called data.csv),
### the code would be: database = read.csv("data.csv",header=TRUE)
database = apollo_timeUseData
### for data dictionary, use ?apollo_timeUseData
# outside good: time spent at home and travelling
database$t_outs = rowSums(database[,c("t_a01", "t_a06", "t_a10", "t_a11", "t_a12")])/60
database$t_leis = rowSums(database[,c("t_a07", "t_a08", "t_a09")])/60
database$t_work = database$t_a02/60
database$t_scho = database$t_a03/60
database$t_shop = database$t_a04/60
database$t_priv = database$t_a05/60
database$doesLeisure <- database$t_leis > 0
database$doesWork <- database$t_work > 0
# ################################################################# #
#### DEFINE MODEL PARAMETERS ####
# ################################################################# #
### Vector of parameters, including any that are kept fixed in estimation
apollo_beta = c(ascL_1 = 0, ascL_2 = 0,
bFeL_1 = 0, bFeL_2 = 0,
bAgL_1 = 0, bAgL_2 = 0,
bFTL_1 = 0, bFTL_2 = 0,
bWkL_1 = 0, bWkL_2 = 0,
ascW_1 = 0, ascW_2 = 0,
bFeW_1 = 0, bFeW_2 = 0,
bAgW_1 = 0, bAgW_2 = 0,
bFTW_1 = 0, bFTW_2 = 0,
bWkW_1 = 0, bWkW_2 = 0,
delt_1 = 0, delt_2 = 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("delt_2")
# ################################################################# #
#### DEFINE LATENT CLASS COMPONENTS ####
# ################################################################# #
apollo_lcPars=function(apollo_beta, apollo_inputs){
lcpars = list()
lcpars[["ascL"]] = list(ascL_1, ascL_2)
lcpars[["bFeL"]] = list(bFeL_1, bFeL_2)
lcpars[["bAgL"]] = list(bAgL_1, bAgL_2)
lcpars[["bFTL"]] = list(bFTL_1, bFTL_2)
lcpars[["bWkL"]] = list(bWkL_1, bWkL_2)
lcpars[["ascW"]] = list(ascW_1, ascW_2)
lcpars[["bFeW"]] = list(bFeW_1, bFeW_2)
lcpars[["bAgW"]] = list(bAgW_1, bAgW_2)
lcpars[["bFTW"]] = list(bFTW_1, bFTW_2)
lcpars[["bWkW"]] = list(bWkW_1, bWkW_2)
classAlloc_settings = list(
utilities = list(class_1 = delt_1,
class_2 = delt_2)
)
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"){
### Initialise
apollo_attach(apollo_beta, apollo_inputs)
on.exit(apollo_detach(apollo_beta, apollo_inputs))
P = list()
### Define settings for MNL model component that are generic across classes
mnl_leisure_settings = list(
alternatives = c(no=0, yes=1),
choiceVar = doesLeisure
)
mnl_work_settings = list(
alternatives = c(no=0, yes=1),
choiceVar = doesWork
)
### Loop over classes
for(s in 1:2){
### Leisure decision within class s
mnl_leisure_settings$utilities = list(
no = 0,
yes = ascL[[s]] + bFeL[[s]]*female + bAgL[[s]]*age + bFTL[[s]]*occ_full_time + bWkL[[s]]*weekend
)
P[[paste0("Class_",s,"_leisure")]] = apollo_mnl(mnl_leisure_settings, functionality)
### Work decision within class s
mnl_work_settings$utilities = list(
no = 0,
yes = ascW[[s]] + bFeW[[s]]*female + bAgW[[s]]*age + bFTW[[s]]*occ_full_time + bWkW[[s]]*weekend
)
P[[paste0("Class_",s,"_work")]] = apollo_mnl(mnl_work_settings, functionality)
### Take product of both decisions
P[[paste0("Class_",s)]] = P[[paste0("Class_",s,"_leisure")]]*P[[paste0("Class_",s,"_work")]]
### Take product across observation for same individual
P[[paste0("Class_",s)]] = apollo_panelProd(P[[paste0("Class_",s)]], apollo_inputs ,functionality)
}
### Compute latent class model probabilities
lc_settings = list(inClassProb = P[paste0("Class_",1:2)], classProb=pi_values)
P[["model"]] = apollo_lc(lc_settings, apollo_inputs, functionality)
### Prepare and return outputs of function
P = apollo_prepareProb(P, apollo_inputs, functionality)
return(P)
}
# ################################################################# #
#### MODEL ESTIMATION AND OUTPUT ####
# ################################################################# #
### Estimation
model = apollo_estimate(apollo_beta, apollo_fixed, apollo_probabilities,
apollo_inputs)
### Output to screen
apollo_modelOutput(model)
### Output to file
apollo_saveOutput(model)