@@ -4,7 +4,7 @@ Parameter Estimation
4
4
==================================
5
5
6
6
Parameter Estimation using parmest requires a Pyomo model, experimental
7
- data which defines multiple scenarios, and a list of parameter names
7
+ data which defines multiple scenarios, and parameters
8
8
(thetas) to estimate. parmest uses Pyomo [PyomoBookII ]_ and (optionally)
9
9
mpi-sppy [mpisppy ]_ to solve a
10
10
two-stage stochastic programming problem, where the experimental data is
@@ -36,13 +36,12 @@ which includes the following methods:
36
36
~pyomo.contrib.parmest.parmest.Estimator.likelihood_ratio_test
37
37
~pyomo.contrib.parmest.parmest.Estimator.leaveNout_bootstrap_test
38
38
39
- Additional functions are available in parmest to group data, plot
40
- results, and fit distributions to theta values.
39
+ Additional functions are available in parmest to plot
40
+ results and fit distributions to theta values.
41
41
42
42
.. autosummary ::
43
43
:nosignatures:
44
44
45
- ~pyomo.contrib.parmest.parmest.group_data
46
45
~pyomo.contrib.parmest.graphics.pairwise_plot
47
46
~pyomo.contrib.parmest.graphics.grouped_boxplot
48
47
~pyomo.contrib.parmest.graphics.grouped_violinplot
@@ -58,88 +57,78 @@ Section.
58
57
.. testsetup :: *
59
58
:skipif: not __import__('pyomo.contrib.parmest.parmest').contrib.parmest.parmest.parmest_available
60
59
60
+ # Data
61
61
import pandas as pd
62
- from pyomo.contrib.parmest.examples.rooney_biegler.rooney_biegler import rooney_biegler_model as model_function
63
- data = pd.DataFrame(data=[[1,8.3],[2,10.3],[3,19.0],
64
- [4,16.0],[5,15.6],[6,19.8]],
65
- columns=['hour', 'y'])
66
- theta_names = ['asymptote', 'rate_constant']
67
- def objective_function(model, data):
68
- expr = sum((data.y[i] - model.response_function[data.hour[i]])**2 for i in data.index)
62
+ data = pd.DataFrame(
63
+ data=[[1, 8.3], [2, 10.3], [3, 19.0],
64
+ [4, 16.0], [5, 15.6], [7, 19.8]],
65
+ columns=['hour', 'y'],
66
+ )
67
+
68
+ # Sum of squared error function
69
+ def SSE(model):
70
+ expr = (
71
+ model.experiment_outputs[model.y]
72
+ - model.response_function[model.experiment_outputs[model.hour]]
73
+ ) ** 2
69
74
return expr
70
75
76
+ # Create an experiment list
77
+ from pyomo.contrib.parmest.examples.rooney_biegler.rooney_biegler import RooneyBieglerExperiment
78
+ exp_list = []
79
+ for i in range(data.shape[0]):
80
+ exp_list.append(RooneyBieglerExperiment(data.loc[i, :]))
81
+
71
82
.. doctest ::
72
83
:skipif: not __import__('pyomo.contrib.parmest.parmest').contrib.parmest.parmest.parmest_available
73
84
74
85
>>> import pyomo.contrib.parmest.parmest as parmest
75
- >>> pest = parmest.Estimator(model_function, data, theta_names, objective_function )
86
+ >>> pest = parmest.Estimator(exp_list, obj_function = SSE )
76
87
77
88
Optionally, solver options can be supplied, e.g.,
78
89
79
90
.. doctest ::
80
91
:skipif: not __import__('pyomo.contrib.parmest.parmest').contrib.parmest.parmest.parmest_available
81
92
82
93
>>> solver_options = {" max_iter" : 6000 }
83
- >>> pest = parmest.Estimator(model_function, data, theta_names, objective_function, solver_options)
84
-
85
-
86
-
87
- Model function
88
- --------------
89
-
90
- The first argument is a function which uses data for a single scenario
91
- to return a populated and initialized Pyomo model for that scenario.
92
-
93
- Parameters that the user would like to estimate can be defined as
94
- **mutable parameters (Pyomo `Param`) or variables (Pyomo `Var`) **.
95
- Within parmest, any parameters that are to be estimated are converted to unfixed variables.
96
- Variables that are to be estimated are also unfixed.
97
-
98
- The model does not have to be specifically written as a
99
- two-stage stochastic programming problem for parmest.
100
- That is, parmest can modify the
101
- objective, see :ref: `ObjFunction ` below.
102
-
103
- Data
104
- ----
105
-
106
- The second argument is the data which will be used to populate the Pyomo
107
- model. Supported data formats include:
108
-
109
- * **Pandas Dataframe ** where each row is a separate scenario and column
110
- names refer to observed quantities. Pandas DataFrames are easily
111
- stored and read in from csv, excel, or databases, or created directly
112
- in Python.
113
- * **List of Pandas Dataframe ** where each entry in the list is a separate scenario.
114
- Dataframes store observed quantities, referenced by index and column.
115
- * **List of dictionaries ** where each entry in the list is a separate
116
- scenario and the keys (or nested keys) refer to observed quantities.
117
- Dictionaries are often preferred over DataFrames when using static and
118
- time series data. Dictionaries are easily stored and read in from
119
- json or yaml files, or created directly in Python.
120
- * **List of json file names ** where each entry in the list contains a
121
- json file name for a separate scenario. This format is recommended
122
- when using large datasets in parallel computing.
123
-
124
- The data must be compatible with the model function that returns a
125
- populated and initialized Pyomo model for a single scenario. Data can
126
- include multiple entries per variable (time series and/or duplicate
127
- sensors). This information can be included in custom objective
128
- functions, see :ref: `ObjFunction ` below.
129
-
130
- Theta names
131
- -----------
132
-
133
- The third argument is a list of parameters or variable names that the user wants to
134
- estimate. The list contains strings with `Param ` and/or `Var ` names from the Pyomo
135
- model.
94
+ >>> pest = parmest.Estimator(exp_list, obj_function = SSE , solver_options = solver_options)
95
+
96
+
97
+ List of experiment objects
98
+ --------------------------
99
+
100
+ The first argument is a list of experiment objects which is used to
101
+ create one labeled model for each expeirment.
102
+ The template :class: `~pyomo.contrib.parmest.experiment.Experiment `
103
+ can be used to generate a list of experiment objects.
104
+
105
+ A labeled Pyomo model ``m `` has the following additional suffixes (Pyomo `Suffix `):
106
+
107
+ * ``m.experiment_outputs `` which defines experiment output (Pyomo `Param `, `Var `, or `Expression `)
108
+ and their associated data values (float, int).
109
+ * ``m.unknown_parameters `` which defines the mutable parameters or variables (Pyomo `Param ` or `Var `)
110
+ to estimate along with their component unique identifier (Pyomo `ComponentUID `).
111
+ Within parmest, any parameters that are to be estimated are converted to unfixed variables.
112
+ Variables that are to be estimated are also unfixed.
113
+
114
+ The experiment class has one required method:
115
+
116
+ * :class: `~pyomo.contrib.parmest.experiment.Experiment.get_labeled_model ` which returns the labeled Pyomo model.
117
+ Note that the model does not have to be specifically written as a
118
+ two-stage stochastic programming problem for parmest.
119
+ That is, parmest can modify the
120
+ objective, see :ref: `ObjFunction ` below.
121
+
122
+ Parmest comes with several :ref: `examplesection ` that illustrates how to set up the list of experiment objects.
123
+ The examples commonly include additional :class: `~pyomo.contrib.parmest.experiment.Experiment ` class methods to
124
+ create the model, finalize the model, and label the model. The user can customize methods to suit their needs.
136
125
137
126
.. _ObjFunction :
138
127
139
128
Objective function
140
129
------------------
141
130
142
- The fourth argument is an optional argument which defines the
131
+ The second argument is an optional argument which defines the
143
132
optimization objective function to use in parameter estimation.
144
133
145
134
If no objective function is specified, the Pyomo model is used "as is" and
@@ -150,20 +139,27 @@ stochastic programming problem.
150
139
If the Pyomo model is not written as a two-stage stochastic programming problem in
151
140
this format, and/or if the user wants to use an objective that is
152
141
different than the original model, a custom objective function can be
153
- defined for parameter estimation. The objective function arguments
154
- include `model ` and `data ` and the objective function returns a Pyomo
142
+ defined for parameter estimation. The objective function has a single argument,
143
+ which is the model from a single experiment.
144
+ The objective function returns a Pyomo
155
145
expression which is used to define "SecondStageCost". The objective
156
146
function can be used to customize data points and weights that are used
157
147
in parameter estimation.
158
148
149
+ Parmest includes one built in objective function to compute the sum of squared errors ("SSE") between the
150
+ ``m.experiment_outputs `` model values and data values.
151
+
159
152
Suggested initialization procedure for parameter estimation problems
160
153
--------------------------------------------------------------------
161
154
162
155
To check the quality of initial guess values provided for the fitted parameters, we suggest solving a
163
156
square instance of the problem prior to solving the parameter estimation problem using the following steps:
164
157
165
- 1. Create :class: `~pyomo.contrib.parmest.parmest.Estimator ` object. To initialize the parameter estimation solve from the square problem solution, set optional argument ``solver_options = {bound_push: 1e-8} ``.
158
+ 1. Create :class: `~pyomo.contrib.parmest.parmest.Estimator ` object. To initialize the parameter
159
+ estimation solve from the square problem solution, set optional argument ``solver_options = {bound_push: 1e-8} ``.
166
160
167
- 2. Call :class: `~pyomo.contrib.parmest.parmest.Estimator.objective_at_theta ` with optional argument ``(initialize_parmest_model=True) ``. Different initial guess values for the fitted parameters can be provided using optional argument `theta_values ` (**Pandas Dataframe **)
161
+ 2. Call :class: `~pyomo.contrib.parmest.parmest.Estimator.objective_at_theta ` with optional
162
+ argument ``(initialize_parmest_model=True) ``. Different initial guess values for the fitted
163
+ parameters can be provided using optional argument `theta_values ` (**Pandas Dataframe **)
168
164
169
165
3. Solve parameter estimation problem by calling :class: `~pyomo.contrib.parmest.parmest.Estimator.theta_est `
0 commit comments