Example #1
0
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
Example #2
0
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
Example #3
0
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)
Example #4
0
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
Example #5
0
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