[1]:
import emat
emat.versions()
emat 0.5.2, plotly 4.14.3
Interactive Explorer¶
TMIP-EMAT includes an interactive visualizer, inspired by a similar tool provided with the VisionEval package. To demonstrate the interactive visualizer, we will use the Road Test example model. First, we need to develop and run a design of experiments to have some data to explore. We’ll run 5,000 experiments to get a good size sample of data points to visualize.
[3]:
import emat.examples
scope, db, model = emat.examples.road_test()
design = model.design_experiments(n_samples=5000)
results = model.run_experiments(design)
One feature of the visualizer is the ability to display not only a number of results, but also to contrast those results against a given “reference” model that represents a more traditional single-point forecast of inputs and results. We’ll prepare a reference point here using the run_reference_experiment
method of the CoreModel
class, which reads the input parameter defaults (as defined in the scope), and returns both inputs and outputs in a DataFrame (essentially, an experimental
design with only a single experiment), suitable for use as the reference point marker in our visualizations.
[4]:
refpoint = model.run_reference_experiment()
The interactive visualizer class can be imported from the emat.analysis
package. To use it, we create an Visualizer
instance, giving a scope and a set of experimental results, as well as the reference point.
[5]:
from emat.analysis import Visualizer
/Users/jeffnewman/LocalGit/tmip-emat/emat/workbench/analysis/prim.py:30: ImportWarning:
altair based interactive inspection not available
[6]:
viz = Visualizer(scope=scope, data=results, reference_point=refpoint)
Single Dimension Figures¶
To build a complete interactive workspace similar to that provided by VisionEval, we can use the complete
method of the Visualizer
instance we created above. This will create a set of histograms illustrating the data in the results computed above. There is one histogram for each policy lever, exogenous uncertainty, and performance measure.
A range of data in each histogram can be selected by dragging horizonatally across the figure. For continuous parameters (i.e. float or integer valued parameters) you can select a single contiguous range by dragging across that range, and deselect by double clicking on the figure (or by selecting the entire possible range). For discrete parameters (i.e. boolean or categorical parameters, identifiable by the larger gaps between the bars in the figure) dragging across the center of any bar toggles whether that bar is selected or not. This allows non-contiguous selections in categories that have 3 or more possible values. Like the other figures, any selection can be cleared by double-clicking.
Selections can be made simultaneously over any combination of uncertainties, policy levers, and performance measures. The combination of controls offered can be used interactively to select and highlight only a subset of the experiments in the complete data set. By manipulating these controls, users can explore the interaction across various inputs and outputs.
[7]:
viz.complete()
It is also possible to display just a small subset of the figures of this interactive viewer. This could be convenient, for example, if there are a very large number of performance measures.
[8]:
viz.selectors(['input_flow', 'expand_capacity', 'net_benefits'])
In addition to manipulating the controls interactively, they can also be
set programatically from Python code. To do so, we can define a new emat.Box
that declares lower and/or upper bounds for any continuous dimensions,
as well as the set of allowed (included) value for any discrete dimensions,
and then add that new box to this visualizer using the Visualizer.add_box()
command.
[9]:
box = emat.Box("Passable", scope=scope)
box.set_upper_bound('cost_of_capacity_expansion', 400)
box.set_lower_bound('time_savings', 5)
box.remove_from_allowed_set('debt_type', 'GO Bond')
viz.add_box(box)
Alternatively, a new box can be created and added to the Visualier with a single :meth:Visualizer.new_box
command, which passes most keyword arguments through to the :class:emat.Box
constuctor.
[10]:
viz.new_box('Profitable', lower_bounds={'net_benefits':0});
Each of these new boxes is added to the Visualizer
seperately. You can switch between different active boxes using the dropdown selector at the top of the complete
interface – this same selector is available within the smaller status
widget:
[11]:
viz.status()
You can also programatically find and change the active box from Python:
[12]:
viz.active_selection_name()
[12]:
'Profitable'
[13]:
viz.set_active_selection_name("Passable")
viz.active_selection_name()
[13]:
'Passable'
When interactively changing bounds by dragging on figures, the currently “active” box is modified with the revised bounds. The entire set of bounds can be cleared at once with the clear_box
method, which by default clears the settings on the active box selection; give a name to clear the settings from a different box selection.
[14]:
viz.clear_box()
If instead we want to manipulate an existing box selection, we can access the Box object, manipulate it (e.g. by using remove_from_allowed_set
or add_to_allowed_set
), and write it back into the Visualizer.
[15]:
box = viz['Profitable']
box.remove_from_allowed_set('debt_type', 'Rev Bond')
viz['Profitable'] = box
Two Dimension Figures¶
The Visualizer
object can also create an interactive two-dimensional scatter plot, using the two_way
method. This method allows the user to specify the variables for both the x
and y
axis, and either can be any policy lever, exogenous uncertainty, or performance measure. These dimensions can be changed interactively later as well. The resulting scatter plot is linked to the same selection of experiments in the interactive one-dimensional figures shown above, and by default the
same experiments are highlighted in the same color scheme in all of these related figures.
[16]:
viz.two_way(x='expand_capacity', y='time_savings')
One useful feature of the two_way
is the ability to manually “lasso” a selection of data points. This lasso selection does not need to be anything like a rectangular box selection, as we have seen so far. Once a lasso selection of data points is made in the figure above, you can choose “Use Manual Selection” from the Edit Selection...
menu at right, which will create a new Visualizer
selection from the selected data. The highlight color changes to signify that this is not an
editable rectangular box, and the selected data will be highlighted in all figures linked to this Visualizer
, including the histograms above.
In addition to the two_way, which offers a feature-packed view of two dimensions at a time,
there is also a scatter plot matrix Visualizer.splom()
option, which displays a configurable matrix of similar
two dimensional views.
[17]:
viz.splom(
rows=('expand_capacity','time_savings','net_benefits'),
cols='L',
reset=True
)
[18]:
viz.hmm(
rows=('time_savings','net_benefits'),
cols='L',
show_points=100,
reset=True,
)
---------------------------------------------------------------------------
ModuleNotFoundError Traceback (most recent call last)
<ipython-input-18-af81d9f65bf5> in <module>
----> 1 viz.hmm(
2 rows=('time_savings','net_benefits'),
3 cols='L',
4 show_points=100,
5 reset=True,
~/LocalGit/tmip-emat/emat/analysis/explore_2/explore_visualizer.py in hmm(self, key, reset, cols, rows, emph_selected, show_points, size, with_hover)
1029 box = self._selection_defs[name].to_emat_box()
1030
-> 1031 self._hmm[key] = new_hmm_figure(
1032 self.scope,
1033 self.data,
~/LocalGit/tmip-emat/emat/analysis/explore_2/components/__init__.py in new_hmm_figure(scope, data, rows, cols, row_titles, size, selection, box, refpoint, figure_class, on_select, on_deselect, selected_color, unselected_color, emph_selected, show_points, show_points_frac, marker_size, with_hover)
1506 with_hover=True,
1507 ):
-> 1508 import datashader as ds # optional dependency
1509
1510 if unselected_color is None:
ModuleNotFoundError: No module named 'datashader'
[ ]:
viz.new_selection(
"time_savings * input_flow > 1000 & cost_of_capacity_expansion < 300",
name="TimeSaved"
)
Dynamic Feature Scoring¶
EMAT can score the relative importance of inputs for an experiment being within the selection, either for a typical rectangular selection based on thresholds, or for any arbitrary selection. These scores are recomputed and updated in near-real-time as the thresholds are adjusted.
When the selection includes rectangular thresholds set on both inputs and outputs, the thresholded inputs are automatically excluded from the scoring algorithm.
[ ]:
viz.selection_feature_scores()
Using PRIM with the Interactive Explorer¶
The PRIM tools are available directly within the interactive explorer. Simply set a target as shown.
[20]:
prim = viz.prim(target="net_benefits >= 0")
[21]:
box1 = prim.find_box()
The tradeoff selector is directly integrated into the explorer. In addition to the information visible by hovering over any point in the tradeoff selector figure, clicking on that point will create a new selection in the explorer, and set all of the interactive constraints to the bounds given by that particular point.
[22]:
box1.tradeoff_selector()
[23]:
box1.select(20)
[24]:
viz.status()
[25]:
viz.lever_selectors()
We can also use PRIM to explore solutions based only on manipulating the policy levers, and not the combination of all inputs (levers & uncertainties).
[26]:
prim_levers = viz.prim('levers', target="Profitable")
[27]:
prim_levers.tradeoff_selector()
[28]:
viz.parcoords()