Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BayDAG Contribution #7: Sampling in EDB for Location Choice #773

Merged
merged 3 commits into from
Mar 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 40 additions & 6 deletions activitysim/abm/models/location_choice.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,15 +141,17 @@ def _location_sample(

sample_size = model_settings.SAMPLE_SIZE

if state.settings.disable_destination_sampling or (
estimator and estimator.want_unsampled_alternatives
):
# FIXME interaction_sample will return unsampled complete alternatives with probs and pick_count
if estimator:
sample_size = model_settings.ESTIMATION_SAMPLE_SIZE
logger.info(
"Estimation mode for %s using unsampled alternatives short_circuit_choices"
% (trace_label,)
f"Estimation mode for {trace_label} using sample size of {sample_size}"
)

if state.settings.disable_destination_sampling:
sample_size = 0
logger.info(
f"SAMPLE_SIZE set to 0 for {trace_label} because disable_destination_sampling is set"
)

locals_d = {
"skims": skims,
Expand Down Expand Up @@ -484,6 +486,38 @@ def run_location_sample(
trace_label=trace_label,
)

# adding observed choice to alt set when running in estimation mode
if estimator:
# grabbing survey values
survey_persons = estimation.manager.get_survey_table("persons")
if "school_location" in trace_label:
survey_choices = survey_persons["school_zone_id"].reset_index()
elif ("workplace_location" in trace_label) and ("external" not in trace_label):
survey_choices = survey_persons["workplace_zone_id"].reset_index()
else:
return choices
survey_choices.columns = ["person_id", "alt_dest"]
survey_choices = survey_choices[
survey_choices["person_id"].isin(choices.index)
& (survey_choices.alt_dest > 0)
]
# merging survey destination into table if not available
joined_data = survey_choices.merge(
choices, on=["person_id", "alt_dest"], how="left", indicator=True
)
missing_rows = joined_data[joined_data["_merge"] == "left_only"]
missing_rows["pick_count"] = 1
if len(missing_rows) > 0:
new_choices = missing_rows[
["person_id", "alt_dest", "prob", "pick_count"]
].set_index("person_id")
choices = choices.append(new_choices, ignore_index=False).sort_index()
# making probability the mean of all other sampled destinations by person
# FIXME is there a better way to do this? Does this even matter for estimation?
choices["prob"] = choices["prob"].fillna(
choices.groupby("person_id")["prob"].transform("mean")
)

return choices


Expand Down
9 changes: 9 additions & 0 deletions activitysim/core/configuration/logit.py
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,15 @@ class TourLocationComponentSettings(LocationComponentSettings, extra="forbid"):
ORIG_ZONE_ID: str | None = None
"""This setting appears to do nothing..."""

ESTIMATION_SAMPLE_SIZE: int = 0
"""
The number of alternatives to sample for estimation mode.
If zero, then all alternatives are used.
Truth alternative will be included in the sample.
Larch does not yet support sampling alternatives for estimation,
but this setting is still helpful for estimation mode runtime.
"""


class TourModeComponentSettings(TemplatedLogitComponentSettings, extra="forbid"):
MODE_CHOICE_LOGSUM_COLUMN_NAME: str | None = None
Expand Down
Loading