def _sample_characteristic(states_df, options, level_dict, use_keys): """Sample characteristic of individuals. The function is used to sample the values of one state space characteristic, say experience. The keys of ``level_dict`` are the possible starting values of experience. The values of the dictionary are :class:`pandas.Series` whose index are covariate names and the values are the parameter values. ``states_df`` is used to generate all possible covariates with the existing information. For each level, the dot product of parameters and covariates determines the value ``z``. The softmax function converts the level-specific ``z``-values to probabilities. The probabilities are used to sample the characteristic. Parameters ---------- states_df : pandas.DataFrame Contains the state of each individual. options : dict Options of the model. level_dict : dict A dictionary where the keys are the values distributed according to the probability mass function. The values are a :class:`pandas.Series` with covariate names as the index and parameter values. use_keys : bool Identifier for whether the keys of the level dict should be used as variables values or use numeric codes instead. For example, assign numbers to choices. Returns ------- characteristic : numpy.ndarray Array with shape (n_individuals,) containing sampled values. """ # Generate covariates. all_data = compute_covariates(states_df, options["covariates_all"], check_nans=True, raise_errors=False) # Calculate dot product of covariates and parameters. z = () for level in level_dict: x_beta = pandas_dot(all_data, level_dict[level]) z += (x_beta, ) # Calculate probabilities with the softmax function. probabilities = softmax(np.column_stack(z), axis=1) np.random.seed(next(options["simulation_seed_iteration"])) choices = level_dict if use_keys else len(level_dict) characteristic = _random_choice(choices, probabilities) return characteristic
def _create_choice_rewards(states, choice_set, optim_paras): """Create wage and non-pecuniary reward for each state and choice.""" n_choices = sum(choice_set) choices = select_valid_choices(optim_paras["choices"], choice_set) n_states = states.shape[0] wages = np.ones((n_states, n_choices)) nonpecs = np.zeros((n_states, n_choices)) for i, choice in enumerate(choices): if f"wage_{choice}" in optim_paras: log_wage = pandas_dot(states, optim_paras[f"wage_{choice}"]) wages[:, i] = np.exp(log_wage) if f"nonpec_{choice}" in optim_paras: nonpecs[:, i] = pandas_dot(states, optim_paras[f"nonpec_{choice}"]) return wages, nonpecs
def compute_transition_probabilities( states, transit_keys, optim_paras, dense_key_to_dense_covariates ): """Get transition probabilities by dense_key. We calculate transition probabilities for one dense key in this function. Therefore we retrieve probabilities for individuals and combine them to get a full transition matrix. Returns ------- df : pandas.core.DataFrame Rows represent states within a dense key and columns potential dense states in the next period. """ exogenous_processes = optim_paras["exogenous_processes"] dense_key_to_exogenous = { key: get_exogenous_from_dense_covariates( dense_key_to_dense_covariates[key], optim_paras ) for key in transit_keys } # Compute the probabilities for every exogenous process. probabilities = [] for exog_proc in exogenous_processes: # Create the dot product of covariates and parameters. x_betas = [ pandas_dot(states[params.index], params) for params in exogenous_processes[exog_proc].values() ] probs = special.softmax(np.column_stack(x_betas), axis=1) probabilities.append(probs) # Prepare full Dataframe. If issues arrise we might want to switch typed dicts df = pd.DataFrame(index=states.index) for dense in dense_key_to_exogenous: array = functools.reduce( np.multiply, [ probabilities[proc][:, val] for proc, val in enumerate(dense_key_to_exogenous[dense]) ], ) df[str(dense)] = array return df
def _compute_x_beta_for_type_probabilities(df, optim_paras, options): """Compute the vector dot product of type covariates and type coefficients. For each individual, compute as many vector dot products as there are types. The scalars are later passed to a softmax function to compute the type probabilities. The probability for each individual to be some type. """ for type_ in range(optim_paras["n_types"]): first_observations = df.copy().assign(type=type_) relevant_covariates = identify_necessary_covariates( optim_paras["type_prob"][type_].index, options["covariates_all"]) first_observations = compute_covariates(first_observations, relevant_covariates) df[type_] = pandas_dot(first_observations, optim_paras["type_prob"][type_]) return df[range(optim_paras["n_types"])]