Mixed Logit - elasticities
Posted: 17 Jul 2024, 20:18
Hello Prof. Hess and Prof. Palma,
I have a question regarding elasticities for the mixed logit model. Is it possible to use the part of the code below from MNL_SP_covariates.r to find elasticities for the mixed logit model? The formulas of relative probabilities are quite different in MNL and mixed logit as mixed logit does not follow the IIA assumption, so I was wondering we need to somehow account for that when calculating elasticities.
Thank you for all your work!
Best,
Katya
# ----------------------------------------------------------------- #
#---- MODEL PREDICTIONS AND ELASTICITY CALCULATIONS ----
# ----------------------------------------------------------------- #
### Use the estimated model to make predictions
predictions_base = apollo_prediction(model, apollo_probabilities, apollo_inputs, prediction_settings=list(runs=30))
### Now imagine the cost for rail increases by 1%
database$cost_rail = 1.01*database$cost_rail
### Rerun predictions with the new data
apollo_inputs = apollo_validateInputs()
predictions_new = apollo_prediction(model, apollo_probabilities, apollo_inputs)
### Return to original data
database$cost_rail = 1/1.01*database$cost_rail
apollo_inputs = apollo_validateInputs()
### work with predictions at estimates
predictions_base=predictions_base[["at_estimates"]]
### Compute change in probabilities
change=(predictions_new-predictions_base)/predictions_base
### Not interested in chosen alternative now, so drop last column
change=change[,-ncol(change)]
### First two columns (change in ID and task) also not needed
change=change[,-c(1,2)]
### Look at first individual
change[database$ID==1,]
### And person 9, who has all 4 modes available
change[database$ID==9,]
### Summary of changes (possible presence of NAs for unavailable alternatives)
summary(change)
### Look at mean changes for subsets of the data, ignoring NAs
colMeans(change,na.rm=TRUE)
colMeans(subset(change,database$business==1),na.rm=TRUE)
colMeans(subset(change,database$business==0),na.rm=TRUE)
colMeans(subset(change,(database$income<quantile(database$income,0.25))),na.rm=TRUE)
colMeans(subset(change,(database$income>=quantile(database$income,0.25))|(database$income<=quantile(database$income,0.75))),na.rm=TRUE)
colMeans(subset(change,(database$income>quantile(database$income,0.75))),na.rm=TRUE)
### Compute own elasticity for rail:
log(sum(predictions_new[,6])/sum(predictions_base[,6]))/log(1.01)
### Compute cross-elasticities for other modes
log(sum(predictions_new[,3])/sum(predictions_base[,3]))/log(1.01)
log(sum(predictions_new[,4])/sum(predictions_base[,4]))/log(1.01)
log(sum(predictions_new[,5])/sum(predictions_base[,5]))/log(1.01)
I have a question regarding elasticities for the mixed logit model. Is it possible to use the part of the code below from MNL_SP_covariates.r to find elasticities for the mixed logit model? The formulas of relative probabilities are quite different in MNL and mixed logit as mixed logit does not follow the IIA assumption, so I was wondering we need to somehow account for that when calculating elasticities.
Thank you for all your work!
Best,
Katya
# ----------------------------------------------------------------- #
#---- MODEL PREDICTIONS AND ELASTICITY CALCULATIONS ----
# ----------------------------------------------------------------- #
### Use the estimated model to make predictions
predictions_base = apollo_prediction(model, apollo_probabilities, apollo_inputs, prediction_settings=list(runs=30))
### Now imagine the cost for rail increases by 1%
database$cost_rail = 1.01*database$cost_rail
### Rerun predictions with the new data
apollo_inputs = apollo_validateInputs()
predictions_new = apollo_prediction(model, apollo_probabilities, apollo_inputs)
### Return to original data
database$cost_rail = 1/1.01*database$cost_rail
apollo_inputs = apollo_validateInputs()
### work with predictions at estimates
predictions_base=predictions_base[["at_estimates"]]
### Compute change in probabilities
change=(predictions_new-predictions_base)/predictions_base
### Not interested in chosen alternative now, so drop last column
change=change[,-ncol(change)]
### First two columns (change in ID and task) also not needed
change=change[,-c(1,2)]
### Look at first individual
change[database$ID==1,]
### And person 9, who has all 4 modes available
change[database$ID==9,]
### Summary of changes (possible presence of NAs for unavailable alternatives)
summary(change)
### Look at mean changes for subsets of the data, ignoring NAs
colMeans(change,na.rm=TRUE)
colMeans(subset(change,database$business==1),na.rm=TRUE)
colMeans(subset(change,database$business==0),na.rm=TRUE)
colMeans(subset(change,(database$income<quantile(database$income,0.25))),na.rm=TRUE)
colMeans(subset(change,(database$income>=quantile(database$income,0.25))|(database$income<=quantile(database$income,0.75))),na.rm=TRUE)
colMeans(subset(change,(database$income>quantile(database$income,0.75))),na.rm=TRUE)
### Compute own elasticity for rail:
log(sum(predictions_new[,6])/sum(predictions_base[,6]))/log(1.01)
### Compute cross-elasticities for other modes
log(sum(predictions_new[,3])/sum(predictions_base[,3]))/log(1.01)
log(sum(predictions_new[,4])/sum(predictions_base[,4]))/log(1.01)
log(sum(predictions_new[,5])/sum(predictions_base[,5]))/log(1.01)