Page 1 of 1

Error in Latent Class Nested Logit Model- NAN

Posted: 15 Aug 2022, 19:00
by Chunyu Song
Dear all,

Apologies if this is in the manual, but I've been searching all day and I can't find it.

I want to create a model to analyze heterogeneity between classes and substitution between choices by using latent class analysis with nested logit model. But I am having some problems running this model (There are many "NANs" in the results). I copied my codes and results below, I appreciate if you can have a look and advise what could be the issue?

male(binary: 1 / 0)
Thanks and regards,
Chunyu

Code: Select all

[### Clear memory
rm(list = ls())

### Load Apollo library
library(apollo)

### Initialise code
apollo_initialise()

apollo_control = list(
  modelName ="Apollo_example_20_LC-NL",
  modelDescr ="LC model with class allocation model",
  indivID ="ID",
  nCores = 4
)
database = read.csv
database = subset(database,database$SP==1)
## scaled variables
apollo_beta = c(
                asc_DF_c1 = 0.6,
                asc_HF_c1 = 0.2,
                b_cost_c1 = 0,
                b_rat_c1 = 0,
                b_trf_c1 = 0,
                b_wat_c1 = 0,
                b_ser_P_c1 = 0,
                b_ser_A_c1 = 0,
                b_ser_G_c1 = 0,
                b_envi_P_c1 = 0,
                b_envi_A_c1 = 0,
                b_envi_G_c1 = 0,
                lambda_A_c1 = 1,
                lambda_B_c1 = 0.5,
                delta_c1 = 0,
                gamma_male_c1 = 0,
                asc_DF_c2 = 0.3,
                asc_HF_c2 = 0.2,
                b_cost_c2 = 0,
                b_rat_c2 = 0,
                b_trf_c2 = 0,
                b_wat_c2 = 0,
                b_ser_P_c2 = 0,
                b_ser_A_c2 = 0,
                b_ser_G_c2 = 0,
                b_envi_P_c2 = 0,
                b_envi_A_c2 = 0,
                b_envi_G_c2 = 0,
                lambda_A_c2 = 1,
                lambda_B_c2 = 0.5,
                delta_c2 = 0,
                gamma_male_c2 = 0,
                asc_DF_c3 = 0,
                asc_HF_c3 = 0,
                b_cost_c3 = 0,
                b_rat_c3 = 0,
                b_trf_c3 = 0,
                b_wat_c3 = 0,
                b_ser_P_c3 = 0,
                b_ser_A_c3 = 0,
                b_ser_G_c3 = 0,
                b_envi_P_c3 = 0,
                b_envi_A_c3 = 0,
                b_envi_G_c3 = 0,
                lambda_A_c3 = 1,
                lambda_B_c3 = 0.5,
                delta_c3 = 0,
                gamma_male_c3 = 0
)
apollo_fixed = c("delta_c3","lambda_A_c1","lambda_A_c2","lambda_A_c3","gamma_male_c3")

## Define latent class components
apollo_lcPars = function(apollo_beta, apollo_inputs){
  lcpars = list()
  lcpars[["b_cost"]] = list(b_cost_c1,b_cost_c2,b_cost_c3)
  lcpars[["b_rat"]] = list(b_rat_c1,b_rat_c2,b_rat_c3)
  lcpars[["b_trf"]] = list(b_trf_c1,b_trf_c2,b_trf_c3)
  lcpars[["b_wat"]] = list(b_wat_c1,b_wat_c2,b_wat_c3)
  lcpars[["b_ser_P"]] = list(b_ser_P_c1,b_ser_P_c2,b_ser_P_c3)
  lcpars[["b_ser_A"]] = list(b_ser_A_c1,b_ser_A_c2,b_ser_A_c3)
  lcpars[["b_ser_G"]] = list(b_ser_G_c1,b_ser_G_c2,b_ser_G_c3)
  lcpars[["b_envi_P"]] = list(b_envi_P_c1,b_envi_P_c2,b_envi_P_c3)
  lcpars[["b_envi_A"]] = list(b_envi_A_c1,b_envi_A_c2,b_envi_A_c3)
  lcpars[["b_envi_G"]] = list(b_envi_G_c1,b_envi_G_c2,b_envi_G_c3)
  lcpars[["asc_DF"]] = list(asc_DF_c1,asc_DF_c2,asc_DF_c3)
  lcpars[["asc_HF"]] = list(asc_HF_c1,asc_HF_c2,asc_HF_c3)

  #Utilities of class allocation model
  V = list()
  V[["class_1"]] = delta_c1 + gamma_male_c1*male
  V[["class_2"]] = delta_c2 + gamma_male_c2*male
  V[["class_3"]] = delta_c3 + gamma_male_c3*male


classAlloc_settings = list(
  classes      = c(class_1=1, class_2=2, class_3=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()
  ### Specify nests for NL model
  nlNests = list()
  nlNests[[1]] = list(root=1, A_c1=lambda_A_c1, B_c1 = lambda_B_c1)
  nlNests[[2]] = list(root=1, A_c2=lambda_A_c2, B_c2 = lambda_B_c2)
  nlNests[[3]] = list(root=1, A_c3=lambda_A_c3, B_c3 = lambda_B_c3)
  nlStructure = list()
  nlStructure[[1]] = list()
  nlStructure[[2]] = list()
  nlStructure[[3]] = list()
  nlStructure[[1]][["root"]] = c("A_c1","B_c1")
  nlStructure[[2]][["root"]] = c("A_c2","B_c2")
  nlStructure[[3]][["root"]] = c("A_c3","B_c3")
  
  nlStructure[[1]][["A_c1"]] = c("HF")
  nlStructure[[1]][["B_c1"]] = c("DF","FF")
  nlStructure[[2]][["A_c2"]] = c("HF")
  nlStructure[[2]][["B_c2"]] = c("DF","FF")
  nlStructure[[3]][["A_c3"]] = c("HF")
  nlStructure[[3]][["B_c3"]] = c("DF","FF")
  
  nl_settings <- list(
    alternatives = c(FF=1, DF=2, HF=3),
    avail = list(FF=av_FF, DF=av_DF, HF=av_HF),
    choiceVar = choice,
    nlNests = nlNests,
    nlStructure = nlStructure
  )
  ### Loop over classes
  s=1
  while(s<=3){
    ### Compute class-specific utilities
    V=list()
    V[['FF']] = b_cost[[s]] * cost_FF + b_rat[[s]] * rating_FF + b_trf[[s]] * trf_FF + b_wat[[s]] * wat_FF + b_ser_P[[s]] * (service_FF==1) + b_ser_A[[s]] * (service_FF==2) + b_ser_G[[s]] * (service_FF==3) + b_envi_P[[s]] * (envi_FF==1) + b_envi_A[[s]] * (envi_FF==2) + b_envi_G[[s]] * (envi_FF==3)
    V[['DF']] = asc_DF[[s]] + b_cost[[s]] * cost_DF + b_rat[[s]] * rating_DF + b_trf[[s]] * trf_DF + b_wat[[s]] * wat_DF + b_ser_P[[s]] * (service_DF==1) + b_ser_A[[s]] * (service_DF==2) + b_ser_G[[s]] * (service_DF==3) + b_envi_P[[s]] * (envi_DF==1) + b_envi_A[[s]] * (envi_DF==2) + b_envi_G[[s]] * (envi_DF==3)
    V[['HF']] = asc_HF[[s]] + b_cost[[s]] * cost_HF + b_rat[[s]] * rating_HF + b_trf[[s]] * trf_HF + b_wat[[s]] * wat_HF + b_ser_P[[s]] * (service_HF==1) + b_ser_A[[s]] * (service_HF==2) + b_ser_G[[s]] * (service_HF==3) + b_envi_P[[s]] * (envi_HF==1) + b_envi_A[[s]] * (envi_HF==2) + b_envi_G[[s]] * (envi_HF==3)
    nl_settings$V = V
    nl_settings$nlNests = nlNests[[s]]
    nl_settings$nlStructure = nlStructure[[s]]
    P[[s]] = apollo_nl(nl_settings, functionality)
    P[[s]] = apollo_panelProd(P[[s]],apollo_inputs,functionality)
    
    s=s+1
  }
  lc_settings = list(inClassProb = P, classProb=pi_values)
  P[["model"]] = apollo_lc(lc_settings,apollo_inputs,functionality)
  
  P = apollo_prepareProb(P,apollo_inputs,functionality)
}

model = apollo_estimate(apollo_beta, apollo_fixed, apollo_probabilities,apollo_inputs)
apollo_modelOutput(model,modelOutput_settings = list(printPVal=TRUE))]

[code][### Clear memory
rm(list = ls())

### Load Apollo library
library(apollo)

### Initialise code
apollo_initialise()

apollo_control = list(
  modelName ="Apollo_example_20_LC-NL",
  modelDescr ="LC model with class allocation model",
  indivID ="ID",
  nCores = 4
)
database = read.csv
database = subset(database,database$SP==1)
## scaled variables
apollo_beta = c(
                asc_DF_c1 = 0.6,
                asc_HF_c1 = 0.2,
                b_cost_c1 = 0,
                b_rat_c1 = 0,
                b_trf_c1 = 0,
                b_wat_c1 = 0,
                b_ser_P_c1 = 0,
                b_ser_A_c1 = 0,
                b_ser_G_c1 = 0,
                b_envi_P_c1 = 0,
                b_envi_A_c1 = 0,
                b_envi_G_c1 = 0,
                lambda_A_c1 = 1,
                lambda_B_c1 = 0.5,
                delta_c1 = 0,
                gamma_male_c1 = 0,
                asc_DF_c2 = 0.3,
                asc_HF_c2 = 0.2,
                b_cost_c2 = 0,
                b_rat_c2 = 0,
                b_trf_c2 = 0,
                b_wat_c2 = 0,
                b_ser_P_c2 = 0,
                b_ser_A_c2 = 0,
                b_ser_G_c2 = 0,
                b_envi_P_c2 = 0,
                b_envi_A_c2 = 0,
                b_envi_G_c2 = 0,
                lambda_A_c2 = 1,
                lambda_B_c2 = 0.5,
                delta_c2 = 0,
                gamma_male_c2 = 0,
                asc_DF_c3 = 0,
                asc_HF_c3 = 0,
                b_cost_c3 = 0,
                b_rat_c3 = 0,
                b_trf_c3 = 0,
                b_wat_c3 = 0,
                b_ser_P_c3 = 0,
                b_ser_A_c3 = 0,
                b_ser_G_c3 = 0,
                b_envi_P_c3 = 0,
                b_envi_A_c3 = 0,
                b_envi_G_c3 = 0,
                lambda_A_c3 = 1,
                lambda_B_c3 = 0.5,
                delta_c3 = 0,
                gamma_male_c3 = 0
)
apollo_fixed = c("delta_c3","lambda_A_c1","lambda_A_c2","lambda_A_c3","gamma_male_c3")

## Define latent class components
apollo_lcPars = function(apollo_beta, apollo_inputs){
  lcpars = list()
  lcpars[["b_cost"]] = list(b_cost_c1,b_cost_c2,b_cost_c3)
  lcpars[["b_rat"]] = list(b_rat_c1,b_rat_c2,b_rat_c3)
  lcpars[["b_trf"]] = list(b_trf_c1,b_trf_c2,b_trf_c3)
  lcpars[["b_wat"]] = list(b_wat_c1,b_wat_c2,b_wat_c3)
  lcpars[["b_ser_P"]] = list(b_ser_P_c1,b_ser_P_c2,b_ser_P_c3)
  lcpars[["b_ser_A"]] = list(b_ser_A_c1,b_ser_A_c2,b_ser_A_c3)
  lcpars[["b_ser_G"]] = list(b_ser_G_c1,b_ser_G_c2,b_ser_G_c3)
  lcpars[["b_envi_P"]] = list(b_envi_P_c1,b_envi_P_c2,b_envi_P_c3)
  lcpars[["b_envi_A"]] = list(b_envi_A_c1,b_envi_A_c2,b_envi_A_c3)
  lcpars[["b_envi_G"]] = list(b_envi_G_c1,b_envi_G_c2,b_envi_G_c3)
  lcpars[["asc_DF"]] = list(asc_DF_c1,asc_DF_c2,asc_DF_c3)
  lcpars[["asc_HF"]] = list(asc_HF_c1,asc_HF_c2,asc_HF_c3)

  #Utilities of class allocation model
  V = list()
  V[["class_1"]] = delta_c1 + gamma_male_c1*male
  V[["class_2"]] = delta_c2 + gamma_male_c2*male
  V[["class_3"]] = delta_c3 + gamma_male_c3*male


classAlloc_settings = list(
  classes      = c(class_1=1, class_2=2, class_3=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()
  ### Specify nests for NL model
  nlNests = list()
  nlNests[[1]] = list(root=1, A_c1=lambda_A_c1, B_c1 = lambda_B_c1)
  nlNests[[2]] = list(root=1, A_c2=lambda_A_c2, B_c2 = lambda_B_c2)
  nlNests[[3]] = list(root=1, A_c3=lambda_A_c3, B_c3 = lambda_B_c3)
  nlStructure = list()
  nlStructure[[1]] = list()
  nlStructure[[2]] = list()
  nlStructure[[3]] = list()
  nlStructure[[1]][["root"]] = c("A_c1","B_c1")
  nlStructure[[2]][["root"]] = c("A_c2","B_c2")
  nlStructure[[3]][["root"]] = c("A_c3","B_c3")
  
  nlStructure[[1]][["A_c1"]] = c("HF")
  nlStructure[[1]][["B_c1"]] = c("DF","FF")
  nlStructure[[2]][["A_c2"]] = c("HF")
  nlStructure[[2]][["B_c2"]] = c("DF","FF")
  nlStructure[[3]][["A_c3"]] = c("HF")
  nlStructure[[3]][["B_c3"]] = c("DF","FF")
  
  nl_settings <- list(
    alternatives = c(FF=1, DF=2, HF=3),
    avail = list(FF=av_FF, DF=av_DF, HF=av_HF),
    choiceVar = choice,
    nlNests = nlNests,
    nlStructure = nlStructure
  )
  ### Loop over classes
  s=1
  while(s<=3){
    ### Compute class-specific utilities
    V=list()
    V[['FF']] = b_cost[[s]] * cost_FF + b_rat[[s]] * rating_FF + b_trf[[s]] * trf_FF + b_wat[[s]] * wat_FF + b_ser_P[[s]] * (service_FF==1) + b_ser_A[[s]] * (service_FF==2) + b_ser_G[[s]] * (service_FF==3) + b_envi_P[[s]] * (envi_FF==1) + b_envi_A[[s]] * (envi_FF==2) + b_envi_G[[s]] * (envi_FF==3)
    V[['DF']] = asc_DF[[s]] + b_cost[[s]] * cost_DF + b_rat[[s]] * rating_DF + b_trf[[s]] * trf_DF + b_wat[[s]] * wat_DF + b_ser_P[[s]] * (service_DF==1) + b_ser_A[[s]] * (service_DF==2) + b_ser_G[[s]] * (service_DF==3) + b_envi_P[[s]] * (envi_DF==1) + b_envi_A[[s]] * (envi_DF==2) + b_envi_G[[s]] * (envi_DF==3)
    V[['HF']] = asc_HF[[s]] + b_cost[[s]] * cost_HF + b_rat[[s]] * rating_HF + b_trf[[s]] * trf_HF + b_wat[[s]] * wat_HF + b_ser_P[[s]] * (service_HF==1) + b_ser_A[[s]] * (service_HF==2) + b_ser_G[[s]] * (service_HF==3) + b_envi_P[[s]] * (envi_HF==1) + b_envi_A[[s]] * (envi_HF==2) + b_envi_G[[s]] * (envi_HF==3)
    nl_settings$V = V
    nl_settings$nlNests = nlNests[[s]]
    nl_settings$nlStructure = nlStructure[[s]]
    P[[s]] = apollo_nl(nl_settings, functionality)
    P[[s]] = apollo_panelProd(P[[s]],apollo_inputs,functionality)
    
    s=s+1
  }
  lc_settings = list(inClassProb = P, classProb=pi_values)
  P[["model"]] = apollo_lc(lc_settings,apollo_inputs,functionality)
  
  P = apollo_prepareProb(P,apollo_inputs,functionality)
}

model = apollo_estimate(apollo_beta, apollo_fixed, apollo_probabilities,apollo_inputs)
apollo_modelOutput(model,modelOutput_settings = list(printPVal=TRUE))]


Here are the results:
Estimates:
                 Estimate        s.e.   t.rat.(0)  p(1-sided)    Rob.s.e. Rob.t.rat.(0)  p(1-sided)
asc_DF_c1        1.710023    0.489840      3.4910  2.4063e-04    0.864450      1.978163    0.023955
asc_HF_c1        0.493633    0.525809      0.9388    0.173915    0.954244      0.517303    0.302472
b_cost_c1       -0.003616    0.001289     -2.8056    0.002511    0.002178     -1.659864    0.048471
b_rat_c1         0.349926    0.069816      5.0121   2.691e-07    0.078963      4.431536   4.678e-06
b_trf_c1        -0.013241    0.005173     -2.5599    0.005235    0.006316     -2.096606    0.018014
b_wat_c1       2.5326e-04    0.002349      0.1078    0.457065    0.002556      0.099083    0.460536
b_ser_P_c1      -0.505495         NaN         NaN         NaN  201.318644     -0.002511    0.498998
b_ser_A_c1       0.077520         NaN         NaN         NaN  201.327375    3.8505e-04    0.499846
b_ser_G_c1       0.428057         NaN         NaN         NaN  201.324333      0.002126    0.499152
b_envi_P_c1     -0.463142         NaN         NaN         NaN  349.031535     -0.001327    0.499471
b_envi_A_c1      0.098144         NaN         NaN         NaN  349.048410    2.8118e-04    0.499888
b_envi_G_c1      0.364986         NaN         NaN         NaN  349.047981      0.001046    0.499583
lambda_A_c1      1.000000          NA          NA          NA          NA            NA          NA
lambda_B_c1      0.993324    0.233039      4.2625   1.011e-05    0.405029      2.452478    0.007094
delta_c1         0.480116    0.132377      3.6269  1.4343e-04    0.213453      2.249282    0.012247
gamma_male_c1    0.013893    0.129081      0.1076    0.457144    0.131087      0.105984    0.457797
asc_DF_c2        0.871215         NaN         NaN         NaN    0.066689     13.063835    0.000000
asc_HF_c2        3.266650    0.247016     13.2244    0.000000    0.495385      6.594160   2.138e-11
b_cost_c2       -0.002672    0.003892     -0.6865    0.246198    0.004126     -0.647652    0.258605
b_rat_c2         0.685840    0.044301     15.4814    0.000000    0.037486     18.295842    0.000000
b_trf_c2        -0.039416    0.012486     -3.1567  7.9772e-04    0.024307     -1.621609    0.052444
b_wat_c2        -0.024293    0.001721    -14.1172    0.000000    0.003929     -6.183880   3.127e-10
b_ser_P_c2       0.181757         NaN         NaN         NaN    0.192844      0.942511    0.172966
b_ser_A_c2      -0.592098    0.060240     -9.8289    0.000000    0.042651    -13.882493    0.000000
b_ser_G_c2       0.410372         NaN         NaN         NaN    0.341213      1.202684    0.114549
b_envi_P_c2      0.658738    0.287279      2.2930    0.010923    0.454321      1.449941    0.073537
b_envi_A_c2     -0.098275         NaN         NaN         NaN    0.159265     -0.617054    0.268600
b_envi_G_c2     -0.560458    0.062303     -8.9957    0.000000    0.032823    -17.075240    0.000000
lambda_A_c2      1.000000          NA          NA          NA          NA            NA          NA
lambda_B_c2      0.011233    0.074413      0.1510    0.440006    0.060352      0.186124    0.426174
delta_c2        -2.103835    0.217278     -9.6827    0.000000    0.264715     -7.947543   9.992e-16
gamma_male_c2    0.609546    0.248769      2.4502    0.007138    0.260063      2.343834    0.009543
asc_DF_c3        1.022109    0.124333      8.2207   1.110e-16    0.137877      7.413170   6.162e-14
asc_HF_c3        0.291593    0.212175      1.3743    0.084673    0.208485      1.398633    0.080961
b_cost_c3       -0.012277    0.001364     -9.0035    0.000000    0.001417     -8.666229    0.000000
b_rat_c3        -0.179689    0.102541     -1.7524    0.039856    0.125441     -1.432456    0.076007
b_trf_c3         0.027069    0.005231      5.1745   1.143e-07    0.006688      4.047479   2.589e-05
b_wat_c3         0.003137    0.003445      0.9107    0.181240    0.003646      0.860412    0.194781
b_ser_P_c3       0.644819         NaN         NaN         NaN 2186.712165    2.9488e-04    0.499882
b_ser_A_c3      -0.292178         NaN         NaN         NaN 2186.703442   -1.3362e-04    0.499947
b_ser_G_c3      -0.352634         NaN         NaN         NaN 2186.701975   -1.6126e-04    0.499936
b_envi_P_c3     -0.269307         NaN         NaN         NaN  155.783219     -0.001729    0.499310
b_envi_A_c3      0.255086         NaN         NaN         NaN  155.790631      0.001637    0.499347
b_envi_G_c3      0.014237         NaN         NaN         NaN  155.792497     9.139e-05    0.499964
lambda_A_c3      1.000000          NA          NA          NA          NA            NA          NA
lambda_B_c3      0.456305    0.111485      4.0930   2.130e-05    0.150940      3.023090    0.001251
delta_c3         0.000000          NA          NA          NA          NA            NA          NA
gamma_male_c3    0.000000          NA          NA          NA          NA            NA          NA

Nesting structure for NL model component 1:
Nest: root (1)
|-Nest: A_c1 (1)
|  '-Alternative: HF
'-Nest: B_c1 (0.9933)
   |-Alternative: DF
   '-Alternative: FF

Nesting structure for NL model component 2:
Nest: root (1)
|-Nest: A_c2 (1)
|  '-Alternative: HF
'-Nest: B_c2 (0.0112)
   |-Alternative: DF
   '-Alternative: FF

Nesting structure for NL model component 3:
Nest: root (1)
|-Nest: A_c3 (1)
|  '-Alternative: HF
'-Nest: B_c3 (0.4563)
   |-Alternative: DF
   '-Alternative: FF


Summary of class allocation for LC model component :
         Mean prob.
Class_1     0.72163
Class_2     0.09766
Class_3     0.18070


Overview of choices for NL model component 1:
                                      FF      DF     HF
Times available                  9456.00 9456.00 9456.0
Times chosen                     1943.00 5111.00 2402.0
Percentage chosen overall          20.55   54.05   25.4
Percentage chosen when available   20.55   54.05   25.4


Overview of choices for NL model component 2:
                                      FF      DF     HF
Times available                  9456.00 9456.00 9456.0
Times chosen                     1943.00 5111.00 2402.0
Percentage chosen overall          20.55   54.05   25.4
Percentage chosen when available   20.55   54.05   25.4


Overview of choices for NL model component 3:
                                      FF      DF     HF
Times available                  9456.00 9456.00 9456.0
Times chosen                     1943.00 5111.00 2402.0
Percentage chosen overall          20.55   54.05   25.4
Percentage chosen when available   20.55   54.05   25.4

Re: Error in Latent Class Nested Logit Model- NAN

Posted: 30 Aug 2022, 10:37
by stephanehess
Hi

this could simply be an empirical identification issue.

as a first step, could you confirm that you managed to run a simple NL model, i.e. not as latent class? Then move to a model with 2 classes and see what happens there.

Stephane