Skip to content

Commit

Permalink
Whitespace fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
sean-wallace committed Aug 30, 2023
1 parent 791b1cc commit 8c704ed
Show file tree
Hide file tree
Showing 5 changed files with 272 additions and 272 deletions.
82 changes: 41 additions & 41 deletions choicemodels/mnl.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,8 @@ class MultinomialLogit(object):
https://github.com/timothyb0912/pylogit/blob/master/pylogit/pylogit.py#L116-L130
observation_id_col : str, optional
Name of column or index containing the observation id. This should uniquely
identify each distinct choice scenario. Not required if data is passed as a
Name of column or index containing the observation id. This should uniquely
identify each distinct choice scenario. Not required if data is passed as a
MergedChoiceTable.
choice_col : str, optional
Expand All @@ -114,8 +114,8 @@ class MultinomialLogit(object):
https://github.com/timothyb0912/pylogit/blob/master/pylogit/pylogit.py#L151-L165
alternative_id_col : str, optional
Name of column or index containing the alternative id. This is only required if
the model expression varies for different alternatives. Not required if data is
Name of column or index containing the alternative id. This is only required if
the model expression varies for different alternatives. Not required if data is
passed as a MergedChoiceTable.
initial_coefs : numeric or list-like of numerics, optional
Expand Down Expand Up @@ -144,10 +144,10 @@ def __init__(self, data, model_expression, observation_id_col=None, choice_col=N
self._observation_id_col = self._data.observation_id_col
self._alternative_id_col = self._data.alternative_id_col
self._choice_col = self._data.choice_col

else:
self._df = self._data

if isinstance(self._model_expression, OrderedDict):
self._estimation_engine = 'PyLogit'

Expand All @@ -170,7 +170,7 @@ def __init__(self, data, model_expression, observation_id_col=None, choice_col=N

return


def fit(self):
"""
Fit the model using maximum likelihood estimation. Uses either the ChoiceModels
Expand Down Expand Up @@ -229,7 +229,7 @@ class MultinomialLogitResults(object):
"""
The results class represents a fitted model. It can report the model fit, generate
choice probabilties, etc.
A full-featured results object is returned by MultinomialLogit.fit(). A results object
with more limited functionality can also be built directly from fitted parameters and
a model expression.
Expand All @@ -238,7 +238,7 @@ class MultinomialLogitResults(object):
----------
model_expression : str or OrderedDict
Patsy 'formula-like' (str) or PyLogit 'specification' (OrderedDict).
results : dict or object, optional
Raw results as currently provided by the estimation engine. This should be
replaced with a more consistent and comprehensive set of inputs.
Expand All @@ -250,9 +250,9 @@ class MultinomialLogitResults(object):
'ChoiceModels' (default) or 'PyLogit'.
"""
def __init__(self, model_expression, results=None, fitted_parameters=None,
def __init__(self, model_expression, results=None, fitted_parameters=None,
estimation_engine='ChoiceModels'):

if (fitted_parameters is None) & (results is not None):
if (estimation_engine == 'ChoiceModels'):
fitted_parameters = results['fit_parameters']['Coefficient'].tolist()
Expand All @@ -261,76 +261,76 @@ def __init__(self, model_expression, results=None, fitted_parameters=None,
self.model_expression = model_expression
self.results = results
self.fitted_parameters = fitted_parameters


def __repr__(self):
return self.report_fit()


def __str__(self):
return self.report_fit()


def get_raw_results(self):
"""
Return the raw results as provided by the estimation engine. Dict or object.
"""
return self.results


def probabilities(self, data):
"""
Generate predicted probabilities for a table of choice scenarios, using the fitted
parameters stored in the results object.
Parameters
----------
data : choicemodels.tools.MergedChoiceTable
Long-format table of choice scenarios. TO DO - accept other data formats.
Expected class parameters
-------------------------
self.model_expression : patsy string
self.fitted_parameters : list of floats
Returns
-------
pandas.Series with indexes matching the input
"""
# TO DO - make sure this handles pylogit case

# TO DO - does MergedChoiceTable guarantee that alternatives for a single scenario
# are consecutive? seems like a requirement here; should document it

df = data.to_frame()
numalts = data.sample_size # TO DO - make this an official MCT param

dm = dmatrix(self.model_expression, data=df)

# utility is sum of data values times fitted betas
u = np.dot(self.fitted_parameters, np.transpose(dm))

# reshape so axis 0 lists alternatives and axis 1 lists choosers
u = np.reshape(u, (numalts, u.size // numalts), order='F')

# scale the utilities to make exponentiation easier
# https://stats.stackexchange.com/questions/304758/softmax-overflow
u = u - u.max(axis=0)

exponentiated_utility = np.exp(u)
sum_exponentiated_utility = np.sum(exponentiated_utility, axis=0)

probs = exponentiated_utility / sum_exponentiated_utility

# convert back to ordering of the input data
probs = probs.flatten(order='F')

df['prob'] = probs # adds indexes
return df.prob


def report_fit(self):
"""
Print a report of the model estimation results.
Expand Down Expand Up @@ -617,15 +617,15 @@ def mnl_estimate(data, chosen, numalts, GPU=False, coeffrange=(None, None),
log_likelihood : dict
Dictionary of log-likelihood values describing the quality of
the model fit. The following keys is entered into `log_likelihood`.
aic : float
Akaike information criterion for an estimated model.
aic = -2 * log_likelihood + 2 * num_estimated_parameters
Akaike information criterion for an estimated model.
aic = -2 * log_likelihood + 2 * num_estimated_parameters
bic : float
Bayesian information criterion for an estimated model.
Bayesian information criterion for an estimated model.
bic = -2 * log_likelihood + log(num_observations) * num_parameters
num_obs : int
Number of observations in the model.
Expand All @@ -637,12 +637,12 @@ def mnl_estimate(data, chosen, numalts, GPU=False, coeffrange=(None, None),
llnull : float
Value of the constant-only loglikelihood
ll : float
Value of the loglikelihood
rho_squared : float
McFadden's pseudo-R-squared.
McFadden's pseudo-R-squared.
rho_squared = 1.0 - final_log_likelihood / null_log_likelihood
rho_bar_squared : float
Expand Down Expand Up @@ -696,7 +696,7 @@ def mnl_estimate(data, chosen, numalts, GPU=False, coeffrange=(None, None),

if bfgs_result[2]['warnflag'] > 0:
logger.warning("mnl did not converge correctly: %s", bfgs_result)

beta = bfgs_result[0]
stderr = mnl_loglik(
beta, data, chosen, numalts, weights, stderr=1, lcgrad=lcgrad)
Expand Down
2 changes: 1 addition & 1 deletion choicemodels/tools/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@

from .distancematrix import *
from .mergedchoicetable import *
from .simulation import *
from .simulation import *
Loading

0 comments on commit 8c704ed

Please sign in to comment.