Skip to content

Commit 2bf4edd

Browse files
authored
PR 1/2: Add versioned docs (#509)
* Versioned docs (#8) * versioned [email protected] * Don't trigger publish if target is empty * Set workflow to trigger on release * Fix: versions.json path * Fix edit URI, set site URL to base * Revert erroneous change, rename format/lint job * Fix numpy docstrings * Update README: add docs shield, remove tutorial, references, quick start * Update README.md * Make docs a bit more nice: add links to classes imported from elsewhere, updated docstrings * Rerun `visualization.ipynb` to include `ScreenLogger` colour fixes
1 parent dc4e8ef commit 2bf4edd

25 files changed

+550
-270
lines changed

.github/workflows/build_docs.yml

Lines changed: 90 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,29 @@
1-
name: build docs
1+
name: docs
22

33
on:
4+
release:
5+
types: [published]
46
push:
57
branches:
68
- master
79
pull_request:
810

11+
concurrency:
12+
group: ${{ github.workflow }}
13+
914
jobs:
10-
deploy:
15+
build-docs-and-publish:
1116
runs-on: ubuntu-20.04
1217
permissions:
1318
contents: write
14-
concurrency:
15-
group: ${{ github.workflow }}-${{ github.ref }}
1619
steps:
1720
- uses: actions/checkout@v3
18-
1921
- name: Setup Python
2022
uses: actions/setup-python@v3
2123
with:
2224
python-version: '3.10'
25+
- name: Get tag
26+
uses: olegtarasov/[email protected]
2327
- name: Install pandoc
2428
run: sudo apt-get install -y pandoc
2529
- name: Install Poetry
@@ -31,9 +35,88 @@ jobs:
3135
run: |
3236
cd docsrc
3337
poetry run make github
38+
- name: Determine directory to publish docs to
39+
id: docs-publish-dir
40+
uses: jannekem/run-python-script-action@v1
41+
with:
42+
script: |
43+
import os, re
44+
github_ref = os.environ.get('GITHUB_REF')
45+
m = re.match(r'^refs/tags/v([0-9]+\.[0-9]+\.[0-9]+(-dev\.[0-9]+)?)$',
46+
github_ref)
47+
if m:
48+
target = m.group(1)
49+
elif github_ref == 'refs/heads/master':
50+
target = 'master'
51+
else:
52+
target = ''
53+
set_output('target', target)
3454
- name: Deploy
3555
uses: peaceiris/actions-gh-pages@v3
36-
if: ${{ github.ref == 'refs/heads/master' }}
56+
if: steps.docs-publish-dir.outputs.target != ''
3757
with:
3858
github_token: ${{ secrets.GITHUB_TOKEN }}
39-
publish_dir: ./docs
59+
publish_dir: ./docs/html
60+
destination_dir: ${{ steps.docs-publish-dir.outputs.target }}
61+
keep_files: false
62+
outputs:
63+
docs-target: ${{ steps.docs-publish-dir.outputs.target }}
64+
update-versions:
65+
name: Update docs versions JSON
66+
needs: build-docs-and-publish
67+
if: needs.build-docs-and-publish.outputs.docs-target != ''
68+
runs-on: Ubuntu-latest
69+
steps:
70+
- uses: actions/checkout@v3
71+
with:
72+
ref: gh-pages
73+
- name: Write versions to JSON file
74+
uses: jannekem/run-python-script-action@v1
75+
with:
76+
script: |
77+
import json
78+
import re
79+
80+
# dependency of sphinx, so should be installed
81+
from packaging import version as version_
82+
from pathlib import Path
83+
84+
cwd = Path.cwd()
85+
86+
versions = sorted((item.name for item in cwd.iterdir()
87+
if item.is_dir() and not item.name.startswith('.')),
88+
reverse=True)
89+
90+
# Filter out master and dev versions
91+
parseable_versions = []
92+
for version in versions:
93+
try:
94+
version_.parse(version)
95+
except version_.InvalidVersion:
96+
continue
97+
parseable_versions.append(version)
98+
99+
if parseable_versions:
100+
max_version = max(parseable_versions, key=version_.parse)
101+
else:
102+
max_version = None
103+
target_dir = Path('gh-pages')
104+
target_dir.mkdir(parents=True)
105+
106+
versions = [
107+
dict(
108+
version=version,
109+
title=version + ' (stable)' if version == max_version else version,
110+
aliases=['stable'] if version == max_version else [],
111+
) for version in versions
112+
]
113+
target_file = target_dir / 'versions.json'
114+
with target_file.open('w') as f:
115+
json.dump(versions, f)
116+
117+
- name: Publish versions JSON to GitHub pages
118+
uses: peaceiris/actions-gh-pages@v3
119+
with:
120+
github_token: ${{ secrets.GITHUB_TOKEN }}
121+
publish_dir: gh-pages
122+
keep_files: true

.github/workflows/format_and_lint.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ permissions:
99
contents: read
1010

1111
jobs:
12-
build:
12+
check:
1313
runs-on: ubuntu-latest
1414
steps:
1515
- uses: actions/checkout@v3

README.md

Lines changed: 17 additions & 153 deletions
Original file line numberDiff line numberDiff line change
@@ -5,50 +5,40 @@
55
# Bayesian Optimization
66

77
![tests](https://github.com/bayesian-optimization/BayesianOptimization/actions/workflows/run_tests.yml/badge.svg)
8+
[![docs - stable](https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fraw.githubusercontent.com%2Fbayesian-optimization%2FBayesianOptimization%2Fgh-pages%2Fversions.json&query=%24%5B%3F(%40.aliases%20%26%26%20%40.aliases.indexOf('stable')%20%3E%20-1)%5D.version&prefix=stable%20(v&suffix=)&label=docs)](https://bayesian-optimization.github.io/BayesianOptimization/)
89
[![Codecov](https://codecov.io/github/bayesian-optimization/BayesianOptimization/badge.svg?branch=master&service=github)](https://codecov.io/github/bayesian-optimization/BayesianOptimization?branch=master)
9-
[![Pypi](https://img.shields.io/pypi/v/bayesian-optimization.svg)](https://pypi.python.org/pypi/bayesian-optimization)![PyPI - Python Version](https://img.shields.io/pypi/pyversions/bayesian-optimization)
10+
[![Pypi](https://img.shields.io/pypi/v/bayesian-optimization.svg)](https://pypi.python.org/pypi/bayesian-optimization)
11+
![PyPI - Python Version](https://img.shields.io/pypi/pyversions/bayesian-optimization)
12+
1013

1114
Pure Python implementation of bayesian global optimization with gaussian
1215
processes.
1316

17+
18+
This is a constrained global optimization package built upon bayesian inference
19+
and gaussian processes, that attempts to find the maximum value of an unknown
20+
function in as few iterations as possible. This technique is particularly
21+
suited for optimization of high cost functions and situations where the balance
22+
between exploration and exploitation is important.
23+
1424
## Installation
1525

16-
* PyPI (pip):
26+
* pip (via PyPI):
1727

1828
```console
1929
$ pip install bayesian-optimization
2030
```
2131

22-
* Conda from conda-forge channel:
32+
* Conda (via conda-forge):
2333

2434
```console
2535
$ conda install -c conda-forge bayesian-optimization
2636
```
2737

28-
This is a constrained global optimization package built upon bayesian inference
29-
and gaussian process, that attempts to find the maximum value of an unknown
30-
function in as few iterations as possible. This technique is particularly
31-
suited for optimization of high cost functions, situations where the balance
32-
between exploration and exploitation is important.
33-
34-
## Quick Start
35-
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 the [examples](http://bayesian-optimization.github.io/BayesianOptimization/examples.html) folder. I suggest that you:
36-
- Follow the [basic tour notebook](http://bayesian-optimization.github.io/BayesianOptimization/basic-tour.html) to learn how to use the package's most important features.
37-
- Take a look at the [advanced tour notebook](http://bayesian-optimization.github.io/BayesianOptimization/advanced-tour.html) to learn how to make the package more flexible, how to deal with categorical parameters, how to use observers, and more.
38-
- Check out this [notebook](http://bayesian-optimization.github.io/BayesianOptimization/visualization.html) with a step by step visualization of how this method works.
39-
- To understand how to use bayesian optimization when additional constraints are present, see the [constrained optimization notebook](http://bayesian-optimization.github.io/BayesianOptimization/constraints.html).
40-
- Explore this [notebook](http://bayesian-optimization.github.io/BayesianOptimization/exploitation_vs_exploration.html)
41-
exemplifying the balance between exploration and exploitation and how to
42-
control it.
43-
- Go over this [script](https://github.com/bayesian-optimization/BayesianOptimization/blob/master/examples/sklearn_example.py)
44-
for examples of how to tune parameters of Machine Learning models using cross validation and bayesian optimization.
45-
- Explore the [domain reduction notebook](http://bayesian-optimization.github.io/BayesianOptimization/domain_reduction.html) to learn more about how search can be sped up by dynamically changing parameters' bounds.
46-
- Finally, take a look at this [script](https://github.com/bayesian-optimization/BayesianOptimization/blob/master/examples/async_optimization.py)
47-
for ideas on how to implement bayesian optimization in a distributed fashion using this package.
48-
49-
5038
## How does it work?
5139

40+
See the [documentation](https://bayesian-optimization.github.io/BayesianOptimization/) for how to use this package.
41+
5242
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.
5343

5444
![BayesianOptimization in action](docsrc/static/bo_example.png)
@@ -59,8 +49,8 @@ As you iterate over and over, the algorithm balances its needs of exploration an
5949

6050
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.
6151

62-
This project is under active development, if you find a bug, or anything that
63-
needs correction, please let me know.
52+
This project is under active development. If you run into trouble, find a bug or notice
53+
anything that needs correction, please let us know by filing an issue.
6454

6555

6656
## Basic tour of the Bayesian Optimization package
@@ -154,125 +144,6 @@ for i, res in enumerate(optimizer.res):
154144
```
155145

156146

157-
#### 2.1 Changing bounds
158-
159-
During the optimization process you may realize the bounds chosen for some parameters are not adequate. For these situations you can invoke the method `set_bounds` to alter them. You can pass any combination of **existing** parameters and their associated new bounds.
160-
161-
162-
```python
163-
optimizer.set_bounds(new_bounds={"x": (-2, 3)})
164-
165-
optimizer.maximize(
166-
init_points=0,
167-
n_iter=5,
168-
)
169-
```
170-
171-
| iter | target | x | y |
172-
-------------------------------------------------
173-
| 6 | -5.145 | 2.115 | -0.2924 |
174-
| 7 | -5.379 | 2.337 | 0.04124 |
175-
| 8 | -3.581 | 1.874 | -0.03428 |
176-
| 9 | -2.624 | 1.702 | 0.1472 |
177-
| 10 | -1.762 | 1.442 | 0.1735 |
178-
=================================================
179-
180-
#### 2.2 Sequential Domain Reduction
181-
182-
Sometimes the initial boundaries specified for a problem are too wide, and adding points to improve the response surface in regions of the solution domain is extraneous. Other times the cost function is very expensive to compute, and minimizing the number of calls is extremely beneficial.
183-
184-
When it's worthwhile to converge on an optimal point quickly rather than try to find the optimal point, contracting the domain around the current optimal value as the search progresses can speed up the search progress considerably. Using the `SequentialDomainReductionTransformer` the bounds of the problem can be panned and zoomed dynamically in an attempt to improve convergence.
185-
186-
![sequential domain reduction](docsrc/static/sdr.png)
187-
188-
An example of using the `SequentialDomainReductionTransformer` is shown in the [domain reduction notebook](http://bayesian-optimization.github.io/BayesianOptimization/domain_reduction.html). More information about this method can be found in the paper ["On the robustness of a simple domain reduction scheme for simulation‐based optimization"](http://www.truegrid.com/srsm_revised.pdf).
189-
190-
### 3. Guiding the optimization
191-
192-
It is often the case that we have an idea of regions of the parameter space where the maximum of our function might lie. For these situations the `BayesianOptimization` object allows the user to specify points to be probed. By default these will be explored lazily (`lazy=True`), meaning these points will be evaluated only the next time you call `maximize`. This probing process happens before the gaussian process takes over.
193-
194-
Parameters can be passed as dictionaries or as an iterable.
195-
196-
```python
197-
optimizer.probe(
198-
params={"x": 0.5, "y": 0.7},
199-
lazy=True,
200-
)
201-
202-
optimizer.probe(
203-
params=[-0.3, 0.1],
204-
lazy=True,
205-
)
206-
207-
# Will probe only the two points specified above
208-
optimizer.maximize(init_points=0, n_iter=0)
209-
```
210-
211-
| iter | target | x | y |
212-
-------------------------------------------------
213-
| 11 | 0.66 | 0.5 | 0.7 |
214-
| 12 | 0.1 | -0.3 | 0.1 |
215-
=================================================
216-
217-
218-
### 4. Saving, loading and restarting
219-
220-
By default you can follow the progress of your optimization by setting `verbose>0` when instantiating the `BayesianOptimization` object. If you need more control over logging/alerting you will need to use an observer. For more information about observers checkout the advanced tour notebook. Here we will only see how to use the native `JSONLogger` object to save to and load progress from files.
221-
222-
#### 4.1 Saving progress
223-
224-
225-
```python
226-
from bayes_opt.logger import JSONLogger
227-
from bayes_opt.event import Events
228-
```
229-
230-
The observer paradigm works by:
231-
1. Instantiating an observer object.
232-
2. Tying the observer object to a particular event fired by an optimizer.
233-
234-
The `BayesianOptimization` object fires a number of internal events during optimization, in particular, everytime it probes the function and obtains a new parameter-target combination it will fire an `Events.OPTIMIZATION_STEP` event, which our logger will listen to.
235-
236-
**Caveat:** The logger will not look back at previously probed points.
237-
238-
239-
```python
240-
logger = JSONLogger(path="./logs.log")
241-
optimizer.subscribe(Events.OPTIMIZATION_STEP, logger)
242-
243-
# Results will be saved in ./logs.log
244-
optimizer.maximize(
245-
init_points=2,
246-
n_iter=3,
247-
)
248-
```
249-
250-
By default the previous data in the json file is removed. If you want to keep working with the same logger, the `reset` parameter in `JSONLogger` should be set to False.
251-
252-
#### 4.2 Loading progress
253-
254-
Naturally, if you stored progress you will be able to load that onto a new instance of `BayesianOptimization`. The easiest way to do it is by invoking the `load_logs` function, from the `util` submodule.
255-
256-
257-
```python
258-
from bayes_opt.util import load_logs
259-
260-
261-
new_optimizer = BayesianOptimization(
262-
f=black_box_function,
263-
pbounds={"x": (-2, 2), "y": (-2, 2)},
264-
verbose=2,
265-
random_state=7,
266-
)
267-
268-
# New optimizer is loaded with previously seen points
269-
load_logs(new_optimizer, logs=["./logs.log"]);
270-
```
271-
272-
## Next Steps
273-
274-
This introduction covered the most basic functionality of the package. Checkout the [basic-tour](http://bayesian-optimization.github.io/BayesianOptimization/basic-tour.html) and [advanced-tour](http://bayesian-optimization.github.io/BayesianOptimization/advanced-tour.html), where you will find detailed explanations and other more advanced functionality. Also, browse the [examples](http://bayesian-optimization.github.io/BayesianOptimization/examples.html) for implementation tips and ideas.
275-
276147
## Minutiae
277148

278149
### Citation
@@ -314,10 +185,3 @@ For constrained optimization:
314185
year={2014}
315186
}
316187
```
317-
318-
### References:
319-
* http://papers.nips.cc/paper/4522-practical-bayesian-optimization-of-machine-learning-algorithms.pdf
320-
* http://arxiv.org/pdf/1012.2599v1.pdf
321-
* http://www.gaussianprocess.org/gpml/
322-
* https://www.youtube.com/watch?v=vz3D36VXefI&index=10&list=PLE6Wd9FR--EdyJ5lbFl8UuGjecvVw66F6
323-

bayes_opt/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,15 @@
99
from bayes_opt.constraint import ConstraintModel
1010
from bayes_opt.domain_reduction import SequentialDomainReductionTransformer
1111
from bayes_opt.logger import JSONLogger, ScreenLogger
12+
from bayes_opt.target_space import TargetSpace
1213

1314
__version__ = importlib.metadata.version("bayesian-optimization")
1415

1516

1617
__all__ = [
1718
"acquisition",
1819
"BayesianOptimization",
20+
"TargetSpace",
1921
"ConstraintModel",
2022
"Events",
2123
"ScreenLogger",

0 commit comments

Comments
 (0)