-
Notifications
You must be signed in to change notification settings - Fork 560
Extended Parmest Capability for weighted SSE objective #3535
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
121 commits
Select commit
Hold shift + click to select a range
d332230
Updated parmest file
slilonfe5 e2c5eab
Updated parmest.py file
slilonfe5 6f832ca
Updated parmest.py
slilonfe5 14c0f6d
Updated parmest.py
slilonfe5 d0c857f
Merge branch 'main' into main
slilonfe5 0c210de
Updated parmest.py file
slilonfe5 877d58b
Merge branch 'main' of https://github.com/slilonfe5/pyomo
slilonfe5 f98590f
Created test for the new capabilities
slilonfe5 8fb0de2
Updated parmest.py file
slilonfe5 0aaf29b
Updated parmest.py file
slilonfe5 b3aa7b1
Updated parmest.py file
slilonfe5 8a190eb
Updated parmest.py file
slilonfe5 8837f6d
Implemented Alex's comments on the parmest.py file
slilonfe5 8a68329
Updated parmest.py file
slilonfe5 acd444c
Ran black on parmest.py file
slilonfe5 c3d37a5
Updated the test file for the new covariance methods
slilonfe5 f106b5c
Ran black on test_new_parmest_capabilities.py
slilonfe5 615db14
Merge branch 'main' into main
mrmundt 5dc48f2
Update pyomo/contrib/parmest/parmest.py
slilonfe5 4450a01
Update pyomo/contrib/parmest/parmest.py
slilonfe5 55dd836
Update pyomo/contrib/parmest/parmest.py
slilonfe5 1b362cf
Updated parmest.py and test_new_parmest_capabilities.py files
slilonfe5 ab18ad0
Merge branch 'main' of https://github.com/slilonfe5/pyomo
slilonfe5 49c8abe
Updated parmest.py file
slilonfe5 46b5356
Updated pyomo/contrib/parmest/parmest.py
slilonfe5 a9c4148
Updated pyomo/contrib/parmest/parmest.py
slilonfe5 927e36e
Updated parmest.py and the test file
slilonfe5 78cc3d8
Updated parmest.py and test_parmest.py files
slilonfe5 39824b1
Removed test_new_parmest_capabilities.py file
slilonfe5 7591dc9
Ran black on parmest.py and test_parmest.py files
slilonfe5 f54dbc6
Added back the test for the deprecated interface
slilonfe5 bbcdb2d
Small updates to the parmest.py file
slilonfe5 bc5da0f
Updated the test_parmest.py file
slilonfe5 3130ad7
Updated parmest.py and test_parmest.py files
slilonfe5 2346e1b
Ran black and reduced the code line length of parmest.py and test_par…
slilonfe5 7ba1815
Some string formatting to parmest.py
slilonfe5 06e4e17
A small bug fix in test_parmest.py file
slilonfe5 e1e0392
Ran black on test_parmest.py file
slilonfe5 67a0cbd
Small formatting changes to parmest.py and test_parmest.py
slilonfe5 ed4abb1
Merge branch 'main' into main
mrmundt 8f64290
Merge branch 'main' into main
slilonfe5 3756fdb
Implemented Miranda's feedback on parmest.py and updated test_parmest.py
slilonfe5 23bf10a
Merge branch 'main' into main
slilonfe5 c78ff0b
Updated parmest.py file
slilonfe5 cfb8d60
Minor string formatting in test_parmest.py
slilonfe5 2c2f202
Updated documentation files driver.rst and datarec.rst
slilonfe5 5e1d04a
Undo the trial fix in the datarec.rst and driver.rst files
slilonfe5 b472357
Updated driver.rst file and minor string formats in parmest.py
slilonfe5 b9962dd
Minor string format in test_parmest.py
slilonfe5 b8df9e1
Updated driver.rst and datarec.rst files
slilonfe5 93f28b3
Updated covariance.rst and Xinhong comment on parmest.py
slilonfe5 a2ba7f6
Merge branch 'main' into main
slilonfe5 0f88a71
Fixed typo in covariance.rst
slilonfe5 d06338f
Merge branch 'main' of https://github.com/slilonfe5/pyomo
slilonfe5 726561f
Updated documentation in covariance.rst file
slilonfe5 aa5a92a
Updated driver.rst and covariance.rst files
slilonfe5 0a5e74b
Updated covariance.rst, driver.rst, and parmest.py files
slilonfe5 5f915fb
Updated driver.rst
slilonfe5 42bda97
Fixed indentation in driver.rst
slilonfe5 e715e9f
Merge branch 'main' into main
slilonfe5 1b64e41
Fixed LaTeX error in covariance.rst file
slilonfe5 bdd93a5
Merge branch 'main' of https://github.com/slilonfe5/pyomo
slilonfe5 590c5c9
Implemented Miranda's final review on parmest.py, test_parmest.py, an…
slilonfe5 dd4308e
Update doc/OnlineDocs/explanation/analysis/parmest/covariance.rst
slilonfe5 01505e9
Merge branch 'main' into main
slilonfe5 ee4686f
Update pyomo/contrib/parmest/parmest.py
slilonfe5 66fa00f
Update pyomo/contrib/parmest/parmest.py
slilonfe5 c1ee5c4
Update pyomo/contrib/parmest/parmest.py
slilonfe5 d74d133
Update doc/OnlineDocs/explanation/analysis/parmest/covariance.rst
slilonfe5 d11fdc2
Updated Enum names in parmest.py
slilonfe5 f509c3b
Updated parmest.py file and ran black
slilonfe5 9db147b
Updated the covariance.rst file
slilonfe5 f9a5f69
Merge branch 'main' into main
slilonfe5 b4a2a5b
Minor string formatting in covariance.rst
slilonfe5 c92b405
Updated the rooney_biegler.py and all the examples
slilonfe5 b125043
Ran black on all changed files
slilonfe5 5c826b8
Merge branch 'main' into main
slilonfe5 9480646
Update datarec.rst file
slilonfe5 2149189
Merge branch 'main' of https://github.com/slilonfe5/pyomo
slilonfe5 72e44d4
Updated rooney_biegler.py and test_parmest.py
slilonfe5 6925c97
Updated rooney_biegler.py
slilonfe5 0007ce0
Merge branch 'main' into main
slilonfe5 71c07ea
Ran black
slilonfe5 9c8fe6e
Implemented Bethany's comments
slilonfe5 57e8011
Merge branch 'main' into main
slilonfe5 b6c1fa4
Updated parmest.py file
slilonfe5 e9d6bbc
Merge branch 'main' into main
slilonfe5 9d2a80f
Update pyomo/contrib/parmest/tests/test_parmest.py
slilonfe5 cf64dbd
Update pyomo/contrib/parmest/parmest.py
slilonfe5 5d0da31
Update pyomo/contrib/parmest/parmest.py
slilonfe5 aea14d3
Update pyomo/contrib/parmest/parmest.py
slilonfe5 1e1a9dd
Update pyomo/contrib/parmest/parmest.py
slilonfe5 1086747
Update pyomo/contrib/parmest/parmest.py
slilonfe5 1251c5b
Final updates to parmest.py, test_parmest.py, and covariance.rst
slilonfe5 622715c
Minor doc string update to parmest.py
slilonfe5 ef6cf7b
Merge branch 'main' into main
slilonfe5 0bf3edd
Implemented Miranda's final comments
slilonfe5 bb9fcde
Merge branch 'main' into main
slilonfe5 98074d7
Update doc/OnlineDocs/explanation/analysis/parmest/driver.rst
slilonfe5 5c2a577
Update pyomo/contrib/parmest/parmest.py
slilonfe5 53aaf1a
Update pyomo/contrib/parmest/parmest.py
slilonfe5 e5c1e65
Update pyomo/contrib/parmest/parmest.py
slilonfe5 8f0bf6e
Update pyomo/contrib/parmest/parmest.py
slilonfe5 071dfef
Implemented John's comment on parmest.py
slilonfe5 437bcb2
Update pyomo/contrib/parmest/parmest.py
slilonfe5 74a52e5
Update pyomo/contrib/parmest/parmest.py
slilonfe5 3d844e9
Merge branch 'main' into main
slilonfe5 d9fdd83
Update pyomo/contrib/parmest/parmest.py
slilonfe5 a2d4318
Updated parmest.py file
slilonfe5 5872e55
One missed instance of odd idiom
mrmundt 6dd7f64
Updated the code from Miranda's commit on missed instance
slilonfe5 e6098f3
Merge branch 'main' into main
slilonfe5 580f47a
Apply @jsiirola 's suggestions
mrmundt 0a35810
Missed logging_level logic line
mrmundt f8aadd1
Resolve issues with deprecation
mrmundt 8d638cc
Ignore the deprecation warning
mrmundt 1120b14
Better ignoring of warnings
mrmundt ea70537
Fixing failing tests issues
slilonfe5 ac5405c
Merge branch 'main' into main
slilonfe5 f90d201
More fixing of parmest.py file
slilonfe5 9428201
Merge branch 'main' of https://github.com/slilonfe5/pyomo
slilonfe5 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
129 changes: 117 additions & 12 deletions
129
doc/OnlineDocs/explanation/analysis/parmest/covariance.rst
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,16 +1,121 @@ | ||
| Covariance Matrix Estimation | ||
| ================================= | ||
| ============================ | ||
|
|
||
| If the optional argument ``calc_cov=True`` is specified for :class:`~pyomo.contrib.parmest.parmest.Estimator.theta_est`, | ||
| parmest will calculate the covariance matrix :math:`V_{\theta}` as follows: | ||
| The uncertainty in the estimated parameters is quantified using the covariance matrix. | ||
| The diagonal of the covariance matrix contains the variance of the estimated parameters. | ||
| Assuming Gaussian independent and identically distributed measurement errors, the | ||
| covariance matrix of the estimated parameters can be computed using the following | ||
| methods which have been implemented in parmest. | ||
|
|
||
| .. math:: | ||
| V_{\theta} = 2 \sigma^2 H^{-1} | ||
| 1. Reduced Hessian Method | ||
|
|
||
| This formula assumes all measurement errors are independent and identically distributed with | ||
| variance :math:`\sigma^2`. :math:`H^{-1}` is the inverse of the Hessian matrix for an unweighted | ||
| sum of least squares problem. Currently, the covariance approximation is only valid if the | ||
| objective given to parmest is the sum of squared error. Moreover, parmest approximates the | ||
| variance of the measurement errors as :math:`\sigma^2 = \frac{1}{n-l} \sum e_i^2` where :math:`n` is | ||
| the number of data points, :math:`l` is the number of fitted parameters, and :math:`e_i` is the | ||
| residual for experiment :math:`i`. | ||
| When the objective function is the sum of squared errors (SSE): | ||
| :math:`\text{SSE} = \sum_{i = 1}^n \left(y_{i} - \hat{y}_{i}\right)^2`, | ||
| the covariance matrix is: | ||
|
|
||
| .. math:: | ||
| V_{\boldsymbol{\theta}} = 2 \sigma^2 \left(\frac{\partial^2 \text{SSE}} | ||
| {\partial \boldsymbol{\theta} \partial \boldsymbol{\theta}}\right)^{-1}_{\boldsymbol{\theta} | ||
| = \boldsymbol{\theta}^*} | ||
|
|
||
| When the objective function is the weighted SSE (WSSE): | ||
| :math:`\text{WSSE} = \frac{1}{2} \left(\mathbf{y} - f(\mathbf{x};\boldsymbol{\theta})\right)^\text{T} | ||
| \mathbf{W} \left(\mathbf{y} - f(\mathbf{x};\boldsymbol{\theta})\right)`, | ||
| the covariance matrix is: | ||
|
|
||
| .. math:: | ||
| V_{\boldsymbol{\theta}} = \left(\frac{\partial^2 \text{WSSE}} | ||
| {\partial \boldsymbol{\theta} \partial \boldsymbol{\theta}}\right)^{-1}_{\boldsymbol{\theta} | ||
| = \boldsymbol{\theta}^*} | ||
|
|
||
| Where :math:`V_{\boldsymbol{\theta}}` is the covariance matrix of the estimated | ||
| parameters, :math:`y` are the observed measured variables, :math:`\hat{y}` are the | ||
| predicted measured variables, :math:`n` is the number of data points, | ||
| :math:`\boldsymbol{\theta}` are the unknown parameters, :math:`\boldsymbol{\theta^*}` | ||
| are the estimates of the unknown parameters, :math:`\mathbf{x}` are the decision | ||
| variables, and :math:`\mathbf{W}` is a diagonal matrix containing the inverse of the | ||
| variance of the measurement error, :math:`\sigma^2`. When the standard | ||
| deviation of the measurement error is not supplied by the user, parmest | ||
| approximates the variance of the measurement error as | ||
| :math:`\sigma^2 = \frac{1}{n-l} \sum e_i^2` where :math:`l` is the number of | ||
| fitted parameters, and :math:`e_i` is the residual for experiment :math:`i`. | ||
|
|
||
| In parmest, this method computes the inverse of the Hessian by scaling the | ||
| objective function (SSE or WSSE) with a constant probability factor. | ||
|
|
||
| 2. Finite Difference Method | ||
|
|
||
| In this method, the covariance matrix, :math:`V_{\boldsymbol{\theta}}`, is | ||
| calculated by applying the Gauss-Newton approximation to the Hessian, | ||
| :math:`\frac{\partial^2 \text{SSE}}{\partial \boldsymbol{\theta} \partial \boldsymbol{\theta}}` | ||
| or | ||
| :math:`\frac{\partial^2 \text{WSSE}}{\partial \boldsymbol{\theta} \partial \boldsymbol{\theta}}`, | ||
| leading to: | ||
|
|
||
| .. math:: | ||
| V_{\boldsymbol{\theta}} = \left(\sum_{i = 1}^n \mathbf{G}_{i}^{\mathrm{T}} \mathbf{W} | ||
| \mathbf{G}_{i} \right)^{-1} | ||
|
|
||
| This method uses central finite difference to compute the Jacobian matrix, | ||
| :math:`\mathbf{G}_{i}`, for experiment :math:`i`, which is the sensitivity of | ||
| the measured variables with respect to the parameters, :math:`\boldsymbol{\theta}`. | ||
| :math:`\mathbf{W}` is a diagonal matrix containing the inverse of the variance | ||
| of the measurement errors, :math:`\sigma^2`. | ||
|
|
||
| 3. Automatic Differentiation Method | ||
|
|
||
| Similar to the finite difference method, the covariance matrix is calculated as: | ||
|
|
||
| .. math:: | ||
| V_{\boldsymbol{\theta}} = \left( \sum_{i = 1}^n \mathbf{G}_{\text{kaug},\, i}^{\mathrm{T}} | ||
| \mathbf{W} \mathbf{G}_{\text{kaug},\, i} \right)^{-1} | ||
|
|
||
| However, this method uses the model optimality (KKT) condition to compute the | ||
| Jacobian matrix, :math:`\mathbf{G}_{\text{kaug},\, i}`, for experiment :math:`i`. | ||
|
|
||
| The covariance matrix calculation is only supported with the built-in objective | ||
| functions "SSE" or "SSE_weighted". | ||
|
|
||
| In parmest, the covariance matrix can be calculated after defining the | ||
| :class:`~pyomo.contrib.parmest.parmest.Estimator` object and estimating the unknown | ||
| parameters using :class:`~pyomo.contrib.parmest.parmest.Estimator.theta_est`. To | ||
| estimate the covariance matrix, with the default method being "finite_difference", call | ||
| the :class:`~pyomo.contrib.parmest.parmest.Estimator.cov_est` function, e.g., | ||
|
|
||
| .. testsetup:: * | ||
| :skipif: not __import__('pyomo.contrib.parmest.parmest').contrib.parmest.parmest.parmest_available | ||
|
|
||
| # Data | ||
| import pandas as pd | ||
| data = pd.DataFrame( | ||
| data=[[1, 8.3], [2, 10.3], [3, 19.0], | ||
| [4, 16.0], [5, 15.6], [7, 19.8]], | ||
| columns=['hour', 'y'], | ||
| ) | ||
|
|
||
| # Create the Experiment class | ||
| from pyomo.contrib.parmest.examples.rooney_biegler.rooney_biegler import RooneyBieglerExperiment | ||
|
|
||
| exp_list = [] | ||
| for i in range(data.shape[0]): | ||
| exp_list.append(RooneyBieglerExperiment(data.loc[i, :])) | ||
|
|
||
| .. doctest:: | ||
| :skipif: not __import__('pyomo.contrib.parmest.parmest').contrib.parmest.parmest.parmest_available | ||
|
|
||
| >>> import pyomo.contrib.parmest.parmest as parmest | ||
| >>> pest = parmest.Estimator(exp_list, obj_function="SSE") | ||
| >>> obj_val, theta_val = pest.theta_est() | ||
| >>> cov = pest.cov_est() | ||
|
|
||
| Optionally, one of the three methods; "reduced_hessian", "finite_difference", | ||
| and "automatic_differentiation_kaug" can be supplied for the covariance calculation, | ||
| e.g., | ||
|
|
||
| .. doctest:: | ||
| :skipif: not __import__('pyomo.contrib.parmest.parmest').contrib.parmest.parmest.parmest_available | ||
|
|
||
| >>> pest = parmest.Estimator(exp_list, obj_function="SSE") | ||
| >>> obj_val, theta_val = pest.theta_est() | ||
| >>> cov_method = "reduced_hessian" | ||
| >>> cov = pest.cov_est(method=cov_method) | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.