README (README.md)
<div align="center">
<img src="https://raw.githubusercontent.com/bayesian-optimization/BayesianOptimization/master/docsrc/static/func.png"><br><br>
</div>
Bayesian Optimization
[](https://bayesian-optimization.github.io/BayesianOptimization/index.html)
[](https://codecov.io/github/bayesian-optimization/BayesianOptimization?branch=master)
[](https://pypi.python.org/pypi/bayesian-optimization)
Pure Python implementation of bayesian global optimization with gaussian
processes.
This is a constrained global optimization package built upon bayesian inference
and gaussian processes, that attempts to find the maximum value of an unknown
function in as few iterations as possible. This technique is particularly
suited for optimization of high cost functions and situations where the balance
between exploration and exploitation is important.
Installation
* pip (via PyPI):
$ pip install bayesian-optimization* Conda (via conda-forge):
$ conda install -c conda-forge bayesian-optimizationHow does it work?
See the documentation for how to use this package.
Bayesian optimization works by constructing a posterior distribution of functions (gaussian process) that best describes the function you want to optimize. As the number of observations grows, the posterior distribution improves, and the algorithm becomes more certain of which regions in parameter space are worth exploring and which are not, as seen in the picture below.
As you iterate over and over, the algorithm balances its needs of exploration and exploitation taking into account what it knows about the target function. At each step a Gaussian Process is fitted to the known samples (points previously explored), and the posterior distribution, combined with a exploration strategy (such as UCB (Upper Confidence Bound), or EI (Expected Improvement)), are used to determine the next point that should be explored (see the gif below).
This process is designed to minimize the number of steps required to find a combination of parameters that are close to the optimal combination. To do so, this method uses a proxy optimization problem (finding the maximum of the acquisition function) that, albeit still a hard problem, is cheaper (in the computational sense) and common tools can be employed. Therefore Bayesian Optimization is most adequate for situations where sampling the function to be optimized is a very expensive endeavor. See the references for a proper discussion of this method.
This project is under active development. If you run into trouble, find a bug or notice
anything that needs correction, please let us know by filing an issue.
Basic tour of the Bayesian Optimization package
1. Specifying the function to be optimized
This is a function optimization package, therefore the first and most important ingredient is, of course, the function to be optimized.
DISCLAIMER: We know exactly how the output of the function below depends on its parameter. Obviously this is just an example, and you shouldn't expect to know it in a real scenario. However, it should be clear that you don't need to. All you need in order to use this package (and more generally, this technique) is a function f that takes a known set of parameters and outputs a real number.
def black_box_function(x, y):
"""Function with unknown internals we wish to maximize. This is just serving as an example, for all intents and
purposes think of the internals of this function, i.e.: the process
which generates its output values, as unknown.
"""
return -x 2 - (y - 1) 2 + 1
2. Getting Started
All we need to get started is to instantiate a BayesianOptimization object specifying a function to be optimized f, and its parameters with their corresponding bounds, pbounds. This is a constrained optimization technique, so you must specify the minimum and maximum values that can be probed for each parameter in order for it to work
from bayes_opt import BayesianOptimizationBounded region of parameter space
pbounds = {'x': (2, 4), 'y': (-3, 3)}optimizer = BayesianOptimization(
f=black_box_function,
pbounds=pbounds,
random_state=1,
)
The BayesianOptimization object will work out of the box without much tuning needed. The main method you should be aware of is maximize, which does exactly what you think it does.
There are many parameters you can pass to maximize, nonetheless, the most important ones are:
- n_iter: How many steps of bayesian optimization you want to perform. The more steps the more likely to find a good maximum you are.
- init_points: How many steps of random exploration you want to perform. Random exploration can help by diversifying the exploration space.
optimizer.maximize(
init_points=2,
n_iter=3,
) | iter | target | x | y |
-------------------------------------------------
| 1 | -7.135 | 2.834 | 1.322 |
| 2 | -7.78 | 2.0 | -1.186 |
| 3 | -19.0 | 4.0 | 3.0 |
| 4 | -16.3 | 2.378 | -2.413 |
| 5 | -4.441 | 2.105 | -0.005822 |
=================================================
The best combination of parameters and target value found can be accessed via the property optimizer.max.
print(optimizer.max)
>>> {'target': -4.441293113411222, 'params': {'y': -0.005822117636089974, 'x': 2.104665051994087}}
While the list of all parameters probed and their corresponding target values is available via the property optimizer.res.
for i, res in enumerate(optimizer.res):
print("Iteration {}: \n\t{}".format(i, res))>>> Iteration 0:
>>> {'target': -7.135455292718879, 'params': {'y': 1.3219469606529488, 'x': 2.8340440094051482}}
>>> Iteration 1:
>>> {'target': -7.779531005607566, 'params': {'y': -1.1860045642089614, 'x': 2.0002287496346898}}
>>> Iteration 2:
>>> {'target': -19.0, 'params': {'y': 3.0, 'x': 4.0}}
>>> Iteration 3:
>>> {'target': -16.29839645063864, 'params': {'y': -2.412527795983739, 'x': 2.3776144540856503}}
>>> Iteration 4:
>>> {'target': -4.441293113411222, 'params': {'y': -0.005822117636089974, 'x': 2.104665051994087}}
Minutiae
Citation
If you used this package in your research, please cite it:
@Misc{,
author = {Fernando Nogueira},
title = {{Bayesian Optimization}: Open source constrained global optimization tool for {Python}},
year = {2014--},
url = " https://github.com/bayesian-optimization/BayesianOptimization"
}If you used any of the advanced functionalities, please additionally cite the corresponding publication:
For the SequentialDomainTransformer:
@article{
author = {Stander, Nielen and Craig, Kenneth},
year = {2002},
month = {06},
pages = {},
title = {On the robustness of a simple domain reduction scheme for simulation-based optimization},
volume = {19},
journal = {International Journal for Computer-Aided Engineering and Software (Eng. Comput.)},
doi = {10.1108/02644400210430190}
}For constrained optimization:
@inproceedings{gardner2014bayesian,
title={Bayesian optimization with inequality constraints.},
author={Gardner, Jacob R and Kusner, Matt J and Xu, Zhixiang Eddie and Weinberger, Kilian Q and Cunningham, John P},
booktitle={ICML},
volume={2014},
pages={937--945},
year={2014}
}For optimization over non-float parameters:
@article{garrido2020dealing,
title={Dealing with categorical and integer-valued variables in bayesian optimization with gaussian processes},
author={Garrido-Merch{\'a}n, Eduardo C and Hern{\'a}ndez-Lobato, Daniel},
journal={Neurocomputing},
volume={380},
pages={20--35},
year={2020},
publisher={Elsevier}
}---
.Pre Commit Config.Yaml (.pre-commit-config.yaml)
repos:
- hooks:
- id: ruff
name: ruff-lint
- id: ruff-format
name: ruff-format
args: [--check]
repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.12.3
---
Docsrc/Index (docsrc/index.rst)
.. toctree::
:hidden:
Quickstart <self>
.. toctree::
:hidden:
:maxdepth: 3
:caption: Example Notebooks:
Basic Tour </basic-tour>
Advanced Tour </advanced-tour>
Constrained Bayesian Optimization </constraints>
Parameter Types </parameter_types>
Sequential Domain Reduction </domain_reduction>
Acquisition Functions </acquisition_functions>
Exploration vs. Exploitation </exploitation_vs_exploration>
Visualization of a 1D-Optimization </visualization>
.. toctree::
:hidden:
:maxdepth: 2
:caption: API reference:
reference/bayes_opt
reference/acquisition
reference/constraint
reference/domain_reduction
reference/target_space
reference/parameter
reference/exception
reference/other
.. raw:: html
<div align="center">
<img src="https://raw.githubusercontent.com/bayesian-optimization/BayesianOptimization/master/docsrc/static/func.png"><br><br>
</div>
Bayesian Optimization
=====================
|tests| |Codecov| |Pypi| |PyPI - Python Version|
Pure Python implementation of bayesian global optimization with gaussian
processes.
This is a constrained global optimization package built upon bayesian
inference and gaussian processes, that attempts to find the maximum value
of an unknown function in as few iterations as possible. This technique
is particularly suited for optimization of high cost functions and
situations where the balance between exploration and exploitation is
important.
Installation
------------
pip (via PyPI)
~~~~~~~~~~~~~~
.. code:: console
$ pip install bayesian-optimization
Conda (via conda-forge)
~~~~~~~~~~~~~~~~~~~~~~~
.. code:: console
$ conda install -c conda-forge bayesian-optimization
How does it work?
-----------------
Bayesian optimization works by constructing a posterior distribution of
functions (gaussian process) that best describes the function you want
to optimize. As the number of observations grows, the posterior
distribution improves, and the algorithm becomes more certain of which
regions in parameter space are worth exploring and which are not, as
seen in the picture below.
.. image:: ./static/bo_example.png
:alt: BayesianOptimization in action
As you iterate over and over, the algorithm balances its needs of
exploration and exploitation taking into account what it knows about the
target function. At each step a Gaussian Process is fitted to the known
samples (points previously explored), and the posterior distribution,
combined with a exploration strategy (such as UCB (Upper Confidence
Bound), or EI (Expected Improvement)), are used to determine the next
point that should be explored (see the gif below).
.. image:: ./static/bayesian_optimization.gif
:alt: BayesianOptimization in action
This process is designed to minimize the number of steps required to
find a combination of parameters that are close to the optimal
combination. To do so, this method uses a proxy optimization problem
(finding the maximum of the acquisition function) that, albeit still a
hard problem, is cheaper (in the computational sense) and common tools
can be employed. Therefore Bayesian Optimization is most adequate for
situations where sampling the function to be optimized is a very
expensive endeavor. See the references for a proper discussion of this
method.
This project is under active development, if you find a bug, or anything
that needs correction, please let us know by filing anissue on GitHub <https://github.com/bayesian-optimization/BayesianOptimization/issues>__
.
Quick Index
-----------
See below for a quick tour over the basics of the Bayesian Optimization
package. More detailed information, other advanced features, and tips on
usage/implementation can be found in theexamples <examples.html>__
section. We suggest that you:
- Follow the basic tour__
notebook <basic-tour.html>
to learn how to use the package's most important features.
- Take a look at the advanced tour__
notebook <advanced-tour.html>
to learn how to make the package more flexible or how to use observers.
- To learn more about acquisition functions, a central building block
of bayesian optimization, see the acquisition functions__
notebook <acquisition_functions.html>
- If you want to optimize over integer-valued or categorical
parameters, see the parameter types__.
notebook <parameter_types.html>
- Check out this
notebook <visualization.html>__
with a step by step visualization of how this method works.
- To understand how to use bayesian optimization when additional
constraints are present, see the constrained optimization__.
notebook <constraints.html>
- Explore the domain reduction__
notebook <domain_reduction.html>
to learn more about how search can be sped up by dynamically changing
parameters' bounds.
- Explore this
notebook <exploitation_vs_exploration.html>__
exemplifying the balance between exploration and exploitation and how
to control it.
- Go over this
script <https://github.com/bayesian-optimization/BayesianOptimization/blob/master/examples/sklearn_example.py>__
for examples of how to tune parameters of Machine Learning models
using cross validation and bayesian optimization.
- Finally, take a look at this
script <https://github.com/bayesian-optimization/BayesianOptimization/blob/master/examples/async_optimization.py>__
for ideas on how to implement bayesian optimization in a distributed
fashion using this package.
Citation
--------
If you used this package in your research, please cite it:
::
@Misc{,
author={Fernando Nogueira},
title={{Bayesian Optimization}: Open source constrained global optimization tool for {Python}},
year={2014--},
url="https://github.com/bayesian-optimization/BayesianOptimization"
}
If you used any of the advanced functionalities, please additionally
cite the corresponding publication:
For the `SequentialDomainTransformer:
::
@article{
author={Stander, Nielen and Craig, Kenneth},
year={2002},
month={06},
pages={},
title={On the robustness of a simple domain reduction scheme for simulation-based optimization},
volume={19},
journal={International Journal for Computer-Aided Engineering and Software (Eng. Comput.)},
doi={10.1108/02644400210430190}
}
For constrained optimization:
::
@inproceedings{gardner2014bayesian,
title={Bayesian optimization with inequality constraints.},
author={Gardner, Jacob R and Kusner, Matt J and Xu, Zhixiang Eddie and Weinberger, Kilian Q and Cunningham, John P},
booktitle={ICML},
volume={2014},
pages={937--945},
year={2014}
}
For optimization over non-float parameters:
::
@article{garrido2020dealing,
title={Dealing with categorical and integer-valued variables in bayesian optimization with gaussian processes},
author={Garrido-Merch{\'a}n, Eduardo C and Hern{\'a}ndez-Lobato, Daniel},
journal={Neurocomputing},
volume={380},
pages={20--35},
year={2020},
publisher={Elsevier}
}
.. |tests| image:: https://github.com/bayesian-optimization/BayesianOptimization/actions/workflows/run_tests.yml/badge.svg
.. |Codecov| image:: https://codecov.io/github/bayesian-optimization/BayesianOptimization/badge.svg?branch=master&service=github
:target: https://codecov.io/github/bayesian-optimization/BayesianOptimization?branch=master
.. |Pypi| image:: https://img.shields.io/pypi/v/bayesian-optimization.svg
:target: https://pypi.python.org/pypi/bayesian-optimization
.. |PyPI - Python Version| image:: https://img.shields.io/pypi/pyversions/bayesian-optimization
---
Docsrc/Reference/Acquisition (docsrc/reference/acquisition.rst)
:py:mod:bayes_opt.acquisition
-------------------------------
.. automodule:: bayes_opt.acquisition
:members: AcquisitionFunction
.. toctree::
:hidden:
acquisition/UpperConfidenceBound
acquisition/ProbabilityOfImprovement
acquisition/ExpectedImprovement
acquisition/GPHedge
acquisition/ConstantLiar
---
Docsrc/Reference/Bayes Opt (docsrc/reference/bayes_opt.rst)
:py:class:bayes_opt.BayesianOptimization
------------------------------------------
.. autoclass:: bayes_opt.BayesianOptimization
:members:
---
Docsrc/Reference/Constraint (docsrc/reference/constraint.rst)
:py:class:bayes_opt.ConstraintModel
------------------------------------------------
See the Constrained Optimization notebook <../constraints.html#2.-Advanced-Constrained-Optimization>__ for a complete example.
.. autoclass:: bayes_opt.constraint.ConstraintModel
:members:
---
Docsrc/Reference/Domain Reduction (docsrc/reference/domain_reduction.rst)
:py:class:bayes_opt.SequentialDomainReductionTransformer
----------------------------------------------------------
See the Sequential Domain Reduction notebook <../domain_reduction.html>__ for a complete example.
.. autoclass:: bayes_opt.SequentialDomainReductionTransformer
:members:
---
Docsrc/Reference/Exception (docsrc/reference/exception.rst)
:py:mod:bayes_opt.exception
-------------------------------
.. automodule:: bayes_opt.exception
:members:
---
Docsrc/Reference/Other (docsrc/reference/other.rst)
Other
-----
.. autoclass:: bayes_opt.ScreenLogger
:members:
---
Docsrc/Reference/Parameter (docsrc/reference/parameter.rst)
:py:mod:bayes_opt.parameter
--------------------------------
.. automodule:: bayes_opt.parameter
:members:
---
Docsrc/Reference/Target Space (docsrc/reference/target_space.rst)
:py:class:bayes_opt.TargetSpace
---------------------------------
.. autoclass:: bayes_opt.TargetSpace
:members:
---
Docsrc/Reference/Acquisition/ConstantLiar (docsrc/reference/acquisition/ConstantLiar.rst)
:py:class:bayes_opt.acquisition.ConstantLiar
----------------------------------------------
.. autoclass:: bayes_opt.acquisition.ConstantLiar
:members:
---
Docsrc/Reference/Acquisition/ExpectedImprovement (docsrc/reference/acquisition/ExpectedImprovement.rst)
:py:class:bayes_opt.acquisition.ExpectedImprovement
-----------------------------------------------------
.. autoclass:: bayes_opt.acquisition.ExpectedImprovement
:members:
---
Docsrc/Reference/Acquisition/GPHedge (docsrc/reference/acquisition/GPHedge.rst)
:py:class:bayes_opt.acquisition.GPHedge
-----------------------------------------
.. autoclass:: bayes_opt.acquisition.GPHedge
:members:
---
Docsrc/Reference/Acquisition/ProbabilityOfImprovement (docsrc/reference/acquisition/ProbabilityOfImprovement.rst)
:py:class:bayes_opt.acquisition.ProbabilityOfImprovement
----------------------------------------------------------
.. autoclass:: bayes_opt.acquisition.ProbabilityOfImprovement
:members:
---
Docsrc/Reference/Acquisition/UpperConfidenceBound (docsrc/reference/acquisition/UpperConfidenceBound.rst)
:py:class:bayes_opt.acquisition.UpperConfidenceBound`
------------------------------------------------------
.. autoclass:: bayes_opt.acquisition.UpperConfidenceBound
:members:
---