def probas(self, betas=None): # The choice model is a logit, with availability conditions prob1 = models.logit(self.V, self.av, 1) prob2 = models.logit(self.V, self.av, 2) prob3 = models.logit(self.V, self.av, 3) simulate = {'Train': prob1, 'SM': prob2, 'Car': prob3} biogeme = bio.BIOGEME(self.database, simulate) biogeme.modelName = "01logit_simul" self.biogeme.generateHtml = False return biogeme.simulate(betas)
def logit(THE_B_TIME_RND): """ Calculate the conditional logit model for a given random parameter. """ V1 = ASC_TRAIN + \ THE_B_TIME_RND * TRAIN_TT_SCALED + \ B_COST * TRAIN_COST_SCALED V2 = ASC_SM + \ THE_B_TIME_RND * SM_TT_SCALED + \ B_COST * SM_COST_SCALED V3 = ASC_CAR + \ THE_B_TIME_RND * CAR_TT_SCALED + \ B_COST * CAR_CO_SCALED # Associate utility functions with the numbering of alternatives V = {1: V1, 2: V2, 3: V3} # Associate the availability conditions with the alternatives av = {1: TRAIN_AV_SP, 2: SM_AV, 3: CAR_AV_SP} # The choice model is a logit, with availability conditions integrand = models.logit(V, av, CHOICE) return integrand
def run_simulation(data_file_directory_for_simulation, data_file_name_for_simulation, output_directory_for_simulation, betas, household_income_limit): """ :author: Antonin Danalet, based on the example '01logit_simul.py' by Michel Bierlaire, EPFL, on biogeme.epfl.ch Simulation with a binary logit model. Two alternatives: work from home at least some times, or not.""" # Read the data df_persons = pd.read_csv(data_file_directory_for_simulation / data_file_name_for_simulation, ';') database = db.Database('persons', df_persons) # The following statement allows you to use the names of the variable as Python variable. globals().update(database.variables) # Parameters to be estimated alternative_specific_constant = Beta('alternative_specific_constant', 0, None, None, 0) b_no_post_school_education = Beta('b_no_post_school_education', 0, None, None, 0) b_secondary_education = Beta('b_secondary_education', 0, None, None, 0) b_tertiary_education = Beta('b_tertiary_education', 0, None, None, 0) b_university = Beta('b_university', 0, None, None, 1) b_male = Beta('b_male', 0, None, None, 0) b_public_transport_connection_quality_na_home = Beta('b_public_transport_connection_quality_na_home', 0, None, None, 0) b_public_transport_connection_quality_a_work = Beta('b_public_transport_connection_quality_are_a_work', 0, None, None, 1) b_rural_work = Beta('b_rural_work', 0, None, None, 0) b_home_work_distance = Beta('b_home_work_distance', 0, None, None, 0) b_business_sector_agriculture = Beta('b_business_sector_agriculture', 0, None, None, 0) b_business_sector_production = Beta('b_business_sector_production', 0, None, None, 0) b_business_sector_wholesale = Beta('b_business_sector_wholesale', 0, None, None, 1) b_business_sector_retail = Beta('b_business_sector_retail', 0, None, None, 0) b_business_sector_gastronomy = Beta('b_business_sector_gastronomy', 0, None, None, 0) b_business_sector_finance = Beta('b_business_sector_finance', 0, None, None, 1) b_business_sector_services_fc = Beta('b_business_sector_services_fc', 0, None, None, 0) b_business_sector_other_services = Beta('b_business_sector_other_services', 0, None, None, 1) b_business_sector_others = Beta('b_business_sector_others', 0, None, None, 1) b_business_sector_non_movers = Beta('b_business_sector_non_movers', 0, None, None, 0) b_executives = Beta('b_executives', 0, None, None, 0) b_german = Beta('b_german', 0, None, None, 0) b_hh_income_8000_or_less = Beta('b_hh_income_8000_or_less', 0, None, None, 0) # Definition of new variables no_post_school_educ = education == 1 secondary_education = education == 2 tertiary_education = education == 3 university = education == 4 male = (sex == 1) public_transport_quality_NA_home = (public_transport_connection_quality_ARE_home == 5) public_transport_quality_A_work = (public_transport_connection_quality_ARE_work == 1) home_work_distance = (home_work_crow_fly_distance * (home_work_crow_fly_distance >= 0.0) / 100000.0) business_sector_agriculture = type_1 == 1 business_sector_retail = type_1 == 4 business_sector_gastronomy = type_1 == 5 business_sector_finance = type_1 == 6 business_sector_production = type_1 == 2 business_sector_wholesale = type_1 == 3 business_sector_services_fC = type_1 == 7 business_sector_other_services = type_1 == 8 business_sector_others = type_1 == 9 business_sector_non_movers = type_1 == 10 german = language == 1 nationality_switzerland = nation == 0 nationality_germany_austria = nation == 1 nationality_italy_vatican = nation == 2 nationality_france_monaco_s_marino = nation == 3 nationality_northwestern_europe = nation == 4 nationality_eastern_europe = nation == 7 hh_income_8000_or_less = hh_income < household_income_limit executives = (0 < position_in_bus) * (position_in_bus < 19) rural_work = urban_rural_typology_work == 3 # Utility utility_function_telecommuting = alternative_specific_constant + \ b_executives * executives + \ b_no_post_school_education * no_post_school_educ + \ b_secondary_education * secondary_education + \ b_tertiary_education * tertiary_education + \ b_university * university + \ b_male * male + \ b_public_transport_connection_quality_na_home * public_transport_quality_NA_home + \ b_public_transport_connection_quality_a_work * public_transport_quality_A_work + \ b_rural_work * rural_work + \ b_home_work_distance * home_work_distance + \ models.piecewiseFormula(age, [0, 20, 35, 75, 200]) + \ b_business_sector_agriculture * business_sector_agriculture + \ b_business_sector_retail * business_sector_retail + \ b_business_sector_gastronomy * business_sector_gastronomy + \ b_business_sector_finance * business_sector_finance + \ b_business_sector_production * business_sector_production + \ b_business_sector_wholesale * business_sector_wholesale + \ b_business_sector_services_fc * business_sector_services_fC + \ b_business_sector_other_services * business_sector_other_services + \ b_business_sector_others * business_sector_others + \ b_business_sector_non_movers * business_sector_non_movers + \ b_german * german + \ b_nationality_ch_germany_france_italy_nw_e * nationality_switzerland + \ b_nationality_ch_germany_france_italy_nw_e * nationality_germany_austria + \ b_nationality_ch_germany_france_italy_nw_e * nationality_italy_vatican + \ b_nationality_ch_germany_france_italy_nw_e * nationality_france_monaco_s_marino + \ b_nationality_ch_germany_france_italy_nw_e * nationality_northwestern_europe + \ b_nationality_ch_germany_france_italy_nw_e * nationality_eastern_europe + \ models.piecewiseFormula(work_percentage, [0, 90, 101]) + \ b_hh_income_8000_or_less * hh_income_8000_or_less utility_function_no_telecommuting = 0 # Associate utility functions with the numbering of alternatives utility_functions_with_numbering_of_alternatives = {1: utility_function_telecommuting, # Yes or sometimes 3: utility_function_no_telecommuting} # No availability_conditions = {1: 1, # Always available 3: 1} # Always available # The choice model is a logit, with availability conditions prob_telecommuting = models.logit(utility_functions_with_numbering_of_alternatives, availability_conditions, 1) prob_no_telecommuting = models.logit(utility_functions_with_numbering_of_alternatives, availability_conditions, 3) simulate = {'Prob. telecommuting': prob_telecommuting, 'Prob. no telecommuting': prob_no_telecommuting} # Create the Biogeme object biogeme = bio.BIOGEME(database, simulate) biogeme.modelName = 'logit_telecommuting_simul' # Define level of verbosity logger = msg.bioMessage() # logger.setSilent() logger.setWarning() # logger.setGeneral() # logger.setDetailed() # Get the betas from the estimation (without corrections) # path_to_estimation_folder = Path('../data/output/models/estimation/') # if os.path.isfile(path_to_estimation_folder / 'logit_telecommuting~00.pickle'): # raise Exception('There are several model outputs! Careful.') # results = res.bioResults(pickleFile=path_to_estimation_folder / 'logit_telecommuting.pickle') # betas_without_correction = results.getBetaValues() # Change the working directory, so that biogeme writes in the correct folder, i.e., where this file is standard_directory = os.getcwd() os.chdir(output_directory_for_simulation) results = biogeme.simulate(theBetaValues=betas) # print(results.describe()) df_persons = pd.concat([df_persons, results], axis=1) # Go back to the normal working directory os.chdir(standard_directory) # For unemployed people, fix probability of doing some home office to 0 (and probability of not doing to 1). df_persons.loc[df_persons.employed == 0, 'Prob. telecommuting'] = 0.0 # Unemployed people df_persons.loc[df_persons.employed == 0, 'Prob. no telecommuting'] = 1.0 # Unemployed people df_persons.loc[df_persons.employed == -99, 'Prob. telecommuting'] = 0.0 # Other people df_persons.loc[df_persons.employed == -99, 'Prob. no telecommuting'] = 1.0 # Other people # By definition, apprentices don't work from home (because they were not asked in the MTMC) df_persons.loc[df_persons.position_in_bus == 3, 'Prob. telecommuting'] = 0.0 df_persons.loc[df_persons.position_in_bus == 3, 'Prob. no telecommuting'] = 1.0 # Add a realisation of the probability df_persons['random 0/1'] = np.random.rand(len(df_persons)) df_persons['telecommuting_model'] = np.where(df_persons['random 0/1'] < df_persons['Prob. telecommuting'], 1, 0) del df_persons['random 0/1'] ''' Save the file ''' data_file_name = 'persons_from_SynPop_with_probability_telecommuting.csv' df_persons.to_csv(output_directory_for_simulation / data_file_name, sep=',', index=False)
ASC_SM_RND[i] + B_TIME_RND[i] * SM_TT_SCALED + B_COST[i] * SM_COST_SCALED for i in range(numberOfClasses) ] V3 = [ ASC_CAR_RND[i] + B_TIME_RND[i] * CAR_TT_SCALED + B_COST[i] * CAR_CO_SCALED for i in range(numberOfClasses) ] V = [{1: V1[i], 2: V2[i], 3: V3[i]} for i in range(numberOfClasses)] # Associate the availability conditions with the alternatives av = {1: TRAIN_AV_SP, 2: SM_AV, 3: CAR_AV_SP} # The choice model is a discrete mixture of logit, with availability conditions # We calculate the conditional probability for each class prob = [ PanelLikelihoodTrajectory(models.logit(V[i], av, CHOICE)) for i in range(numberOfClasses) ] # Conditional to the random variables, likelihood for the individual. probIndiv = PROB_class0 * prob[0] + PROB_class1 * prob[1] # We integrate over the random variables using Monte-Carlo logprob = log(MonteCarlo(probIndiv)) # Define level of verbosity logger = msg.bioMessage() #logger.setSilent() #logger.setWarning() logger.setGeneral() #logger.setDetailed()
V1 = [ASC_1[i] + beta_shcostperdist1[i] *(sharecost/distance) + beta_shtime[i] * sharetime + SIGMA_SH_MAASRND[i] for i in range(numberOfClasses)] V2 = [ASC_2[i] + beta_maascostperdist2[i] *(maascost/distance)+ beta_maastime1[i]*(maastime1) + beta_maastime2[i]* maastime2 +\ beta_extra[i]*(extra) *extra + SIGMA_SH_MAASRND[i] for i in range(numberOfClasses)] V3 = [ASC_3[i] + beta_totcostperdist[i] * (currcost/distance) for i in range(numberOfClasses)] V = [{1: V1[i], 2: V2[i], 3: V3[i]} for i in range(numberOfClasses)] # Associate the availability conditions with the alternatives av = {1: availability1,2: availability2,3: availability3} # The choice model is a discrete mixture of logit, with availability conditions # We calculate the conditional probability for each class prob = [PanelLikelihoodTrajectory(models.logit(V[i], av, choice)) for i in range(numberOfClasses)] # Class membership model W = CLASS_MAAS_1 + beta_enthu_class1 * factor1 + beta_fru_class1 * factor2 + beta_edu2_1 * edu_HBO + \ beta_inc2_1*inc_mid + beta_age * age_10_60 + beta_freq * mediumfreq PROB_class0 = models.logit({0: W, 1: 0}, None, 0) PROB_class1 = models.logit({0: W, 1: 0}, None, 1) # Conditional to the random variables, likelihood for the individual. probIndiv = PROB_class0 * prob[0] + PROB_class1 * prob[1] # We integrate over the random variables using Monte-Carlo logprob = log(MonteCarlo(probIndiv)) # Define level of verbosity logger = msg.bioMessage() #logger.setSilent()
def estimate_model(self, pandas_df_for_specified_country, country): ''' :param pandas_df_for_specified_country: :param country: :return: The estimated model, in a variable with 3 attributes: betas, structure, results. ''' mypanda = pandas_df_for_specified_country for i in range(1, 7): mypanda['OCC_' + str(i)] = np.where(pandas_df_for_specified_country['user_occupation'] == i, 1, 0) # create the respective database (needed for biogeme) estimationdb = db.Database('estimationdb', mypanda) print('Training Mode Choice model for', country) # Alternative Specific Constants ASC_CAR = Beta('ASC_CAR', 0, None, None, 1) # This ASC remains equal to zero ASC_PT = Beta('ASC_PT', 0, None, None, 0) ASC_MOT = Beta('ASC_MOT', 0, None, None, 0) ASC_BIKE = Beta('ASC_BIKE', 0, None, None, 0) # Beta variables (i.e. coefficients) - alternative specific BETA_TIME = Beta('BETA_TIME', 0, None, None, 0) # Travel Time BETA_COST = Beta('BETA_COST', 0, None, None, 0) # Travel Cost BETA_S = Beta('BETA_S', 0, None, None, 0) # Comfort # Beta variables (i.e. coefficients) - traveller BETA_AGE_PT = Beta('BETA_AGE_PT', 0, None, None, 0) # Age BETA_NCAR_PT = Beta('BETA_NCAR_PT', 0, None, None, 0) # Number of trips by car BETA_NPT_PT = Beta('BETA_NPT_PT', 0, None, None, 0) # Number of trips by pt BETA_GENDER_PT = Beta('BETA_GENDER_PT', 0, None, None, 0) # Gender BETA_SCOPE_PT = Beta('BETA_SCOPE_PT', 0, None, None, 0) # Trip Purpose BETA_OCC_1_PT = Beta('BETA_OCC_1_PT', 0, None, None, 0) # 1:Private employee BETA_OCC_2_PT = Beta('BETA_OCC_2_PT', 0, None, None, 0) # 2:Public servant BETA_OCC_3_PT = Beta('BETA_OCC_3_PT', 0, None, None, 0) # 3:Self-employed BETA_OCC_5_PT = Beta('BETA_OCC_5_PT', 0, None, None, 0) # 5:Retired BETA_OCC_6_PT = Beta('BETA_OCC_6_PT', 0, None, None, 0) # 6:Unemployed BETA_AGE_BIKE = Beta('BETA_AGE_BIKE', 0, None, None, 0) # Age BETA_NCAR_BIKE = Beta('BETA_NCAR_BIKE', 0, None, None, 0) # Number of trips by car BETA_NPT_BIKE = Beta('BETA_NPT_BIKE', 0, None, None, 0) # Number of trips by pt BETA_OCC_1_BIKE = Beta('BETA_OCC_1_BIKE', 0, None, None, 0) # 1:Private employee BETA_OCC_3_BIKE = Beta('BETA_OCC_3_BIKE', 0, None, None, 0) # 3:Self-employed BETA_OCC_4_BIKE = Beta('BETA_OCC_4_BIKE', 0, None, None, 0) # 4:Student BETA_OCC_5_BIKE = Beta('BETA_OCC_5_BIKE', 0, None, None, 0) # 5:Retired BETA_OCC_6_BIKE = Beta('BETA_OCC_6_BIKE', 0, None, None, 0) # 6:Unemployed BETA_AGE_MOT = Beta('BETA_AGE_MOT', 0, None, None, 0) # Age BETA_GENDER_MOT = Beta('BETA_GENDER_MOT', 0, None, None, 0) # Gender BETA_SCOPE_MOT = Beta('BETA_SCOPE_MOT', 0, None, None, 0) # Scope BETA_NCAR_MOT = Beta('BETA_NCAR_MOT', 0, None, None, 0) # Number of trips by car BETA_NPT_MOT = Beta('BETA_NPT_MOT', 0, None, None, 0) # Number of trips by pt BETA_OCC_2_MOT = Beta('BETA_OCC_2_MOT', 0, None, None, 0) # Occupation 3 BETA_OCC_3_MOT = Beta('BETA_OCC_3_MOT', 0, None, None, 0) # Occupation 3 BETA_OCC_5_MOT = Beta('BETA_OCC_5_MOT', 0, None, None, 0) # Occupation 3 BETA_OCC_6_MOT = Beta('BETA_OCC_6_MOT', 0, None, None, 0) # Occupation 6 trip_comfort_car = Variable('trip_comfort_car') trip_comfort_moto = Variable('trip_comfort_moto') trip_comfort_bike = Variable('trip_comfort_moto') # in the training dataset, both moto and bike are under the moto variable trip_comfort_pt = Variable('trip_comfort_pt') trip_cost_car = Variable('trip_cost_car') trip_cost_moto = Variable('trip_cost_moto') trip_cost_bike = Variable('trip_cost_moto') # in the training dataset, both moto and bike are under the moto variable trip_cost_pt = Variable('trip_cost_pt') trip_dur_car = Variable('trip_dur_car') trip_dur_moto = Variable('trip_dur_moto') trip_dur_bike = Variable('trip_dur_moto') # in the training dataset, both moto and bike are under the moto variable trip_dur_pt = Variable('trip_dur_pt') trip_purpose = Variable('trip_purpose') AGE = Variable('AGE') user_gender = Variable('user_gender') user_trips_car = Variable('user_trips_car') user_trips_pt = Variable('user_trips_pt') OCC_1 = Variable('OCC_1') # 1:Private employee OCC_2 = Variable('OCC_2') # 2:Public servant OCC_3 = Variable('OCC_3') # 3:Self-employed OCC_4 = Variable('OCC_4') # 4:Student OCC_5 = Variable('OCC_5') # 5:Retired OCC_6 = Variable('OCC_6') # 6:Unemployed user_choice = Variable('user_choice') user_car_avail = Variable('user_car_avail') user_moto_avail = Variable('user_moto_avail') user_bike_avail = Variable('user_bike_avail') if country == 'GR' or country == 'ES': # FIXME create a separate model for ES ### Definition of utility functions - one for each alternative: V_CAR = ASC_CAR + \ BETA_TIME * trip_dur_car + \ BETA_S * trip_comfort_car V_PT = ASC_PT + \ BETA_TIME * trip_dur_pt+ \ BETA_S * trip_comfort_pt + \ BETA_SCOPE_PT * trip_purpose + \ BETA_AGE_PT * AGE + \ BETA_GENDER_PT * user_gender + \ BETA_NCAR_PT * user_trips_car + \ BETA_NPT_PT * user_trips_pt + \ BETA_OCC_2_PT * OCC_2 + \ BETA_OCC_5_PT * OCC_5 V_MOT = ASC_MOT + \ BETA_TIME * trip_dur_moto + \ BETA_S * trip_comfort_moto + \ BETA_SCOPE_MOT * trip_purpose + \ BETA_AGE_MOT * AGE + \ BETA_GENDER_MOT * user_gender + \ BETA_NCAR_MOT * user_trips_car + \ BETA_NPT_MOT * user_trips_pt + \ BETA_OCC_3_MOT * OCC_3 + \ BETA_OCC_6_MOT * OCC_6 # Associate the availability conditions with the alternatives. (Does not really apply on ToD modelling) av = {1: user_car_avail, 2: 1, 3: user_moto_avail} # Associate utility functions with the numbering of alternatives V = {1: V_CAR, 2: V_PT, 3: V_MOT} elif country == 'NL': ### Definition of utility functions - one for each alternative: V_CAR = ASC_CAR + \ BETA_COST * trip_cost_car + \ BETA_TIME * trip_dur_car + \ BETA_S * trip_comfort_car V_PT = ASC_PT + \ BETA_COST * trip_cost_pt + \ BETA_TIME * trip_dur_pt + \ BETA_S * trip_comfort_pt + \ BETA_AGE_PT * AGE + \ BETA_NCAR_PT * user_trips_car + \ BETA_NPT_PT * user_trips_pt + \ BETA_OCC_1_PT * OCC_1 + \ BETA_OCC_3_PT * OCC_3 + \ BETA_OCC_5_PT * OCC_5 + \ BETA_OCC_6_PT * OCC_6 V_BIKE = ASC_BIKE + \ BETA_COST * trip_cost_bike + \ BETA_TIME * trip_dur_bike + \ BETA_S * trip_comfort_bike + \ BETA_AGE_BIKE * AGE + \ BETA_NCAR_BIKE * user_trips_car + \ BETA_NPT_BIKE * user_trips_pt + \ BETA_OCC_1_BIKE * OCC_1 + \ BETA_OCC_3_BIKE * OCC_3 + \ BETA_OCC_4_BIKE * OCC_4 + \ BETA_OCC_5_BIKE * OCC_5 + \ BETA_OCC_6_BIKE * OCC_6 # Associate the availability conditions with the alternatives. (Does not really apply on ToD modelling) av = {1: user_car_avail, 2: 1, 3: user_bike_avail} # Associate utility functions with the numbering of alternatives V = {1: V_CAR, 2: V_PT, 3: V_BIKE} elif country == 'PT': ### Definition of utility functions - one for each alternative: V_CAR = ASC_CAR + \ BETA_TIME * trip_dur_car + \ BETA_COST * trip_cost_car V_PT = ASC_PT + \ BETA_TIME * trip_dur_pt + \ BETA_COST * trip_cost_pt + \ BETA_NCAR_PT * user_trips_car + \ BETA_NPT_PT * user_trips_pt + \ BETA_OCC_3_PT * OCC_3 V_MOT = ASC_MOT + \ BETA_TIME * trip_dur_moto + \ BETA_COST * trip_cost_moto + \ BETA_AGE_MOT * AGE + \ BETA_NCAR_MOT * user_trips_car + \ BETA_NPT_MOT * user_trips_pt + \ BETA_OCC_2_MOT * OCC_2 + \ BETA_OCC_3_MOT * OCC_3 + \ BETA_OCC_5_MOT * OCC_5 # Associate the availability conditions with the alternatives. (Does not really apply on ToD modelling) av = {1: user_car_avail, 2: 1, 3: user_moto_avail} # Associate utility functions with the numbering of alternatives V = {1: V_CAR, 2: V_PT, 3: V_MOT} else: V = 1 av = 1 print('There is no model specification for ', country) # The choice model is a log logit, with availability conditions logprob = bioLogLogit(util=V, av=av, choice=user_choice) biogeme = bio.BIOGEME(database=estimationdb, formulas=logprob) biogeme.modelName = "logitEstimation" # Create the outputs of the estimation and store in a namedtuple (= Model) results = biogeme.estimate() betas = results.getBetaValues() # To be used later for the simulation of the model structure = {1: models.logit(V, av, 1), 2: models.logit(V, av, 2), 3: models.logit(V, av, 3)} Output = collections.namedtuple('Output', ['betas', 'structure', 'results']) Model = Output(betas, structure, results) self.__cleanup_after_model_training() # print(self.evaluate_model(pandas_df_for_specified_country, Model)) return Model
# Associate utility functions with the numbering of alternatives V = {1: V1, 2: V2, 3: V3} # Associate the availability conditions with the alternatives CAR_AV_SP = DefineVariable('CAR_AV_SP',CAR_AV * ( SP != 0 ),database) TRAIN_AV_SP = DefineVariable('TRAIN_AV_SP',TRAIN_AV * ( SP != 0 ),database) av = {1: TRAIN_AV_SP, 2: SM_AV, 3: CAR_AV_SP} # The choice model is a logit, with availability conditions prob1 = Elem({0:0,1:models.logit(V,av,1)},av[1]) # Elasticities can be computed. We illustrate below two # formulas. Check in the output file that they produce the same # result. # First, the general definition of elasticities. This illustrates the # use of the Derive expression, and can be used with any model, # however complicated it is. Note the quotes in the Derive opertor. genelas1 = Derive(prob1,'TRAIN_TT') * TRAIN_TT / prob1 # Second, the elasticity of logit models. See Ben-Akiva and Lerman for # the formula logitelas1 = TRAIN_AV_SP * (1.0 - prob1) * TRAIN_TT_SCALED * B_TIME
BETA_TIME_CAR = BETA_TIME_CAR_REF * exp(BETA_TIME_CAR_CL * CARLOVERS) V1 = ASC_CAR + \ BETA_TIME_CAR * TimeCar_scaled + \ BETA_COST_HWH * CostCarCHF_scaled * PurpHWH + \ BETA_COST_OTHER * CostCarCHF_scaled * PurpOther + \ ec_sigma * errorComponent V2 = ASC_SM + BETA_DIST * distance_km_scaled # Associate utility functions with the numbering of alternatives V = {0: V0, 1: V1, 2: V2} # Conditional to the random parameters, we have a logit model (called # the kernel) for the choice condprob = models.logit(V, None, Choice) # Conditional to the random parameters, we have the product of ordered # probit for the indicators. condlike = P_Envir01 * \ P_Envir02 * \ P_Envir03 * \ P_Mobil11 * \ P_Mobil14 * \ P_Mobil16 * \ P_Mobil17 * \ condprob # We integrate over omega using Monte-Carlo integration loglike = log(MonteCarlo(condlike))
CAR_TT_SCALED = CAR_TT / 100 CAR_CO_SCALED = CAR_CO / 100 # Definition of the utility functions V1 = ASC_TRAIN + \ B_TIME_RND * TRAIN_TT_SCALED + \ B_COST * TRAIN_COST_SCALED V2 = ASC_SM + \ B_TIME_RND * SM_TT_SCALED + \ B_COST * SM_COST_SCALED V3 = ASC_CAR + \ B_TIME_RND * CAR_TT_SCALED + \ B_COST * CAR_CO_SCALED # Associate utility functions with the numbering of alternatives V = {1: V1, 2: V2, 3: V3} # Associate the availability conditions with the alternatives av = {1: TRAIN_AV_SP, 2: SM_AV, 3: CAR_AV_SP} # The choice model is a logit, with availability conditions integrand = models.logit(V, av, CHOICE) numericalI = Integrate(integrand * density, 'omega') simulate = {'Numerical': numericalI} biogeme = bio.BIOGEME(database, simulate) results = biogeme.simulate() print('Mixture of logit - numerical integration: ', results.iloc[0]['Numerical'])
ASC_SM_RND[i] + B_TIME_RND[i] * SM_TT_SCALED + B_COST[i] * SM_COST_SCALED for i in range(numberOfClasses) ] V3 = [ ASC_CAR_RND[i] + B_TIME_RND[i] * CAR_TT_SCALED + B_COST[i] * CAR_CO_SCALED for i in range(numberOfClasses) ] V = [{1: V1[i], 2: V2[i], 3: V3[i]} for i in range(numberOfClasses)] # Associate the availability conditions with the alternatives av = {1: TRAIN_AV_SP, 2: SM_AV, 3: CAR_AV_SP} # The choice model is a discrete mixture of logit, with availability conditions # We calculate the conditional probability for each class prob = [ PanelLikelihoodTrajectory(models.logit(V[i], av, CHOICE)) for i in range(numberOfClasses) ] # Class membership model W = CLASS_CTE + CLASS_INC * INCOME PROB_class0 = models.logit({0: W, 1: 0}, None, 0) PROB_class1 = models.logit({0: W, 1: 0}, None, 1) # Conditional to the random variables, likelihood for the individual. probIndiv = PROB_class0 * prob[0] + PROB_class1 * prob[1] # We integrate over the random variables using Monte-Carlo logprob = log(MonteCarlo(probIndiv)) # Define level of verbosity
CAR_AV_SP = DefineVariable('CAR_AV_SP',CAR_AV * ( SP != 0 ),database) TRAIN_AV_SP = DefineVariable('TRAIN_AV_SP',TRAIN_AV * ( SP != 0 ),database) av = {1: TRAIN_AV_SP, 2: SM_AV, 3: CAR_AV_SP} # Class membership model W_OTHER = Beta('W_OTHER',0.5,0,1,0) probClass1 = 1 - W_OTHER probClass2 = W_OTHER # The choice model is a discrete mixture of logit, with availability conditions prob1 = models.logit(V1,av,CHOICE) prob2 = models.logit(V2,av,CHOICE) prob = probClass1 * prob1 + probClass2 * prob2 logprob = log(prob) class test_07(unittest.TestCase): def testEstimation(self): biogeme = bio.BIOGEME(database,logprob) results = biogeme.estimate() self.assertAlmostEqual(results.data.logLike,-5208.4980304812725,2) if __name__ == '__main__': unittest.main()
def apply_model_to_example(df_persons, betas, output_directory_for_simulation, output_file_name): """ :author: Antonin Danalet, based on the example '01logit_simul.py' by Michel Bierlaire, EPFL, on biogeme.epfl.ch Simulation with a binary logit model. Two alternatives: work from home at least some times, or not.""" # Read the data database = db.Database('persons', df_persons) # The following statement allows you to use the names of the variable as Python variable. globals().update(database.variables) # Parameters to be estimated alternative_specific_constant = Beta('alternative_specific_constant', 0, None, None, 0) b_no_post_school_education = Beta('b_no_post_school_education', 0, None, None, 0) b_secondary_education = Beta('b_secondary_education', 0, None, None, 0) b_tertiary_education = Beta('b_tertiary_education', 0, None, None, 0) b_university = Beta('b_university', 0, None, None, 1) b_male = Beta('b_male', 0, None, None, 0) b_public_transport_connection_quality_are_a_home = Beta( 'b_public_transport_connection_quality_are_a_home', 0, None, None, 1) b_public_transport_connection_quality_are_b_home = Beta( 'b_public_transport_connection_quality_are_b_home', 0, None, None, 1) b_public_transport_connection_quality_are_c_home = Beta( 'b_public_transport_connection_quality_are_c_home', 0, None, None, 1) b_public_transport_connection_quality_are_d_home = Beta( 'b_public_transport_connection_quality_are_d_home', 0, None, None, 1) b_public_transport_connection_quality_are_na_home = Beta( 'b_public_transport_connection_quality_are_na_home', 0, None, None, 0) b_urban_work = Beta('b_urban_work', 0, None, None, 1) b_rural_work = Beta('b_rural_work', 0, None, None, 0) b_intermediate_work = Beta('b_intermediate_work', 0, None, None, 1) b_home_work_distance = Beta('b_home_work_distance', 0, None, None, 0) b_business_sector_agriculture = Beta('b_business_sector_agriculture', 0, None, None, 0) b_business_sector_production = Beta('b_business_sector_production', 0, None, None, 0) b_business_sector_wholesale = Beta('b_business_sector_wholesale', 0, None, None, 1) b_business_sector_retail = Beta('b_business_sector_retail', 0, None, None, 0) b_business_sector_gastronomy = Beta('b_business_sector_gastronomy', 0, None, None, 0) b_business_sector_finance = Beta('b_business_sector_finance', 0, None, None, 1) b_business_sector_services_fc = Beta('b_business_sector_services_fc', 0, None, None, 0) b_business_sector_other_services = Beta('b_business_sector_other_services', 0, None, None, 1) b_business_sector_others = Beta('b_business_sector_others', 0, None, None, 1) b_business_sector_non_movers = Beta('b_business_sector_non_movers', 0, None, None, 0) b_employees = Beta('b_employees', 0, None, None, 1) b_executives = Beta('b_executives', 0, None, None, 0) b_german = Beta('b_german', 0, None, None, 0) b_nationality_ch_germany_france_italy_nw_e = Beta( 'b_nationality_ch_germany_france_italy_nw_e', 0, None, None, 1) b_nationality_south_west_europe = Beta('b_nationality_south_west_europe', 0, None, None, 1) b_nationality_southeast_europe = Beta('b_nationality_southeast_europe', 0, None, None, 1) b_hh_income_na = Beta('B_hh_income_na', 0, None, None, 1) b_hh_income_8000_or_less = Beta('b_hh_income_8000_or_less', 0, None, None, 0) b_hh_income_more_than_8000 = Beta('b_hh_income_more_than_8000', 0, None, None, 1) # Definition of new variables no_post_school_educ = ((highest_educ == 1) | (highest_educ == 2) | (highest_educ == 3) | (highest_educ == 4)) secondary_education = ((highest_educ == 5) | (highest_educ == 6) | (highest_educ == 7) | (highest_educ == 8) | (highest_educ == 9) | (highest_educ == 10) | (highest_educ == 11) | (highest_educ == 12)) tertiary_education = ((highest_educ == 13) | (highest_educ == 14) | (highest_educ == 15) | (highest_educ == 16)) university = (highest_educ == 17) male = (sex == 1) public_transport_connection_quality_ARE_A_home = ( public_transport_connection_quality_ARE_home == 1) public_transport_connection_quality_ARE_B_home = ( public_transport_connection_quality_ARE_home == 2) public_transport_connection_quality_ARE_C_home = ( public_transport_connection_quality_ARE_home == 3) public_transport_connection_quality_ARE_D_home = ( public_transport_connection_quality_ARE_home == 4) public_transport_connection_quality_ARE_NA_home = ( public_transport_connection_quality_ARE_home == 5) urban_work = (urban_typology_work == 1) rural_work = (urban_typology_work == 3) intermediate_work = (urban_typology_work == 2) home_work_distance = (home_work_crow_fly_distance * (home_work_crow_fly_distance >= 0.0) / 100000.0) business_sector_agriculture = DefineVariable('business_sector_agriculture', 1 <= noga_08 <= 7, database) business_sector_retail = DefineVariable('business_sector_retail', 47 <= noga_08 <= 47, database) business_sector_gastronomy = DefineVariable('business_sector_gastronomy', 55 <= noga_08 <= 57, database) business_sector_finance = DefineVariable('business_sector_finance', 64 <= noga_08 <= 67, database) business_sector_production = DefineVariable( 'business_sector_production', (10 <= noga_08 <= 35) | (40 <= noga_08 <= 44), database) business_sector_wholesale = DefineVariable('business_sector_wholesale', (45 <= noga_08 <= 45) | (49 <= noga_08 <= 54), database) business_sector_services_fC = DefineVariable( 'business_sector_services_fC', (60 <= noga_08 <= 63) | (69 <= noga_08 <= 83) | (noga_08 == 58), database) business_sector_other_services = DefineVariable( 'business_sector_other_services', (86 <= noga_08 <= 90) | (92 <= noga_08 <= 96) | (noga_08 == 59) | (noga_08 == 68), database) business_sector_others = DefineVariable('business_sector_others', 97 <= noga_08 <= 98, database) business_sector_non_movers = DefineVariable( 'business_sector_non_movers', (8 <= noga_08 <= 9) | (36 <= noga_08 <= 39) | (84 <= noga_08 <= 85) | (noga_08 == 91) | (noga_08 == 99), database) employees = work_position == 2 executives = work_position == 1 german = language == 1 nationality_switzerland = nation == 8100 nationality_germany_austria_lichtenstein = (nation == 8207) + ( nation == 8229) + (nation == 8222) nationality_italy_vatican = (nation == 8218) + (nation == 8241) nationality_france_monaco_san_marino = (nation == 8212) + ( nation == 8226) + (nation == 8233) nationality_northwestern_europe = (nation == 8204) + (nation == 8223) + (nation == 8227) + (nation == 8206) + \ (nation == 8211) + (nation == 8215) + (nation == 8216) + (nation == 8217) + \ (nation == 8228) + (nation == 8234) nationality_south_west_europe = (nation == 8231) + (nation == 8236) + ( nation == 8202) nationality_southeast_europe = (nation == 8224) + (nation == 8201) + (nation == 8214) + (nation == 8256) + \ (nation == 8250) + (nation == 8251) + (nation == 8252) + (nation == 8255) + \ (nation == 8205) + (nation == 8239) + (nation == 8242) + (nation == 8248) + \ (nation == 8254) nationality_eastern_europe = (nation == 8230) + (nation == 8232) + (nation == 8240) + (nation == 8243) + \ (nation == 8244) + (nation == 8263) + (nation == 8265) + (nation == 8266) + \ (nation == 8260) + (nation == 8261) + (nation == 8262) # several_part_time_jobs = full_part_time_job == 3 work_percentage = DefineVariable( 'work_percentage', bioMin( (full_part_time_job == 1) * 100 + percentage_first_part_time_job * (percentage_first_part_time_job > 0), # + # percentage_second_part_time_job * (percentage_second_part_time_job > 0), 100), database) hh_income_na = hh_income == -98 hh_income_less_than_2000 = hh_income == 1 hh_income_2000_to_4000 = hh_income == 2 hh_income_4001_to_6000 = hh_income == 3 hh_income_6001_to_8000 = hh_income == 4 hh_income_8001_to_10000 = hh_income == 5 hh_income_10001_to_12000 = hh_income == 6 hh_income_12001_to_14000 = hh_income == 7 hh_income_14001_to_16000 = hh_income == 8 hh_income_more_than_16000 = hh_income == 9 # Utility U = alternative_specific_constant + \ b_executives * executives + \ b_employees * employees + \ b_no_post_school_education * no_post_school_educ + \ b_secondary_education * secondary_education + \ b_tertiary_education * tertiary_education + \ b_university * university + \ b_male * male + \ b_public_transport_connection_quality_are_a_home * public_transport_connection_quality_ARE_A_home + \ b_public_transport_connection_quality_are_b_home * public_transport_connection_quality_ARE_B_home + \ b_public_transport_connection_quality_are_c_home * public_transport_connection_quality_ARE_C_home + \ b_public_transport_connection_quality_are_d_home * public_transport_connection_quality_ARE_D_home + \ b_public_transport_connection_quality_are_na_home * public_transport_connection_quality_ARE_NA_home + \ b_urban_work * urban_work + \ b_rural_work * rural_work + \ b_intermediate_work * intermediate_work + \ b_home_work_distance * home_work_distance + \ models.piecewiseFormula(age, [0, 20, 35, 75, 200]) + \ b_business_sector_agriculture * business_sector_agriculture + \ b_business_sector_retail * business_sector_retail + \ b_business_sector_gastronomy * business_sector_gastronomy + \ b_business_sector_finance * business_sector_finance + \ b_business_sector_production * business_sector_production + \ b_business_sector_wholesale * business_sector_wholesale + \ b_business_sector_services_fc * business_sector_services_fC + \ b_business_sector_other_services * business_sector_other_services + \ b_business_sector_others * business_sector_others + \ b_business_sector_non_movers * business_sector_non_movers + \ b_german * german + \ b_nationality_ch_germany_france_italy_nw_e * nationality_switzerland + \ b_nationality_ch_germany_france_italy_nw_e * nationality_germany_austria_lichtenstein + \ b_nationality_ch_germany_france_italy_nw_e * nationality_italy_vatican + \ b_nationality_ch_germany_france_italy_nw_e * nationality_france_monaco_san_marino + \ b_nationality_ch_germany_france_italy_nw_e * nationality_northwestern_europe + \ b_nationality_south_west_europe * nationality_south_west_europe + \ b_nationality_southeast_europe * nationality_southeast_europe + \ b_nationality_ch_germany_france_italy_nw_e * nationality_eastern_europe + \ models.piecewiseFormula(work_percentage, [0, 90, 101]) + \ b_hh_income_na * hh_income_na + \ b_hh_income_8000_or_less * hh_income_less_than_2000 + \ b_hh_income_8000_or_less * hh_income_2000_to_4000 + \ b_hh_income_8000_or_less * hh_income_4001_to_6000 + \ b_hh_income_8000_or_less * hh_income_6001_to_8000 + \ b_hh_income_more_than_8000 * hh_income_8001_to_10000 + \ b_hh_income_more_than_8000 * hh_income_10001_to_12000 + \ b_hh_income_more_than_8000 * hh_income_12001_to_14000 + \ b_hh_income_more_than_8000 * hh_income_14001_to_16000 + \ b_hh_income_more_than_8000 * hh_income_more_than_16000 U_No_telecommuting = 0 # Associate utility functions with the numbering of alternatives V = { 1: U, # Yes or sometimes 0: U_No_telecommuting } # No av = {1: 1, 0: 1} # The choice model is a logit, with availability conditions prob_telecommuting = models.logit(V, av, 1) prob_no_telecommuting = models.logit(V, av, 0) simulate = { 'Prob. telecommuting': prob_telecommuting, 'Prob. no telecommuting': prob_no_telecommuting } # Create the Biogeme object biogeme = bio.BIOGEME(database, simulate) biogeme.modelName = 'logit_telecommuting_simul' # Change the working directory, so that biogeme writes in the correct folder, i.e., where this file is # standard_directory = os.getcwd() # os.chdir(output_directory_for_simulation) results = biogeme.simulate(theBetaValues=betas) # print(results.describe()) df_persons = pd.concat([df_persons, results], axis=1) # Go back to the normal working directory # os.chdir(standard_directory) ''' Save the file ''' df_persons.to_csv(output_directory_for_simulation / output_file_name, sep=',', index=False)
b_emipp = u_emipp + sd_emipp * bioDraws('b_emipp', 'NORMAL') V1 = price_1*b_price+time_1*b_time+conven_1*b_conven+comfort_1*b_comfort+\ meals_1*b_meals+petfr_1*b_petfr+emipp_1*b_emipp+nonsig1_1*b_nonsig1+\ nonsig2_1*b_nonsig2+nonsig3_1*b_nonsig3 V2 = price_2*b_price+time_2*b_time+conven_2*b_conven+comfort_2*b_comfort+\ meals_2*b_meals+petfr_2*b_petfr+emipp_2*b_emipp+nonsig1_2*b_nonsig1+\ nonsig2_2*b_nonsig2+nonsig3_2*b_nonsig3 V3 = price_3*b_price+time_3*b_time+conven_3*b_conven+comfort_3*b_comfort+\ meals_3*b_meals+petfr_3*b_petfr+emipp_3*b_emipp+nonsig1_3*b_nonsig1+\ nonsig2_3*b_nonsig2+nonsig3_3*b_nonsig3 V = {1: V1, 2: V2, 3: V3} av = {1: aval_1, 2: aval_2, 3: aval_3} prob = models.logit(V, av, choice) logprob = log(MonteCarlo(prob)) # Define level of verbosity logger = msg.bioMessage() logger.setSilent() # Create the Biogeme object biogeme = bio.BIOGEME(database, logprob, numberOfDraws=n_draws, numberOfThreads=n_cores) biogeme.modelName = 'MixedLogitArtificial' biogeme.generateHtml = False biogeme.generatePickle = False # Estimate the parameters
# For latent class 2, whete the time coefficient is estimated V21 = ASC_TRAIN + B_TIME * TRAIN_TT_SCALED + B_COST * TRAIN_COST_SCALED + EC_TRAIN V22 = ASC_SM + B_TIME * SM_TT_SCALED + B_COST * SM_COST_SCALED + EC_SM V23 = ASC_CAR + B_TIME * CAR_TT_SCALED + B_COST * CAR_CO_SCALED + EC_CAR V2 = {1: V21, 2: V22, 3: V23} # Associate the availability conditions with the alternatives CAR_AV_SP = DefineVariable('CAR_AV_SP', CAR_AV * (SP != 0), database) TRAIN_AV_SP = DefineVariable('TRAIN_AV_SP', TRAIN_AV * (SP != 0), database) av = {1: TRAIN_AV_SP, 2: SM_AV, 3: CAR_AV_SP} # Class membership model W_OTHER = Beta('W_OTHER', 0.798, 0, 1, 0) probClass1 = 1 - W_OTHER probClass2 = W_OTHER # The choice model is a discrete mixture of logit, with availability conditions prob1 = PanelLikelihoodTrajectory(models.logit(V1, av, CHOICE)) prob2 = PanelLikelihoodTrajectory(models.logit(V2, av, CHOICE)) probIndiv = probClass1 * prob1 + probClass2 * prob2 logprob = log(MonteCarlo(probIndiv)) biogeme = bio.BIOGEME(database, logprob) biogeme.modelName = "15panelDiscrete" results = biogeme.estimate() print("Results=", results)
V3 = [ ASC_3[i] + beta_parktime3[i] * (parktime) + beta_parkcost3[i] * (parkcost) / 10 + beta_dist3[i] * sharedist / 10 for i in range(numberOfClasses) ] V4 = [ASC_4[i] for i in range(numberOfClasses)] V = [{1: V1[i], 2: V2[i], 3: V3[i], 4: V4[i]} for i in range(numberOfClasses)] # Associate the availability conditions with the alternatives av = {1: availability1, 2: availability2, 3: availability3, 4: availability4} # The choice model is a discrete mixture of logit, with availability conditions # We calculate the conditional probability for each class prob = [ PanelLikelihoodTrajectory(models.logit(V[i], av, choice)) for i in range(numberOfClasses) ] # Class membership model W = CLASS_MAAS + beta_enthu * factor1 + beta_fru * factor2 + beta_inc2*inc_mid +\ beta_edu2 * edu_HBO + beta_fam * fam_1 + beta_fam * fam_2 + beta_age * age_10_60 PROB_class0 = models.logit({1: W, 0: 0}, None, 1) PROB_class1 = models.logit({1: W, 0: 0}, None, 0) # Conditional to the random variables, likelihood for the individual. probIndiv = PROB_class0 * prob[0] + PROB_class1 * prob[1] # We integrate over the random variables using Monte-Carlo logprob = log(MonteCarlo(probIndiv)) # Define level of verbosity
B_COST * SM_COST_SCALED V3 = ASC_CAR + \ B_TIME * CAR_TT_SCALED + \ B_COST * CAR_CO_SCALED # Associate utility functions with the numbering of alternatives V = {1: V1, 2: V2, 3: V3} # Associate the availability conditions with the alternatives CAR_AV_SP = DefineVariable('CAR_AV_SP', CAR_AV * (SP != 0), database) TRAIN_AV_SP = DefineVariable('TRAIN_AV_SP', TRAIN_AV * (SP != 0), database) av = {1: TRAIN_AV_SP, 2: SM_AV, 3: CAR_AV_SP} # The choice model is a logit, with availability conditions prob1 = models.logit(V, av, 1) prob2 = models.logit(V, av, 2) prob3 = models.logit(V, av, 3) # Elasticities can be computed. We illustrate below two # formulas. Check in the output file that they produce the same # result. # First, the general definition of elasticities. This illustrates the # use of the Derive expression, and can be used with any model, # however complicated it is. Note the quotes in the Derive opertor. genelas1 = Derive(prob1, 'TRAIN_TT') * TRAIN_TT / prob1 genelas2 = Derive(prob2, 'SM_TT') * SM_TT / prob2 genelas3 = Derive(prob3, 'CAR_TT') * CAR_TT / prob3
V2 = [ASC_SM_RND[i] + B_TIME_RND[i] * SM_TT_SCALED + B_COST[i] * SM_COST_SCALED for i in range(numberOfClasses)] V3 = [ASC_CAR_RND[i] + B_TIME_RND[i] * CAR_TT_SCALED + B_COST[i] * CAR_CO_SCALED for i in range(numberOfClasses)] V = [{1: V1[i], 2: V2[i], 3: V3[i]} for i in range(numberOfClasses)] # Associate the availability conditions with the alternatives av = {1: TRAIN_AV_SP, 2: SM_AV, 3: CAR_AV_SP} # The choice model is a discrete mixture of logit, with availability conditions # We calculate the conditional probability for each class prob = [MonteCarlo(PanelLikelihoodTrajectory(models.logit(V[i], av, CHOICE))) for i in range(numberOfClasses)] # Conditional to the random variables, likelihood for the individual. probIndiv = PROB_class0 * prob[0] + PROB_class1 * prob[1] # We integrate over the random variables using Monte-Carlo logprob = log(probIndiv) # Define level of verbosity logger = msg.bioMessage() #logger.setSilent() #logger.setWarning() logger.setGeneral() #logger.setDetailed()
MaaS = ASC_2 + beta_maascostperdist2 *(maascost*10/distance)+ beta_nonebike_accesstime*(maastime1) + beta_ebike_accesstime* maastime2 +\ beta_extra*(extra) *extra +\ beta_enthu * factor1 + beta_fru * factor2 + beta_constructive * factor3 + beta_travelzeal * factor4 + beta_age_package * age_10_60 +\ beta_edu2_package * edu_WO +beta_edu2_package * edu_HBO + beta_inc2_package*inc_mid + SIGMA_SH_MAASRND + beta_freq * highfreq + beta_freq * mediumfreq Continue_following_existing_way = ASC_3 + beta_totcostperdist * (currcost*10/distance) + beta_age_private * age_60_abv + \ beta_edu2_private * edu_WO + beta_edu2_private * edu_HBO + beta_inc2_private*inc_mid # Associate utility functions with the numbering of alternatives choiceset = {1: Shared_vehicle, 2: MaaS, 3: Continue_following_existing_way} availability = {1: availability1, 2: availability2, 3: availability3} # Definition of the model. This is the contribution of each # observation to the log likelihood function. # The choice model is a nested logit, with availability conditions obsprob = models.logit(choiceset, availability, choice) condprobIndiv = PanelLikelihoodTrajectory(obsprob) # We integrate over the random parameters using Monte-Carlo logprob = log(MonteCarlo(condprobIndiv)) # Define level of verbosity logger = msg.bioMessage() #logger.setSilent() #logger.setWarning() #logger.setGeneral() logger.setDetailed() # Create the Biogeme object biogeme = bio.BIOGEME(database, logprob, numberOfDraws=50) biogeme.modelName = 'Mixed logit outside'
V1 = ASC_CAR + \ BETA_TIME_CAR * TimeCar_scaled + \ BETA_COST_HWH * CostCarCHF_scaled * PurpHWH + \ BETA_COST_OTHER * CostCarCHF_scaled * PurpOther V2 = ASC_SM + BETA_DIST * distance_km_scaled # Associate utility functions with the numbering of alternatives V = {0: V0, 1: V1, 2: V2} # Associate the availability conditions with the alternatives. # In this example all alternatives are available for each individual. av = {0: 1, 1: 1, 2: 1} # Conditional to omega, we have a logit model (called the kernel) for the choice condprob = models.logit(V, av, Choice) # Conditional to omega, we have the product of ordered probit for the indicators. condlike = P_Envir01 * \ P_Envir02 * \ P_Envir03 * \ P_Mobil11 * \ P_Mobil14 * \ P_Mobil16 * \ P_Mobil17 * \ condprob # We integrate over omega using numerical integration loglike = log(Integrate(condlike * density, 'omega')) # Define level of verbosity
V2 = ASC_SM + \ B_TIME_RND * SM_TT_SCALED + \ B_COST * SM_COST_SCALED V3 = ASC_CAR + \ B_TIME_RND * CAR_TT_SCALED + \ B_COST * CAR_CO_SCALED # Associate utility functions with the numbering of alternatives V = {1: V1, 2: V2, 3: V3} # Associate the availability conditions with the alternatives CAR_AV_SP = DefineVariable('CAR_AV_SP', CAR_AV * (SP != 0), database) TRAIN_AV_SP = DefineVariable('TRAIN_AV_SP', TRAIN_AV * (SP != 0), database) av = {1: TRAIN_AV_SP, 2: SM_AV, 3: CAR_AV_SP} obsprob = models.logit(V, av, CHOICE) condprobIndiv = PanelLikelihoodTrajectory(obsprob) logprob = log(MonteCarlo(condprobIndiv)) class test_12(unittest.TestCase): def testEstimation(self): biogeme = bio.BIOGEME(database, logprob, numberOfDraws=5, seed=10) results = biogeme.estimate() self.assertAlmostEqual(results.data.logLike, -4705.638407401872, 2) if __name__ == '__main__': unittest.main()
def estimate_model(self, pandas_df_for_specified_country, country): ''' :param pandas_df_for_specified_country: :param country: :return: The estimated model, in a variable with 3 attributes: betas, structure, results. ''' # create the respective database (needed for biogeme) estimationdb = db.Database('estimationdb', pandas_df_for_specified_country) print('Training Time of Departure model for', country) # Alternative Specific Constants ASC_EARLIER = Beta('ASC_EARLIER', 0, None, None, 1) # This ASC remains equal to zero ASC_ONTIME = Beta('ASC_ONTIME', 0, None, None, 0) ASC_LATER = Beta('ASC_LATER', 0, None, None, 0) # Beta variables (i.e. coefficients) - alternative specific BETA_TT = Beta( 'BETA_TT', 0, None, None, 0) # Travel Time - Beta of TT1, TT2, TT3 - same across all Alts BETA_WT = Beta( 'BETA_WT', 0, None, None, 0) # Walking Time - Beta of WT1, WT2, WT3 - same across all Alts BETA_FREQ = Beta( 'BETA_FREQ', 0, None, None, 0) # Frequency - Beta of F1, F2, F3 - same across all Alts BETA_FARE_DISCOUNT = Beta( 'BETA_FARE_DISCOUNT', 0, None, None, 0) # Fare Discount - Beta of C1, C2, C3 - same across all Alts # Beta variables (i.e. coefficients) - traveller BETA_GENDER_ONTIME = Beta('BETA_GENDER_ONTIME', 0, None, None, 0) # Beta of GENDER, for Alt 2 BETA_IMPORTANT_ONTIME = Beta('BETA_IMPORTANT_ONTIME', 0, None, None, 0) # Beta of TWORK, for Alt 2 BETA_SCOPE_ONTIME = Beta('BETA_SCOPE_ONTIME', 0, None, None, 0) # Beta of SCOPE, for Alt 2 BETA_NPT_ONTIME = Beta('BETA_NPT_ONTIME', 0, None, None, 0) # Beta of NPT, for Alt 2 BETA_GENDER_LATER = Beta('BETA_GENDER_LATER', 0, None, None, 0) # Beta of GENDER, for Alt 3 BETA_IMPORTANT_LATER = Beta('BETA_IMPORTANT_LATER', 0, None, None, 0) # Beta of TWORK, for Alt 3 BETA_SCOPE_LATER = Beta('BETA_SCOPE_LATER', 0, None, None, 0) # Beta of SCOPE, for Alt 3 BETA_NPT_LATER = Beta('BETA_NPT_LATER', 0, None, None, 0) # Beta of NPT, for Alt 3 BETA_HOUSEHOLD_LATER = Beta('BETA_HOUSEHOLD_LATER', 0, None, None, 0) # Beta of HOUSEHOLD, for Alt 3 BETA_INCOME_LATER = Beta('BETA_INCOME_LATER', 0, None, None, 0) # Beta of INCOME, for Alt 3 BETA_AGE_LATER = Beta('BETA_AGE_LATER', 0, None, None, 0) # Beta of AGE, for Alt 3 AGE = Variable('AGE') user_income = Variable('user_income') user_household = Variable('user_household') user_trips_pt = Variable('user_trips_pt') trip_discount_earlier = Variable('trip_discount_earlier') trip_discount_later = Variable('trip_discount_later') trip_discount_ontime = Variable('trip_discount_ontime') trip_dur_earlier = Variable('trip_dur_earlier') trip_dur_later = Variable('trip_dur_later') trip_dur_ontime = Variable('trip_dur_ontime') trip_freq_earlier = Variable('trip_freq_earlier') trip_freq_later = Variable('trip_freq_later') trip_freq_ontime = Variable('trip_freq_ontime') trip_purpose = Variable('trip_purpose') trip_walk_earlier = Variable('trip_walk_earlier') trip_walk_later = Variable('trip_walk_later') trip_walk_ontime = Variable('trip_walk_ontime') user_choice = Variable('user_choice') user_gender = Variable('user_gender') user_imp_arr = Variable('user_imp_arr') if country == 'GR' or country == 'ES': # FIXME create a separate model for ES # Definition of utility functions - one for each alternative: V_EARLIER = ASC_EARLIER + \ BETA_TT * trip_dur_earlier + \ BETA_WT * trip_walk_earlier + \ BETA_FREQ * trip_freq_earlier V_ONTIME = ASC_ONTIME + \ BETA_TT * trip_dur_ontime + \ BETA_WT * trip_walk_ontime + \ BETA_FREQ * trip_freq_ontime + \ BETA_IMPORTANT_ONTIME * user_imp_arr + \ BETA_NPT_ONTIME * user_trips_pt V_LATER = ASC_LATER + \ BETA_TT * trip_dur_later + \ BETA_WT * trip_walk_later + \ BETA_FREQ * trip_freq_later + \ BETA_IMPORTANT_LATER * user_imp_arr + \ BETA_GENDER_LATER * user_gender + \ BETA_AGE_LATER * AGE + \ BETA_INCOME_LATER * user_income + \ BETA_HOUSEHOLD_LATER * user_household + \ BETA_NPT_LATER * user_trips_pt elif country == 'NL': # Definition of utility functions - one for each alternative: V_EARLIER = ASC_EARLIER + \ BETA_TT * trip_dur_earlier + \ BETA_WT * trip_walk_earlier + \ BETA_FARE_DISCOUNT * trip_discount_earlier + \ BETA_FREQ * trip_freq_earlier V_ONTIME = ASC_ONTIME + \ BETA_TT * trip_dur_ontime + \ BETA_WT * trip_walk_ontime + \ BETA_FARE_DISCOUNT * trip_discount_ontime + \ BETA_FREQ * trip_freq_ontime + \ BETA_IMPORTANT_ONTIME * user_imp_arr + \ BETA_GENDER_ONTIME * user_gender V_LATER = ASC_LATER + \ BETA_TT * trip_dur_later + \ BETA_WT * trip_walk_later + \ BETA_FARE_DISCOUNT * trip_discount_later + \ BETA_FREQ * trip_freq_later + \ BETA_IMPORTANT_LATER * user_imp_arr + \ BETA_GENDER_LATER * user_gender + \ BETA_SCOPE_LATER * trip_purpose elif country == 'PT': # Definition of utility functions - one for each alternative: V_EARLIER = ASC_EARLIER + \ BETA_TT * trip_dur_earlier + \ BETA_WT * trip_walk_earlier + \ BETA_FREQ * trip_freq_earlier V_ONTIME = ASC_ONTIME + \ BETA_TT * trip_dur_ontime + \ BETA_WT * trip_walk_ontime + \ BETA_FREQ * trip_freq_ontime + \ BETA_IMPORTANT_ONTIME * user_imp_arr + \ BETA_GENDER_ONTIME * user_gender + \ BETA_SCOPE_ONTIME * trip_purpose V_LATER = ASC_LATER + \ BETA_TT * trip_dur_later + \ BETA_WT * trip_walk_later + \ BETA_FREQ * trip_freq_later + \ BETA_IMPORTANT_LATER * user_imp_arr + \ BETA_GENDER_LATER * user_gender + \ BETA_SCOPE_LATER * trip_purpose else: V_EARLIER = ASC_EARLIER V_ONTIME = ASC_ONTIME V_LATER = ASC_LATER print('There is no model specification for ', country) # Associate utility functions with the numbering of alternatives V = {1: V_EARLIER, 2: V_ONTIME, 3: V_LATER} # Associate the availability conditions with the alternatives. (Does not really apply on ToD modelling) av = { 1: 1, # A user is able to arrive earlier.. 2: 1, # A user is able to arrive on time.. 3: 1 } # A user is able to arrive later.. # The choice model is a log logit, with availability conditions logprob = bioLogLogit(util=V, av=av, choice=user_choice) biogeme = bio.BIOGEME(database=estimationdb, formulas=logprob) biogeme.modelName = "logitEstimation" # Create the outputs of the estimation and store in a namedtuple (= Model) results = biogeme.estimate() betas = results.getBetaValues( ) # To be used later for the simulation of the model structure = { 1: models.logit(V, av, 1), 2: models.logit(V, av, 2), 3: models.logit(V, av, 3) } Output = collections.namedtuple('Output', ['betas', 'structure', 'results']) Model = Output(betas, structure, results) self.__cleanup_after_model_training() # print(self.evaluate_model(pandas_df_for_specified_country, Model)) return Model