I recently ran this SCE to collect information on individuals’ willingness to purchase MaaS bundles. Basically, each bundle includes free minutes of biclycle, electric scooter, taxi… at a price. And there are three bundles that offer more and more free minutes at a higher price. Prices are calculated on the total cost of each of those free services +/- a random %.
The point is that I’m obtaining in the model estimation signs for the coefficients completely contrary to what is expected. All LOS, which have a positive meaning (more free minutes), have a negative sign, while the price has a positive one, increasing the probability of choosing the alternative. Simply makes no sense.
I went over the data, and everything looks OK. LOS are much higher for the superior alternatives (basic, premium and superior) and choices look reasonable too (no dominant variable or alternative). I mean, I don’t think that the results show an actual preference for more expensive or less utility alternatives; I don’t see that in the data.
I wonder if I’m missing something in my model specification and it is wrong... (copied below). I can also add a snapshot of the data, if needed.
Thanks for your help.
J.
Code: Select all
# ################################################################# #
#### LOAD LIBRARY AND DEFINE CORE SETTINGS ####
# ################################################################# #
### Clear memory
rm(list = ls())
### Load Apollo library
library(apollo)
library(readxl)
#library(dplyr)
### Initialise code
apollo_initialise()
### Set core controls
apollo_control = list(
modelName = "MNL_v0",
modelDescr = "MNL generic LOS attributes",
indivID = "ID",
outputDirectory = "output"
)
# ################################################################# #
#### LOAD DATA AND APPLY ANY TRANSFORMATIONS ####
# ################################################################# #
### Loading data and some treatment
raw_data <- read_excel("dfhghgfhfg/208001 UCM - MAAS ESCENARIOS PILOTO.xlsx")
database <- raw_data
cols_to_convert <- c("taxi_B", "taxi_P", "taxi_S", "zitty_B", "zitty_P", "zitty_S", "moto_B", "moto_P", "moto_S", "patinete_B", "patinete_P", "patinete_S", "bici_B", "bici_P", "bici_S")
database[cols_to_convert] <- lapply(database[cols_to_convert], as.numeric)
numeric_columns <- sapply(database, is.numeric)
database[numeric_columns] <- scale(database[numeric_columns])
colnames(database)[colnames(database) == "ESCENARI"] <- "CHOICE"
database$av_basic <- 1
database$av_premium <- 1
database$av_superior <- 1
database$av_none <- 1
database$CHOICE <- as.numeric(factor(database$CHOICE, levels = c("BÁSICO", "PREMIUM", "SUPERIOR", "NINGUNO")))
hot_encoded <- model.matrix(~ NOTP - 1, database)
colnames(hot_encoded) <- c("D_estandar", "D_discap", "D_sin_carnet")
database <- cbind(database, hot_encoded)
### for data dictionary, use ?apollo_modeChoiceData
### Use only SP data EVERYTHING IS SP. USE THIS LATER FOR SUBGROUPS.
#database = subset(database,database$SP==1)
# ################################################################# #
#### DEFINE MODEL PARAMETERS ####
# ################################################################# #
### Vector of parameters, including any that are kept fixed in estimation
apollo_beta=c(asc_basic = 0,
asc_prem = 0,
asc_sup = 0,
asc_none = 0, # Quitar si se eliminan esas obs.
# b_taxi_basic = 0,
# b_zitty_basic = 0,
# b_moto_basic = 0,
# b_patinete_basic = 0,
# b_bici_basic = 0,
# b_precio_basic = 0,
# b_taxi_prem = 0,
# b_zitty_prem = 0,
# b_moto_prem = 0,
# b_patinete_prem = 0,
# b_bici_prem = 0,
# b_precio_prem = 0,
# b_taxi_sup = 0,
# b_zitty_sup = 0,
# b_moto_sup = 0,
# b_patinete_sup = 0,
# b_bici_sup = 0,
# b_precio_sup = 0,
###
b_taxi = 0,
b_zitty = 0,
b_moto = 0,
b_patinete = 0,
b_bici = 0,
b_precio = 0
###
#b_estandar = 0,
#b_discap = 0,
#b_sin_carnet = 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("asc_none")
# ################################################################# #
#### 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()
### List of utilities: these must use the same names as in mnl_settings, order is irrelevant
V = list()
V[["basic"]] = asc_basic + b_precio * preu_B +
b_taxi * taxi_B +
b_zitty * zitty_B +
b_moto * moto_B +
b_patinete * patinete_B +
b_bici * bici_B
V[["premium"]] = asc_prem + b_precio * preu_P +
b_taxi * taxi_P +
b_zitty * zitty_P +
b_moto * moto_P +
b_patinete * patinete_P +
b_bici * bici_P
V[["superior"]] = asc_sup + b_precio * preu_S +
b_taxi * taxi_S +
b_zitty * zitty_S +
b_moto * moto_S +
b_patinete * patinete_S +
b_bici * bici_S
V[["none"]] = asc_none
### Define settings for MNL model component
mnl_settings = list(
alternatives = c(basic=1, premium=2, superior=3, none=4),
avail = list(basic=av_basic, premium=av_premium, superior=av_superior, none=av_none),
choiceVar = CHOICE,
utilities = V
)
### Compute probabilities using MNL model
P[["model"]] = apollo_mnl(mnl_settings, functionality)
### Take product across observation for same individual
P = apollo_panelProd(P, 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)
# ################################################################# #
#### MODEL OUTPUTS ####
# ################################################################# #
# ----------------------------------------------------------------- #
#---- FORMATTED OUTPUT (TO SCREEN) ----
# ----------------------------------------------------------------- #
apollo_modelOutput(model)
# ----------------------------------------------------------------- #
#---- FORMATTED OUTPUT (TO FILE, using model name) ----
# ----------------------------------------------------------------- #
apollo_saveOutput(model)
Code: Select all
Model name : MNL_v0
Model description : MNL generic LOS attributes
Model run at : 2024-09-23 16:57:44.334078
Estimation method : bgw
Model diagnosis : Relative function convergence
Optimisation diagnosis : Maximum found
hessian properties : Negative definite
maximum eigenvalue : -36.500448
reciprocal of condition number : 0.0778752
Number of individuals : 106
Number of rows in database : 636
Number of modelled outcomes : 636
Number of cores used : 1
Model without mixing
LL(start) : -881.68
LL at equal shares, LL(0) : -881.68
LL at observed shares, LL(C) : -828.18
LL(final) : -807.54
Rho-squared vs equal shares : 0.0841
Adj.Rho-squared vs equal shares : 0.0739
Rho-squared vs observed shares : 0.0249
Adj.Rho-squared vs observed shares : 0.0177
AIC : 1633.09
BIC : 1673.18
Estimated parameters : 9
Time taken (hh:mm:ss) : 00:00:1.15
pre-estimation : 00:00:0.55
estimation : 00:00:0.17
initial estimation : 00:00:0.13
estimation after rescaling : 00:00:0.04
post-estimation : 00:00:0.44
Iterations : 7
initial estimation : 6
estimation after rescaling : 1
Unconstrained optimisation.
Estimates:
Estimate s.e. t.rat.(0) Rob.s.e. Rob.t.rat.(0)
asc_basic 0.51468 0.10090 5.1007 0.19524 2.6361
asc_prem -0.34331 0.12314 -2.7881 0.22050 -1.5570
asc_sup -0.56800 0.13215 -4.2982 0.24912 -2.2800
asc_none 0.00000 NA NA NA NA
b_taxi -0.07812 0.05610 -1.3926 0.05448 -1.4340
b_zitty -0.02652 0.07311 -0.3628 0.10313 -0.2572
b_moto -0.23779 0.06961 -3.4160 0.07833 -3.0357
b_patinete -0.20992 0.06711 -3.1282 0.08019 -2.6178
b_bici -0.17640 0.06331 -2.7860 0.06830 -2.5826
b_precio 0.07606 0.08718 0.8725 0.17609 0.4319