I have another question regarding the example that you kindly provided. In the code that you've shared, is b a scale parameter, and m a location parameter? When you speak about normalisation, do you mean that b and m should be kept fixed in apollo_fixed?
In the model below I'm trying to classify my respondents into latent classes using a threshold for a latent variable. While the model seems to be running without errors, I'm not fully certain that my code is correct. Can you please take a look at it?
Code: Select all
# ################################################################# #
#### LOAD LIBRARY AND DEFINE CORE SETTINGS ####
# ################################################################# #
### Clear memory
rm(list = ls())
### Load libraries
library(apollo)
### Initialise code
apollo_initialise()
### Set core controls
apollo_control = list(
modelName ="LatentClass_LV1_N1.4_imp",
modelDescr ="ILVLC with 1 LV",
indivID ="UNID",
panelData = FALSE,
mixing = TRUE,
#workInLogs = TRUE,
nCores = 3)
# ################################################################# #
#### LOAD DATA AND APPLY ANY TRANSFORMATIONS ####
# ################################################################# #
setwd("D:/Data")
database = read.csv("latent_class.csv",header=TRUE)
# ################################################################# #
#### DEFINE MODEL PARAMETERS ####
# ################################################################# #
### Vector of parameters, including any that are kept fixed in estimation
apollo_beta=c(zeta_aconC = 1,
zeta_sconC = 1,
zeta_bothC = 1,
zeta_seatC = 1,
zeta_offpeakC = 1,
zeta_altC = 1,
tau_acon_1C =-2,
tau_acon_2C =-1,
tau_acon_3C = 1,
tau_acon_4C = 2,
tau_scon_1C =-2,
tau_scon_2C =-1,
tau_scon_3C = 1,
tau_scon_4C = 2,
tau_both_1C =-2,
tau_both_2C =-1,
tau_both_3C = 1,
tau_both_4C = 2,
tau_seat_1C =-2,
tau_seat_2C =-1,
tau_seat_3C = 1,
tau_seat_4C = 2,
tau_offpeak_1C =-2,
tau_offpeak_2C =-1,
tau_offpeak_3C = 1,
tau_offpeak_4C = 2,
tau_alt_1C =-2,
tau_alt_2C =-1,
tau_alt_3C = 1,
tau_alt_4C = 2,
zeta_sconX_A = 1,
zeta_sconX_B = -1,
tau_scon_1X =-2,
tau_scon_2X =-1,
tau_scon_3X = 1,
tau_scon_4X = 2,
gamma_LV1_female = 1,
gamma_LV1_fulltime = 1,
gamma_LV1_incomelow = 1,
gamma_LV1_age2534 = 1,
gamma_LV1_edbach = 1,
gamma_LV1_kids = 1,
gamma_LV1_car = 1,
gamma_LV1_wave2 = 1,
b1 = 1,
m1 = 0,
thre1 = 1)
### 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("b1", "m1")
# ################################################################# #
#### DEFINE RANDOM COMPONENTS ####
# ################################################################# #
### Set parameters for generating draws
apollo_draws = list(
interDrawsType="halton",
interNDraws=50,
interUnifDraws=c("eta1"),
interNormDraws=c(),
intraDrawsType='',
intraNDraws=0,
intraUnifDraws=c(),
intraNormDraws=c()
)
### Create random parameters
apollo_randCoeff=function(apollo_beta, apollo_inputs){
randcoeff = list()
randcoeff[["LVC1"]] = gamma_LV1_female * FEMALE + gamma_LV1_wave2 * WAVE2 +
gamma_LV1_fulltime * EMPLOY_FULL + gamma_LV1_incomelow * INCOME_LOW + gamma_LV1_age2534 * AGE_2534 +
gamma_LV1_edbach * EDUCATION_BACH + gamma_LV1_kids * HOUSEHOLD_CHILD_CLEAN_N + gamma_LV1_car * CAR_B +
2*b1*atanh(2*eta1-1)+m1 #Error term follows a logistic distribution (to match the logit in allocation function)
randcoeff[["LVX1"]] = gamma_LV1_female * FEMALE + gamma_LV1_wave2 * WAVE2 +
gamma_LV1_fulltime * EMPLOY_FULL + gamma_LV1_incomelow * INCOME_LOW + gamma_LV1_age2534 * AGE_2534 +
gamma_LV1_edbach * EDUCATION_BACH + gamma_LV1_kids * HOUSEHOLD_CHILD_CLEAN_N + gamma_LV1_car * CAR_B
return(randcoeff)
}
# ################################################################# #
#### DEFINE LATENT CLASS COMPONENTS ####
# ################################################################# #
apollo_lcPars=function(apollo_beta, apollo_inputs){
lcpars = list()
### Define lists of parameters for each class
### classA classB ...
lcpars[["zeta_sconX"]] = list(zeta_sconX_A, zeta_sconX_B)
### Class allocation probabilities
### These are the probabilities of a binary logit model
classAlloc_settings = list(
V = list(A = LVC1-thre1,
B = 0)
)
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()
PClass4 = list()
### Likelihood of indicators
ol_settings1C = list(outcomeOrdered=AGREE_BOTH_CROWD_BC_R,
V=zeta_bothC*LVC1,
tau=list(tau_both_1C, tau_both_2C, tau_both_3C, tau_both_4C))
ol_settings2C = list(outcomeOrdered=AGREE_CONCERN_BC_R,
V=zeta_aconC*LVC1,
tau=list(tau_acon_1C, tau_acon_2C, tau_acon_3C, tau_acon_4C))
ol_settings3C = list(outcomeOrdered=AGREE_SEAT_BC_R,
V=zeta_seatC*LVC1,
tau=list(tau_seat_1C, tau_seat_2C, tau_seat_3C, tau_seat_4C))
ol_settings4C = list(outcomeOrdered=STATE_CONCERNED_R,
V=zeta_sconC*LVC1,
tau=list(tau_scon_1C, tau_scon_2C, tau_scon_3C, tau_scon_4C))
ol_settings5C = list(outcomeOrdered=AGREE_OFFPEAK_BC_R,
V=zeta_offpeakC*LVC1,
tau=list(tau_offpeak_1C, tau_offpeak_2C, tau_offpeak_3C, tau_offpeak_4C))
ol_settings6C = list(outcomeOrdered=AGREE_ALT_BC_R,
V=zeta_altC*LVC1,
tau=list(tau_alt_1C, tau_alt_2C, tau_alt_3C, tau_alt_4C))
P[["indic_bothC"]] = apollo_ol(ol_settings1C, functionality)
P[["indic_aconC"]] = apollo_ol(ol_settings2C, functionality)
P[["indic_seatC"]] = apollo_ol(ol_settings3C, functionality)
P[["indic_sconC"]] = apollo_ol(ol_settings4C, functionality)
P[["indic_offpeakC"]] = apollo_ol(ol_settings5C, functionality)
P[["indic_altC"]] = apollo_ol(ol_settings6C, functionality)
### Categorical LV_1 - Indicator 4
### Define settings for OL model component that are generic across classes
ol_settings4X = list(
outcomeOrdered = STATE_CONCERNED_R,
tau = list(tau_scon_1X, tau_scon_2X, tau_scon_3X, tau_scon_4X),
coding = c(1,2,3,4,5))
### Loop over classes
S = 2 # number of classes
for(s in 1:S){
### Class-specific utilities
ol_settings4X$V = zeta_sconX[[s]]*LVX1
### Within-class choice probabilities using OL model
label = paste0("sconClass",s)
PClass4[[label]] = apollo_ol(ol_settings4X, functionality)
### Take product across observation for same individual
#PClass[[label]] = apollo_panelProd(PClass[[label]], apollo_inputs, functionality)
}
### Mix the probabilities from each class
lc_settings4 = list(inClassProb=PClass4, classProb=pi_values)
P[["indic_sconX"]] = apollo_lc(lc_settings4, apollo_inputs, functionality)
### Likelihood of the whole model
P = apollo_combineModels(P, apollo_inputs, functionality)
### Average across inter-individual draws
P = apollo_avgInterDraws(P, apollo_inputs, functionality)
### Prepare and return outputs of function
P = apollo_prepareProb(P, apollo_inputs, functionality)
return(P)
}
# ################################################################# #
#### ESTIMATE SETTINGS ####
# ################################################################# #
estimate_settings = list(maxIterations = 250, scaling = TRUE)
# ################################################################# #
#### MODEL ESTIMATION ####
# ################################################################# #
model = apollo_estimate(apollo_beta, apollo_fixed, apollo_probabilities, apollo_inputs, estimate_settings)