Latent Class Model - Effect coded attributes
Posted: 29 May 2023, 13:27
Hello,
I am running a LCM based on the example LC_no_covariates. Two of my variables are in effect coding, I estimated a MNL and MMNL model I used the "Effects coding constraint" that is used in the MNL_SP_effects example and this worked fine. However, with the LC I have not managed to integrate the constraints into my code, I have tried to do it in multiple ways, but I always get errors and have not been able to estimate the model. I was wondering if you know how I should include the Effect coding constraints or if I have to transform the data and do it in a different way. Thank you!
These are the constraints that I used in my other models:
### Effects coding constraint 1
b_sps = - b_land1 - b_land2
### Effects coding constraint 2
b_nobn = - b_col - b_ind
and I thought for the LCM I could include these :
beta_sps_j = - beta_land1_j - beta_land2_j
beta_sps_k = - beta_land1_k - beta_land2_k
beta_nobn_j = - beta_col_j - beta_ind_j
beta_nobn_k = - beta_col_k - beta_ind_k
Here is the rest of my code:
# \### LOAD LIBRARY AND DEFINE CORE SETTINGS
### Clear memory
rm(list = ls())
### Initialise code
library(apollo)
apollo_initialise()
### Set core controls
apollo_control = list( modelName = "LCM_simple_total",
modelDescr = "Simple LC Logit model on total data",
indivID = "ID",
nCores = 2,
outputDirectory = "output"
)
# ################################################################# #
#### LOAD DATA AND APPLY ANY TRANSFORMATIONS ####
# ################################################################# #
### Loading data from package
### if data is to be loaded from a file (e.g. called data.csv)
load("~/R DCE/Data/rdata/anonymised_data.Rdata")
database = anonymised_data
#### DEFINE MODEL PARAMETERS
### Vector of parameters, including any that are kept fixed in estimation
### k:a and j:b
apollo_beta = c(asc_sq = 0.297499,
beta_price_k = 0.16677,
beta_ta_k = 0.004224,
beta_land1_k = 0.176853,
beta_land2_k = -0.407689,
beta_ind_k = 0.005,
beta_col_k = 0.0001,
beta_price_j = 0.16677,
beta_ta_j = 0.004224,
beta_land1_j = 0.176853,
beta_land2_j = -0.407689,
beta_ind_j = 0.005,
beta_col_j = 0.0001,
delta_j=0,
delta_k=0)
apollo_fixed = c()
apollo_beta_fixed = c()
# ################################################################# #
#### GROUP AND VALIDATE INPUTS ####
# ################################################################# #
apollo_inputs = apollo_validateInputs()
# ################################################################# #
#### DEFINE LATENT CLASS COMPONENTS ####
# ################################################################# #
apollo_lcPars=function(apollo_beta, apollo_inputs){
lcpars = list()
lcpars[["beta_price"]] = list(beta_price_k, beta_price_j)
lcpars[["beta_ta"]] = list(beta_ta_k, beta_ta_j)
lcpars[["beta_sps"]] = list(-apollo_beta["beta_land1_k"] - apollo_beta["beta_land2_k"],
-apollo_beta["beta_land1_j"] - apollo_beta["beta_land2_j"])
lcpars[["beta_land1"]] = list(beta_land1_k, beta_land1_j)
lcpars[["beta_land2"]] = list(beta_land2_k, beta_land2_j)
lcpars[["beta_nobn"]] = list(-apollo_beta["beta_col_k"] - apollo_beta["beta_ind_k"],
-apollo_beta["beta_col_j"] - apollo_beta["beta_ind_j"])
lcpars[["beta_col"]] = list(beta_col_k, beta_col_j)
lcpars[["beta_land2"]] = list(beta_ind_k, beta_ind_j)
V=list()
V[["class_k"]] = delta_k
V[["class_j"]] = delta_j
classAlloc_settings = list(
classes = c(class_k=1, class_j=2),
utilities = V
)
lcpars[["pi_values"]] = apollo_classAlloc(classAlloc_settings)
return(lcpars)
}
# ################################################################# #
#### 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(ProgramA=1, ProgramB=2,
NoProgram=3),
choiceVar = choice
)
### Loop over classes
for(s in 1:2){
###utilities
V = list()
V[["ProgramA"]] = beta_sps* (A.landdist==0) + beta_land1*
(A.landdist==1) + beta_land2* (A.landdist==2) + beta_nobn* (A.bonus==0)+
beta_col* (A.bonus==1) + beta_ind* (A.bonus==2) + beta_ta* A.trainning +
beta_price* A.compensation
V[["ProgramB"]] = beta_sps* (B.landdist==0) +
beta_land1* (B.landdist==1) + beta_land2* (B.landdist==2) + beta_nobn*
(B.bonus==0) + beta_col* (B.bonus==1) + beta_ind* (B.bonus==2) + beta_ta*
B.trainning + beta_price* B.compensation
V[["NoProgram"]] = asc_sq
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)
}
### Compute latent class model probabilities
lc_settings = list(inClassProb = P, 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 ####
# ################################################################# #
model = apollo_estimate(apollo_beta, apollo_fixed, apollo_probabilities, apollo_inputs)
I am running a LCM based on the example LC_no_covariates. Two of my variables are in effect coding, I estimated a MNL and MMNL model I used the "Effects coding constraint" that is used in the MNL_SP_effects example and this worked fine. However, with the LC I have not managed to integrate the constraints into my code, I have tried to do it in multiple ways, but I always get errors and have not been able to estimate the model. I was wondering if you know how I should include the Effect coding constraints or if I have to transform the data and do it in a different way. Thank you!
These are the constraints that I used in my other models:
### Effects coding constraint 1
b_sps = - b_land1 - b_land2
### Effects coding constraint 2
b_nobn = - b_col - b_ind
and I thought for the LCM I could include these :
beta_sps_j = - beta_land1_j - beta_land2_j
beta_sps_k = - beta_land1_k - beta_land2_k
beta_nobn_j = - beta_col_j - beta_ind_j
beta_nobn_k = - beta_col_k - beta_ind_k
Here is the rest of my code:
# \### LOAD LIBRARY AND DEFINE CORE SETTINGS
### Clear memory
rm(list = ls())
### Initialise code
library(apollo)
apollo_initialise()
### Set core controls
apollo_control = list( modelName = "LCM_simple_total",
modelDescr = "Simple LC Logit model on total data",
indivID = "ID",
nCores = 2,
outputDirectory = "output"
)
# ################################################################# #
#### LOAD DATA AND APPLY ANY TRANSFORMATIONS ####
# ################################################################# #
### Loading data from package
### if data is to be loaded from a file (e.g. called data.csv)
load("~/R DCE/Data/rdata/anonymised_data.Rdata")
database = anonymised_data
#### DEFINE MODEL PARAMETERS
### Vector of parameters, including any that are kept fixed in estimation
### k:a and j:b
apollo_beta = c(asc_sq = 0.297499,
beta_price_k = 0.16677,
beta_ta_k = 0.004224,
beta_land1_k = 0.176853,
beta_land2_k = -0.407689,
beta_ind_k = 0.005,
beta_col_k = 0.0001,
beta_price_j = 0.16677,
beta_ta_j = 0.004224,
beta_land1_j = 0.176853,
beta_land2_j = -0.407689,
beta_ind_j = 0.005,
beta_col_j = 0.0001,
delta_j=0,
delta_k=0)
apollo_fixed = c()
apollo_beta_fixed = c()
# ################################################################# #
#### GROUP AND VALIDATE INPUTS ####
# ################################################################# #
apollo_inputs = apollo_validateInputs()
# ################################################################# #
#### DEFINE LATENT CLASS COMPONENTS ####
# ################################################################# #
apollo_lcPars=function(apollo_beta, apollo_inputs){
lcpars = list()
lcpars[["beta_price"]] = list(beta_price_k, beta_price_j)
lcpars[["beta_ta"]] = list(beta_ta_k, beta_ta_j)
lcpars[["beta_sps"]] = list(-apollo_beta["beta_land1_k"] - apollo_beta["beta_land2_k"],
-apollo_beta["beta_land1_j"] - apollo_beta["beta_land2_j"])
lcpars[["beta_land1"]] = list(beta_land1_k, beta_land1_j)
lcpars[["beta_land2"]] = list(beta_land2_k, beta_land2_j)
lcpars[["beta_nobn"]] = list(-apollo_beta["beta_col_k"] - apollo_beta["beta_ind_k"],
-apollo_beta["beta_col_j"] - apollo_beta["beta_ind_j"])
lcpars[["beta_col"]] = list(beta_col_k, beta_col_j)
lcpars[["beta_land2"]] = list(beta_ind_k, beta_ind_j)
V=list()
V[["class_k"]] = delta_k
V[["class_j"]] = delta_j
classAlloc_settings = list(
classes = c(class_k=1, class_j=2),
utilities = V
)
lcpars[["pi_values"]] = apollo_classAlloc(classAlloc_settings)
return(lcpars)
}
# ################################################################# #
#### 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(ProgramA=1, ProgramB=2,
NoProgram=3),
choiceVar = choice
)
### Loop over classes
for(s in 1:2){
###utilities
V = list()
V[["ProgramA"]] = beta_sps* (A.landdist==0) + beta_land1*
(A.landdist==1) + beta_land2* (A.landdist==2) + beta_nobn* (A.bonus==0)+
beta_col* (A.bonus==1) + beta_ind* (A.bonus==2) + beta_ta* A.trainning +
beta_price* A.compensation
V[["ProgramB"]] = beta_sps* (B.landdist==0) +
beta_land1* (B.landdist==1) + beta_land2* (B.landdist==2) + beta_nobn*
(B.bonus==0) + beta_col* (B.bonus==1) + beta_ind* (B.bonus==2) + beta_ta*
B.trainning + beta_price* B.compensation
V[["NoProgram"]] = asc_sq
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)
}
### Compute latent class model probabilities
lc_settings = list(inClassProb = P, 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 ####
# ################################################################# #
model = apollo_estimate(apollo_beta, apollo_fixed, apollo_probabilities, apollo_inputs)