def cdap_model( edb_directory="output/estimation_data_bundle/{name}/", coefficients_file="{name}_coefficients.csv", interaction_coeffs_file="{name}_interaction_coefficients.csv", households_file="../../final_households.csv", persons_file="../../final_persons.csv", spec1_file="{name}_INDIV_AND_HHSIZE1_SPEC.csv", settings_file="{name}_model_settings.yaml", chooser_data_file="{name}_values_combined.csv", return_data=False, ): d = cdap_data( name="cdap", edb_directory=edb_directory, coefficients_file=coefficients_file, interaction_coeffs_file=interaction_coeffs_file, households_file=households_file, persons_file=persons_file, spec1_file=spec1_file, settings_file=settings_file, chooser_data_file=chooser_data_file, ) households = d.households values = d.person_data spec1 = d.spec1 interaction_coef = d.interaction_coef coefficients = d.coefficients cdap_dfs = cdap_dataframes(households, values) m = {} _logger.info(f"building for model 1") m[1] = Model(dataservice=cdap_dfs[1]) cdap_base_utility_by_person(m[1], n_persons=1, spec=spec1) m[1].choice_any = True m[1].availability_any = True # Add cardinality into interaction_coef if not present if 'cardinality' not in interaction_coef: interaction_coef['cardinality'] = interaction_coef[ 'interaction_ptypes'].str.len() for s in [2, 3, 4, 5]: _logger.info(f"building for model {s}") m[s] = Model(dataservice=cdap_dfs[s]) alts = generate_alternatives(s) cdap_base_utility_by_person(m[s], s, spec1, alts, values.columns) cdap_interaction_utility(m[s], s, alts, interaction_coef, coefficients) m[s].choice_any = True m[s].availability_any = True model = ModelGroup(m.values()) explicit_value_parameters(model) apply_coefficients(coefficients, model) if return_data: return model, d return model
def stop_frequency_model( edb_directory="output/estimation_data_bundle/{name}/", return_data=False, ): data = stop_frequency_data( edb_directory=edb_directory, values_index_col="tour_id", ) models = [] for n in range(len(data.spec)): coefficients = data.coefficients # coef_template = data.coef_template # not used spec = data.spec[n] chooser_data = data.chooser_data[n] settings = data.settings alt_names = data.alt_names[n] alt_codes = data.alt_codes[n] from .general import clean_values chooser_data = clean_values( chooser_data, alt_names_to_codes=data.alt_names_to_codes[n], choice_code="override_choice_code", ) if settings.get('LOGIT_TYPE') == 'NL': tree = construct_nesting_tree(data.alt_names[n], settings["NESTS"]) m = Model(graph=tree) else: m = Model() m.utility_co = dict_of_linear_utility_from_spec( spec, "Label", dict(zip(alt_names, alt_codes)), ) apply_coefficients(coefficients, m) avail = True d = DataFrames( co=chooser_data, av=avail, alt_codes=alt_codes, alt_names=alt_names, ) m.dataservice = d m.choice_co_code = "override_choice_code" models.append(m) from larch.model.model_group import ModelGroup models = ModelGroup(models) if return_data: return ( models, data, ) return models
def test_simple_model_group(): df = pd.read_csv(example_file("MTCwork.csv.gz")) df.set_index(['casenum', 'altnum'], inplace=True) d = larch.DataFrames(df, ch='chose', crack=True) d.set_alternative_names({ 1: 'DA', 2: 'SR2', 3: 'SR3+', 4: 'Transit', 5: 'Bike', 6: 'Walk', }) m0 = larch.Model(dataservice=d) m0.utility_co[2] = P("ASC_SR2") + P("hhinc#2") * X("hhinc") m0.utility_co[3] = P("ASC_SR3P") + P("hhinc#3") * X("hhinc") m0.utility_co[4] = P("ASC_TRAN") + P("hhinc#4") * X("hhinc") m0.utility_co[5] = P("ASC_BIKE") + P("hhinc#5") * X("hhinc") m0.utility_co[6] = P("ASC_WALK") + P("hhinc#6") * X("hhinc") m0.utility_ca = ( (P("tottime_m") * X("tottime") + P("totcost_m") * X("totcost")) * X("femdum == 0") + (P("tottime_f") * X("tottime") + P("totcost_f") * X("totcost")) * X("femdum == 1")) m1 = larch.Model(dataservice=d.selector_co("femdum == 0")) m1.utility_co[2] = P("ASC_SR2") + P("hhinc#2") * X("hhinc") m1.utility_co[3] = P("ASC_SR3P") + P("hhinc#3") * X("hhinc") m1.utility_co[4] = P("ASC_TRAN") + P("hhinc#4") * X("hhinc") m1.utility_co[5] = P("ASC_BIKE") + P("hhinc#5") * X("hhinc") m1.utility_co[6] = P("ASC_WALK") + P("hhinc#6") * X("hhinc") m1.utility_ca = P("tottime_m") * X("tottime") + P("totcost_m") * X( "totcost") m2 = larch.Model(dataservice=d.selector_co("femdum == 1")) m2.utility_co[2] = P("ASC_SR2") + P("hhinc#2") * X("hhinc") m2.utility_co[3] = P("ASC_SR3P") + P("hhinc#3") * X("hhinc") m2.utility_co[4] = P("ASC_TRAN") + P("hhinc#4") * X("hhinc") m2.utility_co[5] = P("ASC_BIKE") + P("hhinc#5") * X("hhinc") m2.utility_co[6] = P("ASC_WALK") + P("hhinc#6") * X("hhinc") m2.utility_ca = P("tottime_f") * X("tottime") + P("totcost_f") * X( "totcost") m0.load_data() assert m0.loglike2().ll == approx(-7309.600971749625) m1.load_data() assert m1.loglike2().ll == approx(-4068.8091617468717) m2.load_data() assert m2.loglike2().ll == approx(-3240.7918100027578) from larch.model.model_group import ModelGroup mg = ModelGroup([m1, m2]) assert mg.loglike2().ll == approx(-7309.600971749625) assert mg.loglike() == approx(-7309.600971749625) pd.testing.assert_series_equal(mg.loglike2().dll.sort_index(), m0.loglike2().dll.sort_index()) m0.simple_step_bhhh() mg.set_values(**m0.pf.value) pd.testing.assert_series_equal(mg.loglike2().dll.sort_index(), m0.loglike2().dll.sort_index()) assert mg.loglike2().ll == approx(-4926.4822036792275) assert mg.check_d_loglike().data.similarity.min() > 4 result = mg.maximize_loglike(method='slsqp') assert result.loglike == approx(-3620.697668335103) mg2 = ModelGroup([]) mg2.append(m1) mg2.append(m2) assert mg2.loglike() == approx(-3620.697667552756) mg3 = ModelGroup([]) mg3.append(m1) mg3.append(m2) mg3.doctor() assert mg3.loglike() == approx(-3620.697667552756)
def mode_choice_model( name, edb_directory="output/estimation_data_bundle/{name}/", return_data=False, override_filenames=None, ): if override_filenames is None: override_filenames = {} data = simple_simulate_data( name=name, edb_directory=edb_directory, **override_filenames, ) coefficients = data.coefficients coef_template = data.coef_template spec = data.spec chooser_data = data.chooser_data settings = data.settings chooser_data = clean_values( chooser_data, alt_names_to_codes=data.alt_names_to_codes, choice_code="override_choice_code", ) tree = construct_nesting_tree(data.alt_names, settings["NESTS"]) purposes = list(coef_template.columns) if "atwork" in name: purposes = ['atwork'] elif 'atwork' in purposes: purposes.remove('atwork') # Setup purpose specific models m = {purpose: Model(graph=tree, title=purpose) for purpose in purposes} for alt_code, alt_name in tree.elemental_names().items(): # Read in base utility function for this alt_name u = linear_utility_from_spec( spec, x_col="Label", p_col=alt_name, ignore_x=("#", ), ) for purpose in purposes: # Modify utility function based on template for purpose u_purp = sum((P(coef_template[purpose].get(i.param, i.param)) * i.data * i.scale) for i in u) m[purpose].utility_co[alt_code] = u_purp for model in m.values(): explicit_value_parameters(model) apply_coefficients(coefficients, m) avail = construct_availability(m[purposes[0]], chooser_data, data.alt_codes_to_names) d = DataFrames( co=chooser_data, av=avail, alt_codes=data.alt_codes, alt_names=data.alt_names, ) if 'atwork' not in name: for purpose, model in m.items(): model.dataservice = d.selector_co(f"tour_type=='{purpose}'") model.choice_co_code = "override_choice_code" else: for purpose, model in m.items(): model.dataservice = d model.choice_co_code = "override_choice_code" from larch.model.model_group import ModelGroup mg = ModelGroup(m.values()) if return_data: return ( mg, Dict( edb_directory=Path(edb_directory), chooser_data=chooser_data, avail=avail, coefficients=coefficients, coef_template=coef_template, spec=spec, settings=settings, ), ) return mg
def tour_mode_choice_model( edb_directory="output/estimation_data_bundle/{name}/", return_data=False, ): data = simple_simulate_data( name="tour_mode_choice", edb_directory=edb_directory, ) coefficients = data.coefficients coef_template = data.coef_template spec = data.spec chooser_data = data.chooser_data settings = data.settings chooser_data = clean_values( chooser_data, data.alt_names, alt_names_to_codes=data.alt_names_to_codes, choice_code='override_choice_code', ) tree = construct_nesting_tree(data.alt_names, settings['NESTS']) purposes = list(coef_template.columns) # Setup purpose specific models m = {purpose: Model(graph=tree) for purpose in purposes} for alt_code, alt_name in tree.elemental_names().items(): # Read in base utility function for this alt_name u = linear_utility_from_spec( spec, x_col='Label', p_col=alt_name, ignore_x=('#', ), ) for purpose in purposes: # Modify utility function based on template for purpose u_purp = sum((P(coef_template[purpose].get(i.param, i.param)) * i.data * i.scale) for i in u) m[purpose].utility_co[alt_code] = u_purp for model in m.values(): explicit_value_parameters(model) apply_coefficients(coefficients, m) avail = {} for acode, aname in data.alt_codes_to_names.items(): unavail_cols = list((chooser_data[i.data] if i.data in chooser_data else chooser_data.eval(i.data)) for i in m[purposes[0]].utility_co[acode] if i.param == "-999") if len(unavail_cols): avail[acode] = sum(unavail_cols) == 0 else: avail[acode] = 1 avail = pd.DataFrame(avail).astype(np.int8) avail.index = chooser_data.index d = DataFrames( co=chooser_data, av=avail, alt_codes=data.alt_codes, alt_names=data.alt_names, ) for purpose, model in m.items(): model.dataservice = d.selector_co(f"tour_type=='{purpose}'") model.choice_co_code = 'override_choice_code' from larch.model.model_group import ModelGroup mg = ModelGroup(m.values()) if return_data: return mg, Dict( edb_directory=Path(edb_directory), chooser_data=chooser_data, avail=avail, coefficients=coefficients, coef_template=coef_template, spec=spec, ) return mg