diff --git a/CHANGELOG.md b/CHANGELOG.md index 0fd22e4..026f9d5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## 0.2 (not yet released) +#### 0.2.dev7 (2019-07-15) + +- fixes a bug with the `out_transform` parameter for `OLSRegressionStep` + #### 0.2.dev6 (2019-04-04) - introduces classes for storing common settings: `shared.CoreTemplateSettings`, `shared.OutputColumnSettings` @@ -39,6 +43,11 @@ - adds support for `autorun` template property +## 0.1.3 (2019-07-15) + +- patch to incorporate the `out_transform` bug fix for `OLSRegressionStep`, from 0.2.dev7 + + ## 0.1.2 (2019-02-28) - patch to incorporate the small MNL bug fix from 0.2.dev1 diff --git a/docs/source/index.rst b/docs/source/index.rst index 10451ec..4f888e6 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -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 `__ task orchestrator. ModelManager can register template-based model steps with the orchestrator, save them to disk, and automatically reload them for future sessions. -v0.2.dev6, released April 4, 2019 +v0.2.dev7, released July 22, 2019 Contents diff --git a/setup.py b/setup.py index e9e99af..511b093 100644 --- a/setup.py +++ b/setup.py @@ -6,7 +6,7 @@ setup( name='urbansim_templates', - version='0.2.dev6', + version='0.2.dev7', description='UrbanSim extension for managing model steps', author='UrbanSim Inc.', author_email='info@urbansim.com', diff --git a/tests/test_regression.py b/tests/test_regression.py index 1220395..cd6ea23 100644 --- a/tests/test_regression.py +++ b/tests/test_regression.py @@ -64,3 +64,24 @@ def test_simulation(orca_session): assert orca.get_table('obs').to_frame()['a_predicted'].equals(m.predicted_values) + +def test_out_transform(orca_session): + """ + Test transformation of the predicted values. + + """ + modelmanager.initialize() + + m = OLSRegressionStep() + m.tables = 'obs' + m.model_expression = 'a ~ b' + m.fit() + + m.out_column = 'a_predicted' + m.out_transform = 'np.exp' + m.run() + + predictions = m.predicted_values.apply(np.exp) + + assert orca.get_table('obs').to_frame()['a_predicted'].equals(predictions) + diff --git a/urbansim_templates/__init__.py b/urbansim_templates/__init__.py index 8157a0e..baa94ae 100644 --- a/urbansim_templates/__init__.py +++ b/urbansim_templates/__init__.py @@ -1 +1 @@ -version = __version__ = '0.2.dev6' +version = __version__ = '0.2.dev7' diff --git a/urbansim_templates/models/regression.py b/urbansim_templates/models/regression.py index 7683498..9d6b843 100644 --- a/urbansim_templates/models/regression.py +++ b/urbansim_templates/models/regression.py @@ -1,5 +1,6 @@ from __future__ import print_function +import math import numpy as np import pandas as pd from datetime import datetime as dt @@ -69,10 +70,12 @@ class OLSRegressionStep(TemplateStep): side variable from the model expression will be used. Replaces the `out_fname` argument in UrbanSim. - out_transform : callable, optional - Transformation to apply to the predicted values, for example to reverse a - transformation of the left-hand-side variable in the model expression. Replaces - the `ytransform` argument in UrbanSim. + out_transform : str, optional + Element-wise transformation to apply to the predicted values, for example to + reverse a transformation of the left-hand-side variable in the model expression. + This should be provided as a string containing a function name. Supports anything + from NumPy or Python's built-in math library, for example 'np.exp' or + 'math.floor'. Replaces the `ytransform` argument in UrbanSim. out_filters : str or list of str, optional Filters to apply to the data before simulation. If not provided, no filters will @@ -168,7 +171,7 @@ def fit(self): """ self.model = RegressionModel(model_expression=self.model_expression, fit_filters=self.filters, predict_filters=self.out_filters, - ytransform=self.out_transform, name=self.name) + ytransform=None, name=self.name) df = get_data(tables = self.tables, filters = self.filters, @@ -207,7 +210,7 @@ def run(self): self.predicted_values = values if self.out_transform is not None: - values = self.out_transform(values) + values = values.apply(eval(self.out_transform)) colname = self._get_out_column() tabname = self._get_out_table()