def test_latent_class_full_data(swissmetro_raw_df): dfs = larch.DataFrames(swissmetro_raw_df, alt_codes=[1, 2, 3]) m1 = larch.Model(dataservice=dfs) m1.availability_co_vars = { 1: "TRAIN_AV_SP", 2: "SM_AV", 3: "CAR_AV_SP", } m1.choice_co_code = 'CHOICE' m1.utility_co[1] = P("ASC_TRAIN") + X("TRAIN_CO*(GA==0)") * P("B_COST") m1.utility_co[2] = X("SM_CO*(GA==0)") * P("B_COST") m1.utility_co[3] = P("ASC_CAR") + X("CAR_CO") * P("B_COST") m2 = larch.Model(dataservice=dfs) m2.availability_co_vars = { 1: "TRAIN_AV_SP", 2: "SM_AV", 3: "CAR_AV_SP", } m2.choice_co_code = 'CHOICE' m2.utility_co[1] = P("ASC_TRAIN") + X("TRAIN_TT") * P("B_TIME") + X( "TRAIN_CO*(GA==0)") * P("B_COST") m2.utility_co[ 2] = X("SM_TT") * P("B_TIME") + X("SM_CO*(GA==0)") * P("B_COST") m2.utility_co[3] = P( "ASC_CAR") + X("CAR_TT") * P("B_TIME") + X("CAR_CO") * P("B_COST") km = larch.Model(dataservice=dfs, alts=[1, 2]) km.utility_co[2] = P.W_OTHER from larch.model.latentclass import LatentClassModel m = LatentClassModel(km, {1: m1, 2: m2}) m.load_data() m.set_value(P.ASC_CAR, 0.125 / 2) m.set_value(P.ASC_TRAIN, -0.398 / 2) m.set_value(P.B_COST, -.0126 / 2) m.set_value(P.B_TIME, -0.028 / 2) m.set_value(P.W_OTHER, 1.095 / 2) check1 = m.check_d_loglike() assert dict(check1.data.analytic) == approx({ 'ASC_CAR': -81.69736186616234, 'ASC_TRAIN': -613.131371089499, 'B_COST': -6697.31706964777, 'B_TIME': -40104.940072046316, 'W_OTHER': 245.43145056623683, })
def test_pmath(): m = larch.Model() m.utility_ca = P.Aaa * X.Aaa + P.Bbb * X.Bbb + P.Ccc m.set_values(Aaa=12, Bbb=20, Ccc=2) assert P.Aaa.value(m) == 12 assert P.Bbb.value(m) == 20 assert P.Ccc.value(m) == 2 with pytest.raises(KeyError): P.Ddd.value(m) assert P.Ddd.value(m, {'Ddd': 123}) == 123 y = P.Aaa + P.Bbb assert y.value(m) == 12 + 20 assert repr(y) == 'P.Aaa + P.Bbb' assert repr(y + y) == 'P.Aaa + P.Bbb + P.Aaa + P.Bbb' assert isinstance(y, larch.model.linear.LinearFunction_C) assert isinstance(y + y, larch.model.linear.LinearFunction_C) y = P.Aaa / P.Bbb assert y.value(m) == 12 / 20 assert y.string(m) == "0.6" assert repr(y) == 'P.Aaa / P.Bbb' assert repr(y + y) == 'P.Aaa / P.Bbb + P.Aaa / P.Bbb' y = P.Aaa * 60 / (P.Bbb * 100) y.set_fmt("${:0.2f}/hr") assert y.value(m) == 12 * 60 / (20 * 100) assert y.string(m) == '$0.36/hr' y = P.Aaa + P.Bbb / P.Ccc assert y.value(m) == 12 + 20 / 2 assert isinstance(y, larch.model.linear_math.ParameterAdd) assert repr(y) == 'P.Aaa + P.Bbb / P.Ccc' y = (P.Aaa + P.Bbb) + P.Ccc * P.Aaa assert isinstance(y, larch.model.linear_math.ParameterAdd) assert y.value(m) == (12 + 20) + 2 * 12 y = (P.Aaa + P.Bbb) + P.Ccc / P.Aaa assert isinstance(y, larch.model.linear_math.ParameterAdd) assert y.value(m) == (12 + 20) + 2 / 12 y = (P.Aaa + P.Bbb + P.Ccc) * P.Aaa assert isinstance(y, larch.model.linear_math.ParameterMultiply) assert y.value(m) == (12 + 20 + 2) * 12 y = (P.Aaa + P.Bbb + P.Ccc) / P.Aaa assert isinstance(y, larch.model.linear_math.ParameterDivide) assert y.value(m) == (12 + 20 + 2) / 12 assert repr(y) == '(P.Aaa + P.Bbb + P.Ccc) / P.Aaa' y = (P.Aaa + P.Bbb + P.Ccc) - P.Aaa assert isinstance(y, larch.model.linear.LinearFunction_C) assert y.value(m) == 12 + 20 + 2 - 12
def test_linear_function_iadd(): # Test inplace add on unattached LinearFunction_C lf = P.tottime * X.tottime + P.totcost * X.totcost lf += X("totcost*tottime") * P("fake") assert lf == P.tottime * X.tottime + P.totcost * X.totcost + X( "totcost*tottime") * P("fake") # Test inplace add on attached LinearFunction_C m = larch.Model(utility_ca=P.tottime * X.tottime + P.totcost * X.totcost) m.utility_ca += X("totcost*tottime") * P("fake") xx = P.tottime * X.tottime + P.totcost * X.totcost + X( "totcost*tottime") * P("fake") assert m.utility_ca == xx
def fitModel(d,vars): m = larch.Model(d) m.option.threads=2 m.utility.ca = sum(PX(i) for i in vars) result = m.maximize_loglike() print(m.report('txt', sigfigs=3)) print(vars) print("loglike: ",result.loglike) nparams = len(vars) print("nparams: ",nparams) print("aic: ",aic(result.loglike,nparams)) return m
def test_latent_class_mixed_data(swissmetro_raw_df): dfs = larch.DataFrames(swissmetro_raw_df, alt_codes=[1, 2, 3]) m1 = larch.Model(dataservice=dfs) m1.availability_co_vars = { 1: "TRAIN_AV_SP", 2: "SM_AV", 3: "CAR_AV_SP", } m1.choice_co_code = 'CHOICE' m1.utility_co[1] = P("ASC_TRAIN") + X("TRAIN_CO*(GA==0)") * P("B_COST") m1.utility_co[2] = X("SM_CO*(GA==0)") * P("B_COST") m1.utility_co[3] = P("ASC_CAR") + X("CAR_CO") * P("B_COST") m2 = larch.Model(dataservice=dfs) m2.availability_co_vars = { 1: "TRAIN_AV_SP", 2: "SM_AV", 3: "CAR_AV_SP", } m2.choice_co_code = 'CHOICE' m2.utility_co[1] = P("ASC_TRAIN") + X("TRAIN_TT") * P("B_TIME") + X( "TRAIN_CO*(GA==0)") * P("B_COST") m2.utility_co[ 2] = X("SM_TT") * P("B_TIME") + X("SM_CO*(GA==0)") * P("B_COST") m2.utility_co[3] = P( "ASC_CAR") + X("CAR_TT") * P("B_TIME") + X("CAR_CO") * P("B_COST") dfs2 = larch.DataFrames(swissmetro_raw_df, alt_codes=[1, 2]) km = larch.Model(dataservice=dfs2) km.utility_co[2] = P.W_OTHER from larch.model.latentclass import LatentClassModel with raises(ValueError): m = LatentClassModel(km, {1: m1, 2: m2})
def test_joint_parameter_summary(): m = larch.example(1, legacy=True) m.load_data() m.loglike_null() m.set_values( **{ 'ASC_BIKE': -2.3763275319243244, 'ASC_SR2': -2.1780143286612037, 'ASC_SR3P': -3.725078388760564, 'ASC_TRAN': -0.6708609582690096, 'ASC_WALK': -0.20677521181801753, 'hhinc#2': -0.0021699381002406883, 'hhinc#3': 0.0003577067151217295, 'hhinc#4': -0.00528632366072714, 'hhinc#5': -0.012807975284603574, 'hhinc#6': -0.009686302933787567, 'totcost': -0.00492023540098787, 'tottime': -0.05134209452571549, }) m.loglike() m.maximize_loglike() m_c = larch.Model(dataservice=m.dataservice) m_c.choice_ca_var = '_choice_' m_c.availability_var = '_avail_' m_c.utility_co[2] = P("ASC_SR2") m_c.utility_co[3] = P("ASC_SR3P") m_c.utility_co[4] = P("ASC_TRAN") m_c.utility_co[5] = P("ASC_BIKE") m_c.utility_co[6] = P("ASC_WALK") m_c.title = "Constants Only" m_c.load_data() m_c.loglike_null() m_c.maximize_loglike() from larch.util.summary import joint_parameter_summary stable_df(joint_parameter_summary([m, m_c], bases=[m_c]), 'joint_parameter_summary')
def test_ch_av_summary_output(): skims = larch.OMX(larch.exampville.files.skims, mode='r') hh = pandas.read_csv(larch.exampville.files.hh) pp = pandas.read_csv(larch.exampville.files.person) tour = pandas.read_csv(larch.exampville.files.tour) pp_col = [ 'PERSONID', 'HHID', 'HHIDX', 'AGE', 'WORKS', 'N_WORK_TOURS', 'N_OTHER_TOURS', 'N_TOURS', 'N_TRIPS', 'N_TRIPS_HBW', 'N_TRIPS_HBO', 'N_TRIPS_NHB' ] raw = tour.merge(hh, on='HHID').merge(pp[pp_col], on=('HHID', 'PERSONID')) raw["HOMETAZi"] = raw["HOMETAZ"] - 1 raw["DTAZi"] = raw["DTAZ"] - 1 raw = raw[raw.TOURPURP == 1] f_tour = raw.join(skims.get_rc_dataframe( raw.HOMETAZi, raw.DTAZi, )) DA = 1 SR = 2 Walk = 3 Bike = 4 Transit = 5 dfs = larch.DataFrames( co=f_tour, alt_codes=[DA, SR, Walk, Bike, Transit], alt_names=['DA', 'SR', 'Walk', 'Bike', 'Transit'], ) m = larch.Model(dataservice=dfs) m.title = "Exampville Work Tour Mode Choice v1" m.utility_co[DA] = ( +P.InVehTime * X.AUTO_TIME + P.Cost * X.AUTO_COST # dollars per mile ) m.utility_co[SR] = ( +P.ASC_SR + P.InVehTime * X.AUTO_TIME + P.Cost * (X.AUTO_COST * 0.5) # dollars per mile, half share + P("HighInc:SR") * X("INCOME>75000")) m.utility_co[Walk] = (+P.ASC_Walk + P.NonMotorTime * X.WALK_TIME + P("HighInc:Walk") * X("INCOME>75000")) m.utility_co[Bike] = (+P.ASC_Bike + P.NonMotorTime * X.BIKE_TIME + P("HighInc:Bike") * X("INCOME>75000")) m.utility_co[Transit] = (+P.ASC_Transit + P.InVehTime * X.TRANSIT_IVTT + P.OutVehTime * X.TRANSIT_OVTT + P.Cost * X.TRANSIT_FARE + P("HighInc:Transit") * X("INCOME>75000")) # No choice or avail data set m.load_data() q = m.dataframes.choice_avail_summary() assert numpy.array_equal(q.columns, ['name', 'chosen', 'available']) assert q.index.identical( pandas.Index([1, 2, 3, 4, 5, '< Total All Alternatives >'], dtype='object')) assert numpy.array_equal(q.values, [ ['DA', None, None], ['SR', None, None], ['Walk', None, None], ['Bike', None, None], ['Transit', None, None], ['', 0, ''], ]) # Reasonable choice and avail data set m.choice_co_code = 'TOURMODE' m.availability_co_vars = { DA: 'AGE >= 16', SR: '1', Walk: 'WALK_TIME < 60', Bike: 'BIKE_TIME < 60', Transit: 'TRANSIT_FARE>0', } m.load_data() q = m.dataframes.choice_avail_summary() assert numpy.array_equal(q.columns, ['name', 'chosen', 'available']) assert q.index.identical( pandas.Index([1, 2, 3, 4, 5, '< Total All Alternatives >'], dtype='object')) assert numpy.array_equal(q['name'].values, ['DA', 'SR', 'Walk', 'Bike', 'Transit', '']) assert numpy.array_equal(q['chosen'].values, [6052., 810., 196., 72., 434., 7564.]) assert numpy.array_equal( q['available'].values, numpy.array([7564.0, 7564.0, 4179.0, 7564.0, 4199.0, ''], dtype=object)) # Unreasonable choice and avail data set m.choice_co_code = 'TOURMODE' m.availability_co_vars = { DA: 'AGE >= 26', SR: '1', Walk: 'WALK_TIME < 60', Bike: 'BIKE_TIME < 60', Transit: 'TRANSIT_FARE>0', } m.load_data() q = m.dataframes.choice_avail_summary() assert numpy.array_equal( q.columns, ['name', 'chosen', 'available', 'chosen but not available']) assert q.index.identical( pandas.Index([1, 2, 3, 4, 5, '< Total All Alternatives >'], dtype='object')) assert numpy.array_equal(q['name'].values, ['DA', 'SR', 'Walk', 'Bike', 'Transit', '']) assert numpy.array_equal(q['chosen'].values, [6052., 810., 196., 72., 434., 7564.]) assert numpy.array_equal( q['available'].values, numpy.array([6376.0, 7564.0, 4179.0, 7564.0, 4199.0, ''], dtype=object)) assert numpy.array_equal(q['chosen but not available'].values, [942.0, 0.0, 0.0, 0.0, 0.0, 942.0])
def test_doctor_before_load_data(): with raises(ValueError): larch.Model().doctor()
def test_latent_class(swissmetro_raw_df): dfs = larch.DataFrames(swissmetro_raw_df, alt_codes=[1, 2, 3]) m1 = larch.Model(dataservice=dfs) m1.availability_co_vars = { 1: "TRAIN_AV_SP", 2: "SM_AV", 3: "CAR_AV_SP", } m1.choice_co_code = 'CHOICE' m1.utility_co[1] = P("ASC_TRAIN") + X("TRAIN_CO*(GA==0)") * P("B_COST") m1.utility_co[2] = X("SM_CO*(GA==0)") * P("B_COST") m1.utility_co[3] = P("ASC_CAR") + X("CAR_CO") * P("B_COST") m2 = larch.Model(dataservice=dfs) m2.availability_co_vars = { 1: "TRAIN_AV_SP", 2: "SM_AV", 3: "CAR_AV_SP", } m2.choice_co_code = 'CHOICE' m2.utility_co[1] = P("ASC_TRAIN") + X("TRAIN_TT") * P("B_TIME") + X( "TRAIN_CO*(GA==0)") * P("B_COST") m2.utility_co[ 2] = X("SM_TT") * P("B_TIME") + X("SM_CO*(GA==0)") * P("B_COST") m2.utility_co[3] = P( "ASC_CAR") + X("CAR_TT") * P("B_TIME") + X("CAR_CO") * P("B_COST") km = larch.Model() km.utility_co[2] = P.W_OTHER from larch.model.latentclass import LatentClassModel m = LatentClassModel(km, {1: m1, 2: m2}) m.load_data() m.set_value(P.ASC_CAR, 0.125 / 2) m.set_value(P.ASC_TRAIN, -0.398 / 2) m.set_value(P.B_COST, -.0126 / 2) m.set_value(P.B_TIME, -0.028 / 2) m.set_value(P.W_OTHER, 1.095 / 2) check1 = m.check_d_loglike() assert dict(check1.data.analytic) == approx({ 'ASC_CAR': -81.69736186616234, 'ASC_TRAIN': -613.131371089499, 'B_COST': -6697.31706964777, 'B_TIME': -40104.940072046316, 'W_OTHER': 245.43145056623683, }) assert check1.data.similarity.min() > 4 m.set_value(P.ASC_CAR, 0.125) m.set_value(P.ASC_TRAIN, -0.398) m.set_value(P.B_COST, -.0126) m.set_value(P.B_TIME, -0.028) m.set_value(P.W_OTHER, 1.095) assert m.loglike() == approx(-5208.502259337974) check2 = m.check_d_loglike() assert dict(check2.data.analytic) == approx({ 'ASC_CAR': 0.6243716033364302, 'ASC_TRAIN': 0.9297965389102578, 'B_COST': -154.03997923797007, 'B_TIME': 76.19297915128493, 'W_OTHER': -0.7936963902343083, }) assert check2.data.similarity.min( ) > 2 # similarity is a bit lower very close to the optimum
def test_pmath_in_utility(): d = larch.examples.MTC() m0 = larch.Model(dataservice=d) m0.utility_co[2] = P("ASC_SR2") * 10 + P("hhinc#2") / 10 * X("hhinc") m0.utility_co[3] = P("ASC_SR3P") * 10 + P("hhinc#3") / 10 * X("hhinc") m0.utility_co[4] = P("ASC_TRAN") * 10 + P("hhinc#4") / 10 * X("hhinc") m0.utility_co[5] = P("ASC_BIKE") * 10 + P("hhinc#5") / 10 * X("hhinc") m0.utility_co[6] = P("ASC_WALK") * 10 + P("hhinc#6") / 10 * X("hhinc") m0.utility_ca = ( +P("nonmotorized_time") / 10. * X("(altnum>4) * tottime") + P("motorized_ovtt") * 10 * X("(altnum <= 4) * ovtt") + P("motorized_ivtt") * X("(altnum <= 4) * ivtt") + PX("totcost")) m0.availability_var = '_avail_' m0.choice_ca_var = '_choice_' m1 = larch.Model(dataservice=d) m1.utility_co[2] = P("ASC_SR2") * X('10') + P("hhinc#2") * X("hhinc/10") m1.utility_co[3] = P("ASC_SR3P") * X('10') + P("hhinc#3") * X("hhinc/10") m1.utility_co[4] = P("ASC_TRAN") * X('10') + P("hhinc#4") * X("hhinc/10") m1.utility_co[5] = P("ASC_BIKE") * X('10') + P("hhinc#5") * X("hhinc/10") m1.utility_co[6] = P("ASC_WALK") * X('10') + P("hhinc#6") * X("hhinc/10") m1.utility_ca = (+P("nonmotorized_time") * X("(altnum>4) * tottime / 10") + P("motorized_ovtt") * X("(altnum <= 4) * ovtt * 10") + P("motorized_ivtt") * X("(altnum <= 4) * ivtt") + PX("totcost")) m1.availability_var = '_avail_' m1.choice_ca_var = '_choice_' m0.load_data() m1.load_data() r0 = m0.maximize_loglike(quiet=True) r1 = m1.maximize_loglike(quiet=True) assert r0.loglike == pytest.approx(-3587.6430040944942) assert r1.loglike == pytest.approx(-3587.6430040944942) m0.calculate_parameter_covariance() m1.calculate_parameter_covariance() t = { 'ASC_BIKE': -5.318650574990901, 'ASC_SR2': -22.291563439182628, 'ASC_SR3P': -22.174552606750527, 'ASC_TRAN': -3.293923857045225, 'ASC_WALK': 1.6172450189610719, 'hhinc#2': -1.4000897138949544, 'hhinc#3': 0.12900984170888324, 'hhinc#4': -3.0601742475362923, 'hhinc#5': -2.333410249527477, 'hhinc#6': -3.048442130390144, 'motorized_ivtt': -0.4116740527068954, 'motorized_ovtt': -12.958446214791113, 'nonmotorized_time': -11.789244777056298, 'totcost': -20.19350165272386, } assert dict(m0.pf['t_stat']) == pytest.approx(t, rel=1e-5) assert dict(m1.pf['t_stat']) == pytest.approx(t, rel=1e-5) assert (m0.get_value(P.motorized_ivtt) * 60) / ( m0.get_value(P.totcost) * 100) == pytest.approx(0.3191492801963062) assert m0.get_value((P.motorized_ivtt * 60) / (P.totcost * 100)) == pytest.approx(0.3191492801963062) assert (m1.get_value(P.motorized_ivtt) * 60) / ( m1.get_value(P.totcost) * 100) == pytest.approx(0.3191492801963062) assert m1.get_value((P.motorized_ivtt * 60) / (P.totcost * 100)) == pytest.approx(0.3191492801963062)
def test_pvalue(): m = larch.Model() m.utility_ca = P.Aaa * X.Aaa + P.Bbb * X.Bbb + P.Ccc m.set_values(Aaa=12, Bbb=20, Ccc=2) assert P.Aaa.value(m) == 12 assert P.Bbb.value(m) == 20 assert P.Ccc.value(m) == 2 with pytest.raises(KeyError): P.Ddd.value(m) assert P.Ddd.value(m, {'Ddd': 123}) == 123 y = P.Ddd / P.Bbb with pytest.raises(KeyError): m.pvalue(y, log_errors=False) assert m.pformat(y) == 'NA' y = P.Aaa + P.Bbb assert m.pvalue(y) == 12 + 20 assert m.pformat(y) == str(12 + 20) y = P.Aaa / P.Bbb assert m.pvalue(y) == 12 / 20 assert m.pformat(y) == "0.6" y = P.Aaa * 60 / (P.Bbb * 100) y.set_fmt("${:0.2f}/hr") assert m.pvalue(y) == 12 * 60 / (20 * 100) assert m.pformat(y) == '$0.36/hr' y = P.Aaa + P.Bbb / P.Ccc assert m.pvalue(y) == 12 + 20 / 2 assert m.pformat(y) == '22' y = (P.Aaa + P.Bbb) + P.Ccc * P.Aaa assert m.pvalue(y) == (12 + 20) + 2 * 12 assert m.pformat(y) == "{:.3g}".format((12 + 20) + 2 * 12) y = (P.Aaa + P.Bbb) + P.Ccc / P.Aaa assert m.pvalue(y) == (12 + 20) + 2 / 12 assert m.pformat(y) == "{:.3g}".format((12 + 20) + 2 / 12) y = (P.Aaa + P.Bbb + P.Ccc) * P.Aaa assert m.pvalue(y) == (12 + 20 + 2) * 12 assert m.pformat(y) == "{:.3g}".format((12 + 20 + 2) * 12) y = (P.Aaa + P.Bbb + P.Ccc) / P.Aaa assert m.pvalue(y) == (12 + 20 + 2) / 12 assert m.pformat(y) == "{:.3g}".format((12 + 20 + 2) / 12) y = (P.Aaa + P.Bbb + P.Ccc) - P.Aaa assert m.pvalue(y) == 12 + 20 + 2 - 12 assert m.pformat(y) == "{:.3g}".format(12 + 20 + 2 - 12) y = (P.Aaa + P.Bbb * 2) + P.Ccc * P.Aaa assert m.pvalue(y) == (12 + 20 * 2) + 2 * 12 assert m.pformat(y) == "{:.3g}".format((12 + 20 * 2) + 2 * 12) y = (P.Aaa + P.Bbb) + P.Ccc / P.Aaa * 3 assert m.pvalue(y) == (12 + 20) + 2 / 12 * 3 assert m.pformat(y) == "{:.3g}".format((12 + 20) + 2 / 12 * 3) y = (P.Aaa + P.Bbb + P.Ccc) * P.Aaa * 3 assert m.pvalue(y) == (12 + 20 + 2) * 12 * 3 assert m.pformat(y) == "{:.3g}".format((12 + 20 + 2) * 12 * 3) y = (P.Aaa + P.Bbb + P.Ccc) / P.Aaa * 3 assert m.pvalue(y) == (12 + 20 + 2) / 12 * 3 assert m.pformat(y) == "{:.3g}".format((12 + 20 + 2) / 12 * 3) y = (P.Aaa + P.Bbb + P.Ccc) - P.Aaa * 3 assert m.pvalue(y) == 12 + 20 + 2 - 12 * 3 assert m.pformat(y) == "{:.3g}".format(12 + 20 + 2 - 12 * 3) y = (11 + P.Aaa + P.Bbb * 2) + P.Ccc * P.Aaa assert m.pvalue(y) == (11 + 12 + 20 * 2) + 2 * 12 assert m.pformat(y) == "{:.3g}".format((11 + 12 + 20 * 2) + 2 * 12) y = (11 + P.Aaa + P.Bbb) + P.Ccc / P.Aaa * 3 assert m.pvalue(y) == (11 + 12 + 20) + 2 / 12 * 3 assert m.pformat(y) == "{:.3g}".format((11 + 12 + 20) + 2 / 12 * 3) y = (11 + P.Aaa + P.Bbb + P.Ccc) * P.Aaa * 3 assert m.pvalue(y) == (11 + 12 + 20 + 2) * 12 * 3 assert m.pformat(y) == "{:.3g}".format((11 + 12 + 20 + 2) * 12 * 3) y = (11 + P.Aaa + P.Bbb + P.Ccc) / P.Aaa * 3 assert m.pvalue(y) == (11 + 12 + 20 + 2) / 12 * 3 assert m.pformat(y) == "{:.3g}".format((11 + 12 + 20 + 2) / 12 * 3) y = (11 + P.Aaa + P.Bbb + P.Ccc) - P.Aaa * 3 assert m.pvalue(y) == 11 + 12 + 20 + 2 - 12 * 3 assert m.pformat(y) == "{:.3g}".format(11 + 12 + 20 + 2 - 12 * 3) with pytest.raises(NotImplementedError): P.Aaa * 10 + P.Bbb / 10 * X.Yyy + 2 y = P.Aaa * 10 + P.Bbb / 10 + 2 assert m.pvalue(y) == 12 * 10 + 20 / 10 + 2 assert m.pformat(y) == "{:.3g}".format(12 * 10 + 20 / 10 + 2) with pytest.raises(Exception): m.utility_ca = P.Aaa + P.Ccc + 5 yd = { 'Yxx': P.Aaa + P.Bbb / P.Ccc, 'Yyy': P.Aaa + P.Bbb, 'Yzz': P.Aaa * 60 / (P.Bbb * 100), } assert m.pvalue(yd) == { 'Yxx': 12 + 20 / 2, 'Yyy': 12 + 20, 'Yzz': 12 * 60 / (20 * 100), } assert m.pformat(yd) == { 'Yxx': "{:.3g}".format(12 + 20 / 2), 'Yyy': "{:.3g}".format(12 + 20), 'Yzz': "{:.3g}".format(12 * 60 / (20 * 100)), }
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)
# For clarity, we can define numbers as names for modes DA = 1 SR = 2 Walk = 3 Bike = 4 Transit = 5 dfs = larch.DataFrames( co=df, alt_codes=[DA,SR,Walk,Bike,Transit], alt_names=['DA','SR','Walk','Bike','Transit'], ch_name='TOURMODE', ) # Model Definition m = larch.Model(dataservice=dfs) m.title = "Exampville Work Tour Mode Choice v1" from larch import P, X P('NamedParameter') X.NamedDataValue P('Named Parameter') X("log(INCOME)") P.InVehTime * X.AUTO_TIME + P.Cost * X.AUTO_COST m.utility_co[DA] = ( + P.InVehTime * X.AUTO_TIME + P.Cost * X.AUTO_COST # dollars per mile )