Skip to content
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

Implement AxModelManager and allow building GP models from diagnostics #178

Merged
merged 64 commits into from
Mar 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
64 commits
Select commit Hold shift + click to select a range
73c85a6
Add surrogate models analysis capabilities through the `AxClient` class.
delaossa Feb 9, 2024
721a42a
Some fixes
delaossa Feb 9, 2024
a56c704
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Feb 9, 2024
d8213b7
More fixes.
delaossa Feb 10, 2024
3019124
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Feb 10, 2024
17b58b5
Change callable for fitting model.
delaossa Feb 12, 2024
3fdc0b4
Make it work for multi-objective cases.
delaossa Feb 12, 2024
834ca5a
Merge branch 'feature/ax_model_manager' of github.com:delaossa/optima…
delaossa Feb 12, 2024
1348e40
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Feb 12, 2024
ce73dca
Some more fixes.
delaossa Feb 13, 2024
dd02114
Add test for `ax_model_manager`.
delaossa Feb 13, 2024
d4016e2
Resolve conflicts.
delaossa Feb 13, 2024
4ea48c1
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Feb 13, 2024
13e1aed
Fix line in documentation.
delaossa Feb 13, 2024
6d0b3d6
Allow to initialize multi-objective models.
delaossa Feb 13, 2024
fd59406
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Feb 13, 2024
d40fd6d
Change the logix of .
delaossa Feb 14, 2024
ad85ed4
Change the logic of .
delaossa Feb 14, 2024
cfd3978
Merge branch 'feature/ax_model_manager' of github.com:delaossa/optima…
delaossa Feb 14, 2024
3e890fb
Change the logic of `build_model`.
delaossa Feb 14, 2024
75fd63d
Merge branch 'feature/ax_model_manager' of github.com:delaossa/optima…
delaossa Feb 14, 2024
e092704
Convert parameter type properly.
delaossa Feb 14, 2024
faa44b8
Refactor class methods
AngelFP Feb 15, 2024
4ffd81c
Update test
AngelFP Feb 15, 2024
3781d6a
Allow converting 1-element dictionary data to `DataFrame`.
delaossa Feb 27, 2024
6357f13
Add function to get the best point parameters.
delaossa Feb 27, 2024
8898052
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Feb 27, 2024
d1317c2
Pass optimas parameters to `AxModelManager.build_model`.
delaossa Feb 28, 2024
7122d7f
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Feb 28, 2024
a7f24b2
Add `get_mid_point` method.
delaossa Feb 29, 2024
f6688b8
Merge branch 'feature/ax_model_manager' of github.com:delaossa/optima…
delaossa Feb 29, 2024
2142dce
Simplify implementation
AngelFP Mar 6, 2024
02199f6
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Mar 6, 2024
5ef261e
Use `Models.MOO` for multi-objective cases.
delaossa Mar 6, 2024
513044f
Merge branch 'main' into pr/delaossa/178
AngelFP Mar 6, 2024
dc2d9aa
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Mar 6, 2024
5b1880d
Reduce number of lines
AngelFP Mar 6, 2024
18f0c7f
Add comment
AngelFP Mar 6, 2024
9a7a830
Return index in `get_best_point`
AngelFP Mar 6, 2024
9b1358d
Implement fixed point.
delaossa Mar 6, 2024
f1f0489
Merge branch 'feature/ax_model_manager' of github.com:delaossa/optima…
delaossa Mar 6, 2024
c651778
Fix typo.
delaossa Mar 6, 2024
ce42196
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Mar 6, 2024
0a6a15d
Small correction.
delaossa Mar 6, 2024
24655f0
Merge branch 'feature/ax_model_manager' of github.com:delaossa/optima…
delaossa Mar 6, 2024
8520fb8
Various fixes and changes:
AngelFP Mar 7, 2024
85a6716
Update test
AngelFP Mar 7, 2024
448a8f7
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Mar 7, 2024
03096c4
Add `AxModelManager` to documentation
AngelFP Mar 7, 2024
eb1d8a2
Make argument names more similar to Ax
AngelFP Mar 7, 2024
dec20a7
Reformat imports
AngelFP Mar 7, 2024
85e3261
Improve docstrings
AngelFP Mar 7, 2024
c7ee235
Update docstring and typo
AngelFP Mar 7, 2024
52e81cf
Add documentation on building GPs
AngelFP Mar 7, 2024
a8ae726
Add some options to the `AxModelManager` plots.
delaossa Mar 7, 2024
3a03e71
Merge branch 'feature/ax_model_manager' of github.com:delaossa/optima…
delaossa Mar 7, 2024
da112d8
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Mar 7, 2024
555f0a2
Typo in docs.
delaossa Mar 7, 2024
f98b283
Update docs
AngelFP Mar 7, 2024
57793cd
Edit docstrings
AngelFP Mar 7, 2024
28b7942
FIx typo
AngelFP Mar 7, 2024
f944d4d
Add docstring details
AngelFP Mar 7, 2024
9ea6774
Fix docs
AngelFP Mar 7, 2024
0b4d6a7
Increase version number
AngelFP Mar 7, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions doc/source/api/diagnostics.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ Diagnostics
:toctree: _autosummary

ExplorationDiagnostics
AxModelManager
294 changes: 294 additions & 0 deletions doc/source/user_guide/advanced_usage/build_gp_surrogates.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,294 @@
{
"cells": [
{
"cell_type": "raw",
"metadata": {
"raw_mimetype": "text/restructuredtext"
},
"source": [
"Building GP surrogate models from optimization data\n",
"===================================================\n",
"\n",
"The :class:`~optimas.diagnostics.ExplorationDiagnostics` class\n",
"provides a simple way of fitting a Gaussian process (GP) model to any of the\n",
"objectives or analyzed parameters of an ``optimas``\n",
":class:`~optimas.explorations.Exploration`, independently of which generator\n",
"was used. This is useful to get a better understanding of the underlying\n",
"function, make predictions, etc.\n",
"\n",
"In this example, we will illustrate how to build GP models by using\n",
"a basic optimization that runs directly on\n",
"a Jupyter notebook. This optimization uses an\n",
":class:`~optimas.generators.RandomSamplingGenerator` and a simple\n",
":class:`~optimas.evaluators.FunctionEvaluator` that evaluates an\n",
"analytical function.\n",
"\n",
"\n",
"Set up example optimization\n",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~\n",
"\n",
"The following cell sets up and runs an optimization with two input parameters\n",
"``x1`` and ``x2``, two objectives ``f1`` and ``f2``, and one additional\n",
"analyzed parameter ``p1``.\n",
"At each evaluation, the ``eval_func_sf_moo`` function is run,\n",
"which assigns a value to each outcome parameter according to the analytical\n",
"formulas\n",
"\n",
".. math::\n",
"\n",
" f_1(x_1, x_2) = -(x_1 + 10 \\cos(x_1)) (x_2 + 5\\cos(x_2))\n",
"\n",
".. math::\n",
"\n",
" f_2(x_1, x_2) = 2 f_1(x_1, x_2)\n",
"\n",
".. math::\n",
"\n",
" p_1(x_1, x_2) = \\sin(x_1) + \\cos(x_2)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import numpy as np\n",
"from optimas.explorations import Exploration\n",
"from optimas.core import VaryingParameter, Objective, Parameter\n",
"from optimas.generators import RandomSamplingGenerator\n",
"from optimas.evaluators import FunctionEvaluator\n",
"\n",
"\n",
"def eval_func_sf_moo(input_params, output_params):\n",
" \"\"\"Example multi-objective function.\"\"\"\n",
" x1 = input_params[\"x1\"]\n",
" x2 = input_params[\"x2\"]\n",
" result = -(x1 + 10 * np.cos(x1)) * (x2 + 5 * np.cos(x2))\n",
" output_params[\"f1\"] = result\n",
" output_params[\"f2\"] = result * 2\n",
" output_params[\"p1\"] = np.sin(x1) + np.cos(x2)\n",
"\n",
"\n",
"var1 = VaryingParameter(\"x1\", 0.0, 5.0)\n",
"var2 = VaryingParameter(\"x2\", -5.0, 5.0)\n",
"par1 = Parameter(\"p1\")\n",
"obj1 = Objective(\"f1\", minimize=True)\n",
"obj2 = Objective(\"f2\", minimize=False)\n",
"\n",
"gen = RandomSamplingGenerator(\n",
" varying_parameters=[var1, var2],\n",
" objectives=[obj1, obj2],\n",
" analyzed_parameters=[par1],\n",
")\n",
"ev = FunctionEvaluator(function=eval_func_sf_moo)\n",
"exploration = Exploration(\n",
" generator=gen,\n",
" evaluator=ev,\n",
" max_evals=50,\n",
" sim_workers=1,\n",
" exploration_dir_path=\"./exploration\",\n",
" libe_comms=\"threads\", #this is only needed to run on a Jupyter notebook.\n",
")\n",
"\n",
"# Run exploration.\n",
"exploration.run()"
]
},
{
"cell_type": "raw",
"metadata": {
"raw_mimetype": "text/restructuredtext"
},
"source": [
"Initialize diagnostics\n",
"~~~~~~~~~~~~~~~~~~~~~~\n",
"\n",
"The diagnostics class only requires the path to the exploration directory\n",
"as input parameter, or directly the ``exploration`` instance."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from optimas.diagnostics import ExplorationDiagnostics\n",
"\n",
"diags = ExplorationDiagnostics(exploration)"
]
},
{
"cell_type": "raw",
"metadata": {
"raw_mimetype": "text/restructuredtext"
},
"source": [
"Building a GP model of each objective and analyzed parameter\n",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n",
"\n",
"To build a GP model, simply call\n",
":meth:`~optimas.diagnostics.Exploration.build_gp_model` on the diagnostics,\n",
"indicating the name of the variable to which the model should be fitted.\n",
"This variable can be any ``objective`` or ``analyzed_parameter`` of the\n",
"optimization.\n",
"\n",
"Note that when building a surrogate model of an analyzed parameter, it is\n",
"required to provide a value to the ``minimize`` argument. This parameter\n",
"should therefore be ``True`` is lower values of the analyzed parameter are\n",
"better than higher values. This information is necessary, e.g., for determining\n",
"the best point in the model."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Build one model for each objective and analyzed parameter.\n",
"f1_model = diags.build_gp_model(\"f1\")\n",
"f2_model = diags.build_gp_model(\"f2\")\n",
"p1_model = diags.build_gp_model(\"p1\", minimize=False)"
]
},
{
"cell_type": "raw",
"metadata": {
"raw_mimetype": "text/restructuredtext"
},
"source": [
"Visualizing the surrogate models\n",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n",
"\n",
"The models provide some basic plotting methods for easy visualization, like\n",
":meth:`~optimas.diagnostics.AxModelManager.plot_contour`\n",
"and :meth:`~optimas.diagnostics.AxModelManager.plot_slice`."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# plot model for `f1`.\n",
"fig, ax1 = f1_model.plot_contour(mode=\"both\", figsize=(6, 3), dpi=300)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# plot 1D slice of `f1`.\n",
"fig, ax1 = f1_model.plot_slice(\"x1\", figsize=(6, 3), dpi=300)"
]
},
{
"cell_type": "raw",
"metadata": {
"raw_mimetype": "text/restructuredtext"
},
"source": [
"These methods also allow more complex plot compositions to be created,\n",
"such as in the example below, by providing a ``subplot_spec`` where the plot\n",
"should be drawn."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import matplotlib.pyplot as plt\n",
"from matplotlib.gridspec import GridSpec\n",
"\n",
"fig = plt.figure(figsize=(10, 3), dpi=300)\n",
"gs = GridSpec(1, 3, wspace=0.4)\n",
"\n",
"# plot model for `f1`.\n",
"fig, ax1 = f1_model.plot_contour(\n",
" pcolormesh_kw={\"cmap\": \"GnBu\"},\n",
" subplot_spec=gs[0, 0],\n",
")\n",
"\n",
"# Get and draw top 3 evaluations for `f`\n",
"df_top = diags.get_best_evaluations(top=3, objective=\"f1\")\n",
"ax1.scatter(df_top[\"x1\"], df_top[\"x2\"], c=\"red\", marker=\"x\")\n",
"\n",
"# plot model for `f2`\n",
"fig, ax2 = f2_model.plot_contour(\n",
" pcolormesh_kw={\"cmap\": \"OrRd\"},\n",
" subplot_spec=gs[0, 1],\n",
")\n",
"\n",
"# plot model for `p1`\n",
"fig, ax3 = p1_model.plot_contour(\n",
" pcolormesh_kw={\"cmap\": \"PuBu\"},\n",
" subplot_spec=gs[0, 2],\n",
")"
]
},
{
"cell_type": "raw",
"metadata": {
"raw_mimetype": "text/restructuredtext"
},
"source": [
"Evaluating the surrogate model\n",
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n",
"\n",
"In addition to plotting, it is also possible to evaluate the model at any\n",
"point by using the :meth:`~optimas.diagnostics.AxModelManager.evaluate_model`\n",
"method.\n",
"\n",
"In the example below, this method is used to evaluate the model in all the\n",
"history points to create a cross-validation plot."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Evaluate model for each point in the history\n",
"mean, sem = f1_model.evaluate_model(diags.history)\n",
"min_f, max_f = np.min(diags.history[\"f1\"]), np.max(diags.history[\"f1\"])\n",
"\n",
"# Make plot\n",
"fig, ax = plt.subplots(figsize=(5, 4), dpi=300)\n",
"ax.errorbar(diags.history[\"f1\"], mean, yerr=sem, fmt=\"o\", ms=4, label=\"Data\")\n",
"ax.plot([min_f, max_f], [min_f, max_f], color=\"k\", ls=\"--\", label=\"Ideal correlation\")\n",
"ax.set_xlabel(\"Observations\")\n",
"ax.set_ylabel(\"Model predictions\")\n",
"ax.legend(frameon=False)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "optimas_env_py11",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.5"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
6 changes: 6 additions & 0 deletions doc/source/user_guide/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@ User guide
basic_usage/analyze_output
basic_usage/exploration_diagnostics

.. toctree::
:maxdepth: 2
:caption: Advanced usage

advanced_usage/build_gp_surrogates

.. toctree::
:maxdepth: 1
:caption: Citation
Expand Down
2 changes: 1 addition & 1 deletion optimas/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "0.4.1"
__version__ = "0.5.0"
3 changes: 2 additions & 1 deletion optimas/diagnostics/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from .exploration_diagnostics import ExplorationDiagnostics
from .ax_model_manager import AxModelManager

__all__ = ["ExplorationDiagnostics"]
__all__ = ["ExplorationDiagnostics", "AxModelManager"]
Loading