Skip to content

Commit

Permalink
Merge pull request #99 from UDST/v1-patch
Browse files Browse the repository at this point in the history
[0.1.2] Small MNL patch
  • Loading branch information
smmaurer committed Feb 28, 2019
2 parents 167ffb2 + 6f430c6 commit 2c84db0
Show file tree
Hide file tree
Showing 7 changed files with 49 additions and 36 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# UrbanSim Templates change log

### 0.1.2 (2019-02-28)

- fixes a crash in small MNL simulation

### 0.1.1 (2019-02-05)

- production release
Expand Down
2 changes: 1 addition & 1 deletion docs/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ UrbanSim Templates provides building blocks for Orca-based simulation models. It

The library contains templates for common types of model steps, plus a tool called ModelManager that runs as an extension to the `Orca <https://udst.github.io/orca>`__ task orchestrator. ModelManager can register template-based model steps with the orchestrator, save them to disk, and automatically reload them for future sessions.

v0.1.1, released February 5, 2019
v0.1.2, released February 28, 2019


Contents
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

setup(
name='urbansim_templates',
version='0.1.1',
version='0.1.2',
description='UrbanSim extension for managing model steps',
author='UrbanSim Inc.',
author_email='info@urbansim.com',
Expand Down
26 changes: 21 additions & 5 deletions tests/test_small_multinomial_logit.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,22 @@

@pytest.fixture
def orca_session():
d1 = {'a': np.random.random(100),
'b': np.random.random(100),
d1 = {'id': np.arange(100),
'building_id': np.arange(100),
'a': np.random.random(100),
'choice': np.random.randint(3, size=100)}

d2 = {'building_id': np.arange(100),
'b': np.random.random(100)}

households = pd.DataFrame(d1).set_index('id')
orca.add_table('households', households)

buildings = pd.DataFrame(d2).set_index('building_id')
orca.add_table('buildings', buildings)

obs = pd.DataFrame(d1)
orca.add_table('obs', obs)
orca.broadcast(cast='buildings', onto='households',
cast_index=True, onto_on='building_id')


def test_template_validity():
Expand All @@ -35,7 +45,7 @@ def test_small_mnl(orca_session):
modelmanager.initialize()

m = SmallMultinomialLogitStep()
m.tables = 'obs'
m.tables = ['households', 'buildings']
m.choice_column = 'choice'
m.model_expression = OrderedDict([
('intercept', [1,2]), ('a', [0,2]), ('b', [0,2])])
Expand All @@ -51,6 +61,12 @@ def test_small_mnl(orca_session):

print(m.model_expression)

# TEST SIMULATION
m.out_column = 'simulated_choice'

m.run()
print(orca.get_table('households').to_frame())

modelmanager.initialize()
m = modelmanager.get_step('small-mnl-test')
assert(m.model_expression is not None)
Expand Down
2 changes: 1 addition & 1 deletion urbansim_templates/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
version = __version__ = '0.1.1'
version = __version__ = '0.1.2'
20 changes: 0 additions & 20 deletions urbansim_templates/models/shared.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,16 +168,6 @@ def _get_data(self, task='fit'):
if isinstance(self.model_expression, str):
expr_cols = util.columns_in_formula(self.model_expression)

# This is for PyLogit model expressions
elif isinstance(self.model_expression, OrderedDict):
# TO DO - check that this works in Python 2.7
expr_cols = [t[0] for t in list(self.model_expression.items()) \
if t[0] != 'intercept']
# TO DO - not very general, maybe we should just override the method
# TO DO - and this only applies to the fit condition
if self.choice_column is not None:
expr_cols += [self.choice_column]

if (task == 'fit'):
tables = self.tables
columns = expr_cols + util.columns_in_filters(self.filters)
Expand All @@ -204,16 +194,6 @@ def _get_data(self, task='fit'):
return df


def _get_filter_columns(self):
"""
THIS METHOD DOES NOT WORK YET.
Return list of column names referenced in the filters.
"""
return


def _get_out_column(self):
"""
Return name of the column to save data to. This is 'out_column' if it exsits,
Expand Down
29 changes: 21 additions & 8 deletions urbansim_templates/models/small_multinomial_logit.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@
from choicemodels import MultinomialLogit
import orca

from ..utils import update_column
from .. import modelmanager
from .shared import TemplateStep
from urbansim_templates import modelmanager
from urbansim_templates.models import TemplateStep
from urbansim_templates.utils import get_data, update_column


@modelmanager.template
Expand Down Expand Up @@ -87,8 +87,6 @@ class SmallMultinomialLogitStep(TemplateStep):
in the primary output table, it will be created. If not provided, the
`choice_column` will be used. Replaces the `out_fname` argument in UrbanSim.
# TO DO - auto-generation not yet working; column must exist in the primary table
out_filters : str or list of str, optional
Filters to apply to the data before simulation. If not provided, no filters will
be applied. Replaces the `predict_filters` argument in UrbanSim.
Expand Down Expand Up @@ -312,14 +310,22 @@ def fit(self):
with Orca or ModelManager until the `register()` method is run.
"""
long_df = self._to_long(self._get_data())
expr_cols = [t[0] for t in list(self.model_expression.items()) \
if t[0] != 'intercept']

df = get_data(tables = self.tables,
filters = self.filters,
extra_columns = expr_cols + [self.choice_column])

long_df = self._to_long(df)

# Set initial coefs to 0 if none provided
pc = self._get_param_count()
if (self.initial_coefs is None) or (len(self.initial_coefs) != pc):
self.initial_coefs = np.zeros(pc).tolist()

model = MultinomialLogit(data=long_df, observation_id_col='_obs_id',
model = MultinomialLogit(data=long_df,
observation_id_col='_obs_id',
choice_col='_chosen',
model_expression=self.model_expression,
model_labels=self.model_labels,
Expand Down Expand Up @@ -352,7 +358,14 @@ def run(self):
model step.
"""
df = self._get_data('predict')
expr_cols = [t[0] for t in list(self.model_expression.items()) \
if t[0] != 'intercept']

df = get_data(tables = self.out_tables,
fallback_tables = self.tables,
filters = self.out_filters,
extra_columns = expr_cols)

long_df = self._to_long(df, 'predict')

num_obs = len(df)
Expand Down

0 comments on commit 2c84db0

Please sign in to comment.