17A: MTC MNL Mode Choice, Segmented for 1 or fewer cars

Market segmentation can be used to determine whether the impact of other variables is different among population groups. The most common approach to market segmentation is for the analyst to consider sample segments which are mutually exclusive and collectively exhaustive (that is, each case is included in one and only one segment). Models are estimated for the sample associated with each segment and compared to the pooled model (all segments represented by a single model) to determine if there are statistically significant and important differences among the market segments.

Model 17A segments the market by automobile ownership for households that have one or fewer cars. It is appealing to include a distinct segment for households with no cars since the mode choice behavior of this segment is very different from the rest of the population due to their dependence on non-automobile modes. However, the size of this segment in the dataset is too small, so it is joined with the one car group. (pp. 129-133)

d = larch.examples.MTC()
m = larch.Model(dataservice=d)

m.dataservice.selector = "numveh <= 1"
m.availability_var = '_avail_'
m.choice_ca_var = '_choice_'
from larch.roles import P, X, PX
m.utility_ca = (
        + P("costbyincome") * X("totcost/hhinc")
        + P("motorized_time") * X("(altnum <= 4) * tottime")
        + P("nonmotorized_time") * X("(altnum > 4) * tottime")
        + P("motorized_ovtbydist") * X("(altnum <=4) * ovtt/dist")
        )
for a in [4,5,6]:
        m.utility_co[a] = P("hhinc#{}".format(a)) * X("hhinc")

for a,name in m.dataservice.alternatives[1:3]:
        m.utility_co[a] += (
                + P("vehbywrk_SR") * X("vehbywrk")
                + P("wkcbd_"+name) * X("wkccbd+wknccbd")
                + P("wkempden"+name) * X("wkempden")
                + P("ASC_"+name)
                )

for a,name in m.dataservice.alternatives[3:]:
        m.utility_co[a] += (
                + P("vehbywrk_"+name) * X("vehbywrk")
                + P("wkcbd_"+name) * X("wkccbd + wknccbd")
                + P("wkempden"+name) * X("wkempden")
                + P("ASC_"+name)
                )
m.ordering = (
        ("CostbyInc","costbyincome",),
        ("TravelTime",".*time.*",".*dist.*", ),
        ("Household","hhinc.*","vehbywrk.*", ),
        ("Zonal","wkcbd.*","wkempden.*", ),
        ("ASCs","ASC.*", ),
)
>>> m.load_data()
>>> m.maximize_loglike()
┣ ...Optimization terminated successfully...
>>> m.calculate_parameter_covariance()
>>> m.loglike()
-1049.279...

>>> print(m.pfo()[['value','std err','t stat','robust std err','robust t stat']])
                                 value  std err   t stat  robust std err  robust t stat
Category   Parameter
CostbyInc  costbyincome        -0.0227   0.0138  -1.6408          0.0172        -1.3178
TravelTime motorized_time      -0.0211   0.0060  -3.4888          0.0063        -3.3546
           nonmotorized_time   -0.0440   0.0081  -5.4261          0.0086        -5.1318
           motorized_ovtbydist -0.1131   0.0260  -4.3588          0.0355        -3.1862
Household  hhinc#4             -0.0064   0.0036  -1.8066          0.0036        -1.7838
           hhinc#5             -0.0116   0.0095  -1.2272          0.0086        -1.3496
           hhinc#6             -0.0120   0.0060  -2.0084          0.0057        -2.1147
           vehbywrk_BIKE       -2.6641   0.6620  -4.0240          0.6861        -3.8831
           vehbywrk_SR         -3.0145   0.3488  -8.6438          0.3532        -8.5357
           vehbywrk_TRANSIT    -3.9632   0.3758 -10.5458          0.3829       -10.3497
           vehbywrk_WALK       -3.3420   0.4446  -7.5166          0.4800        -6.9621
Zonal      wkcbd_BIKE           0.3958   0.5370   0.7371          0.5601         0.7067
           wkcbd_SR2            0.3724   0.2410   1.5454          0.2383         1.5627
           wkcbd_SR3            0.2294   0.4065   0.5644          0.4235         0.5418
           wkcbd_TRANSIT        1.1065   0.2593   4.2667          0.2541         4.3548
           wkcbd_WALK           0.0297   0.3505   0.0847          0.3646         0.0814
           wkempdenBIKE         0.0015   0.0019   0.8015          0.0018         0.8151
           wkempdenSR2          0.0020   0.0007   2.8046          0.0008         2.5928
           wkempdenSR3          0.0035   0.0009   3.8880          0.0010         3.4788
           wkempdenTRANSIT      0.0032   0.0007   4.7292          0.0008         4.1510
           wkempdenWALK         0.0038   0.0010   3.9143          0.0010         3.8821
ASCs       ASC_BIKE             0.9765   0.7023   1.3905          0.7043         1.3865
           ASC_SR2              0.5929   0.3025   1.9596          0.3187         1.8600
           ASC_SR3             -0.7852   0.3538  -2.2196          0.3660        -2.1452
           ASC_TRANSIT          2.2579   0.4442   5.0835          0.4932         4.5781
           ASC_WALK             2.9070   0.5621   5.1715          0.6133         4.7402