def individual_utilities( persons, cdap_indiv_spec, locals_d, trace_hh_id=None, trace_label=None): """ Calculate CDAP utilities for all individuals. Parameters ---------- persons : pandas.DataFrame DataFrame of individual persons data. cdap_indiv_spec : pandas.DataFrame CDAP spec applied to individuals. Returns ------- utilities : pandas.DataFrame Will have index of `persons` and columns for each of the alternatives. plus some 'useful columns' [_hh_id_, _ptype_, 'cdap_rank', _hh_size_] """ # calculate single person utilities indiv_utils = simulate.eval_utilities(cdap_indiv_spec, persons, locals_d, trace_label=trace_label) # add columns from persons to facilitate building household interactions useful_columns = [_hh_id_, _ptype_, 'cdap_rank', _hh_size_] indiv_utils[useful_columns] = persons[useful_columns] if trace_hh_id: tracing.trace_df(indiv_utils, '%s.indiv_utils' % trace_label, column_labels=['activity', 'person']) return indiv_utils
def individual_utilities( persons, cdap_indiv_spec, locals_d, trace_hh_id=None, trace_label=None): """ Calculate CDAP utilities for all individuals. Parameters ---------- persons : pandas.DataFrame DataFrame of individual persons data. cdap_indiv_spec : pandas.DataFrame CDAP spec applied to individuals. Returns ------- utilities : pandas.DataFrame Will have index of `persons` and columns for each of the alternatives. plus some 'useful columns' [_hh_id_, _ptype_, 'cdap_rank', _hh_size_] """ # calculate single person utilities indiv_utils = simulate.eval_utilities(cdap_indiv_spec, persons, locals_d, trace_label) # add columns from persons to facilitate building household interactions useful_columns = [_hh_id_, _ptype_, 'cdap_rank', _hh_size_] indiv_utils[useful_columns] = persons[useful_columns] if trace_hh_id: tracing.trace_df(indiv_utils, '%s.indiv_utils' % trace_label, column_labels=['activity', 'person']) return indiv_utils
def compute_utilities(network_los, model_settings, choosers, model_constants, trace_label, trace=False, trace_column_names=None): """ Compute utilities """ with chunk.chunk_log(f'tvpb compute_utilities'): trace_label = tracing.extend_trace_label(trace_label, 'compute_utils') logger.debug( f"{trace_label} Running compute_utilities with {choosers.shape[0]} choosers" ) locals_dict = {'np': np, 'los': network_los} locals_dict.update(model_constants) # we don't grok coefficients, but allow them to use constants in spec alt columns spec = simulate.read_model_spec(file_name=model_settings['SPEC']) for c in spec.columns: if c != simulate.SPEC_LABEL_NAME: spec[c] = spec[c].map( lambda s: model_constants.get(s, s)).astype(float) with chunk.chunk_log(f'compute_utilities'): # - run preprocessor to annotate choosers preprocessor_settings = model_settings.get('PREPROCESSOR') if preprocessor_settings: # don't want to alter caller's dataframe choosers = choosers.copy() expressions.assign_columns( df=choosers, model_settings=preprocessor_settings, locals_dict=locals_dict, trace_label=trace_label) utilities = simulate.eval_utilities( spec, choosers, locals_d=locals_dict, trace_all_rows=trace, trace_label=trace_label, trace_column_names=trace_column_names) return utilities
def household_activity_choices(indiv_utils, interaction_coefficients, hhsize, trace_hh_id=None, trace_label=None): """ Calculate household utilities for each activity pattern alternative for households of hhsize The resulting activity pattern for each household will be coded as a string of activity codes. e.g. 'MNHH' for a 4 person household with activities Mandatory, NonMandatory, Home, Home Parameters ---------- indiv_utils : pandas.DataFrame CDAP utilities for each individual, ignoring interactions ind_utils has index of _persons_index_ and a column for each alternative i.e. three columns 'M' (Mandatory), 'N' (NonMandatory), 'H' (Home) interaction_coefficients : pandas.DataFrame Rules and coefficients for generating interaction specs for different household sizes hhsize : int the size of household for which activity perttern should be calculated (1..MAX_HHSIZE) Returns ------- choices : pandas.Series the chosen cdap activity pattern for each household represented as a string (e.g. 'MNH') with same index (_hh_index_) as utils """ if hhsize == 1: # for 1 person households, there are no interactions to account for # and the household utils are the same as the individual utils choosers = vars = None # extract the individual utilities for individuals from hhsize 1 households utils = indiv_utils.loc[indiv_utils[_hh_size_] == 1, [_hh_id_, 'M', 'N', 'H']] # index on household_id, not person_id set_hh_index(utils) else: choosers = hh_choosers(indiv_utils, hhsize=hhsize) spec = build_cdap_spec(interaction_coefficients, hhsize, trace_spec=(trace_hh_id in choosers.index), trace_label=trace_label) utils = simulate.eval_utilities(spec, choosers, trace_label=trace_label) if len(utils.index) == 0: return pd.Series(dtype='float64') probs = logit.utils_to_probs(utils, trace_label=trace_label) # select an activity pattern alternative for each household based on probability # result is a series indexed on _hh_index_ with the (0 based) index of the column from probs idx_choices, rands = logit.make_choices(probs, trace_label=trace_label) # convert choice expressed as index into alternative name from util column label choices = pd.Series(utils.columns[idx_choices].values, index=utils.index) if trace_hh_id: if hhsize > 1: tracing.trace_df(choosers, '%s.hhsize%d_choosers' % (trace_label, hhsize), column_labels=['expression', 'person']) tracing.trace_df(utils, '%s.hhsize%d_utils' % (trace_label, hhsize), column_labels=['expression', 'household']) tracing.trace_df(probs, '%s.hhsize%d_probs' % (trace_label, hhsize), column_labels=['expression', 'household']) tracing.trace_df(choices, '%s.hhsize%d_activity_choices' % (trace_label, hhsize), column_labels=['expression', 'household']) tracing.trace_df(rands, '%s.hhsize%d_rands' % (trace_label, hhsize), columns=[None, 'rand']) return choices
def household_activity_choices(indiv_utils, interaction_coefficients, hhsize, trace_hh_id=None, trace_label=None): """ Calculate household utilities for each activity pattern alternative for households of hhsize The resulting activity pattern for each household will be coded as a string of activity codes. e.g. 'MNHH' for a 4 person household with activities Mandatory, NonMandatory, Home, Home Parameters ---------- indiv_utils : pandas.DataFrame CDAP utilities for each individual, ignoring interactions ind_utils has index of _persons_index_ and a column for each alternative i.e. three columns 'M' (Mandatory), 'N' (NonMandatory), 'H' (Home) interaction_coefficients : pandas.DataFrame Rules and coefficients for generating interaction specs for different household sizes hhsize : int the size of household for which activity perttern should be calculated (1..MAX_HHSIZE) Returns ------- choices : pandas.Series the chosen cdap activity pattern for each household represented as a string (e.g. 'MNH') with same index (_hh_index_) as utils """ if hhsize == 1: # for 1 person households, there are no interactions to account for # and the household utils are the same as the individual utils choosers = vars = None # extract the individual utilities for individuals from hhsize 1 households utils = indiv_utils.loc[indiv_utils[_hh_size_] == 1, [_hh_id_, 'M', 'N', 'H']] # index on household_id, not person_id set_hh_index(utils) else: choosers = hh_choosers(indiv_utils, hhsize=hhsize) spec = build_cdap_spec(interaction_coefficients, hhsize, trace_spec=(trace_hh_id in choosers.index), trace_label=trace_label) utils = simulate.eval_utilities(spec, choosers, trace_label=trace_label) if len(utils.index) == 0: return pd.Series() probs = logit.utils_to_probs(utils, trace_label=trace_label) # select an activity pattern alternative for each household based on probability # result is a series indexed on _hh_index_ with the (0 based) index of the column from probs idx_choices, rands = logit.make_choices(probs, trace_label=trace_label) # convert choice expressed as index into alternative name from util column label choices = pd.Series(utils.columns[idx_choices].values, index=utils.index) if trace_hh_id: if hhsize > 1: tracing.trace_df(choosers, '%s.hhsize%d_choosers' % (trace_label, hhsize), column_labels=['expression', 'person']) tracing.trace_df(utils, '%s.hhsize%d_utils' % (trace_label, hhsize), column_labels=['expression', 'household']) tracing.trace_df(probs, '%s.hhsize%d_probs' % (trace_label, hhsize), column_labels=['expression', 'household']) tracing.trace_df(choices, '%s.hhsize%d_activity_choices' % (trace_label, hhsize), column_labels=['expression', 'household']) tracing.trace_df(rands, '%s.hhsize%d_rands' % (trace_label, hhsize), columns=[None, 'rand']) return choices