
.. DO NOT EDIT.
.. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY.
.. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE:
.. "examples/examples_bbo/plot_black_box_optimization.py"
.. LINE NUMBERS ARE GIVEN BELOW.

.. only:: html

    .. note::
        :class: sphx-glr-download-link-note

        :ref:`Go to the end <sphx_glr_download_examples_examples_bbo_plot_black_box_optimization.py>`
        to download the full example code.

.. rst-class:: sphx-glr-example-title

.. _sphx_glr_examples_examples_bbo_plot_black_box_optimization.py:


Black-Box Optimization
======================

**Author(s)**: Romain Egele, Brett Eiffert.

In this tutorial, we introduce you to the notion of `black-box optimization (Wikipedia) <https://en.wikipedia.org/wiki/Derivative-free_optimization>`_ (a.k.a., derivative-free optimization) with DeepHyper.

Black-box optimization is a field of optimization research where an objective function :math:`f(x) = y \in \mathbb{R}` is optimized only based on input-output observations :math:`\{ (x_1,y_1), \ldots, (x_n, y_n) \}`.
 
Let's start by installing DeepHyper!

.. GENERATED FROM PYTHON SOURCE LINES 15-19

.. code-block:: bash

    %%bash
    pip install deephyper

.. GENERATED FROM PYTHON SOURCE LINES 22-23

Then, we can import it and check the installed version:

.. GENERATED FROM PYTHON SOURCE LINES 23-27

.. code-block:: Python


    import deephyper
    print(deephyper.__version__)





.. rst-class:: sphx-glr-script-out

 .. code-block:: none

    0.10.2




.. GENERATED FROM PYTHON SOURCE LINES 28-41

Optimization Problem
--------------------

The optimization problem is based  on two components:

1. The black-box function that we want to optimize.
2. The search space or domain of input variables over which we want to optimize.

Black-Box Function
~~~~~~~~~~~~~~~~~~

DeepHyper is developed to optimize black-box functions.
Here, we define the function :math:`f(x) = - x ^ 2` that we want to maximise (the maximum being :math:`f(x=0) = 0` on :math:`I_x = [-10;10]`). The black-box function ``f`` takes as input a ``job`` that follows a dictionary interface from which we retrieve the variables of interest.

.. GENERATED FROM PYTHON SOURCE LINES 43-46

.. code-block:: Python

    def f(job):
        return -job.parameters["x"] ** 2








.. GENERATED FROM PYTHON SOURCE LINES 47-51

Search Space of Input Variables
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

In this example, we have only one variable :math:`x` for the black-box functin :math:`f`. We empirically decide to optimize this variable $x$ on the interval :math:`I_x = [-10;10]`. To do so we use the :class:`deephyper.hpo.HpProblem` from DeepHyper and add a **real** hyperparameter by using a tuple of two floats.

.. GENERATED FROM PYTHON SOURCE LINES 53-63

.. code-block:: Python

    from deephyper.hpo import HpProblem


    problem = HpProblem()

    # Define the variable you want to optimize
    problem.add_hyperparameter((-10.0, 10.0), "x")

    problem





.. rst-class:: sphx-glr-script-out

 .. code-block:: none


    Configuration space object:
      Hyperparameters:
        x, Type: UniformFloat, Range: [-10.0, 10.0], Default: 0.0




.. GENERATED FROM PYTHON SOURCE LINES 64-73

Evaluator Interface
-------------------

DeepHyper uses an API called :class:`deephyper.evaluator.Evaluator` to distribute the computation of black-box functions and adapt to different backends (e.g., threads, processes, MPI, Ray). An ``Evaluator`` object wraps the black-box function ``f`` that we want to optimize. Then a ``method`` parameter is used to select the backend and ``method_kwargs`` defines some available options of this backend.


.. hint:: The ``method="thread"`` provides parallel computation only if the black-box is releasing the global interpretor lock (GIL). Therefore, if you want parallelism in Jupyter notebooks you should use the Ray evaluator (``method="ray"``) after installing Ray with ``pip install ray``.

It is possible to define callbacks to extend the behaviour of ``Evaluator`` each time a function-evaluation is launched or completed. In this example we use the :class:`deephyper.evaluator.callback.TqdmCallback` to follow the completed evaluations and the evolution of the objective with a progress-bar.

.. GENERATED FROM PYTHON SOURCE LINES 73-90

.. code-block:: Python


    from deephyper.evaluator import Evaluator
    from deephyper.evaluator.callback import TqdmCallback


    # define the evaluator to distribute the computation
    evaluator = Evaluator.create(
        f,
        method="thread",
        method_kwargs={
            "num_workers": 4,
            "callbacks": [TqdmCallback()]
        },
    )

    print(f"Evaluator has {evaluator.num_workers} available worker{'' if evaluator.num_workers == 1 else 's'}")





.. rst-class:: sphx-glr-script-out

 .. code-block:: none

    Evaluator has 4 available workers




.. GENERATED FROM PYTHON SOURCE LINES 91-95

Search Algorithm
----------------

The next step is to define the search algorithm that we want to use. Here, we choose :class:`deephyper.hpo.CBO` (Centralized Bayesian Optimization) which is a sampling based Bayesian optimization strategy. This algorithm has the advantage of being asynchronous thanks to a constant liar strategy which is crutial to keep a good utilization of the resources when the number of available workers increases.

.. GENERATED FROM PYTHON SOURCE LINES 95-106

.. code-block:: Python


    from deephyper.hpo import CBO

    # define your search
    def create_search():
        search = CBO(
            problem,
            acq_optimizer="ga",
        )
        return search








.. GENERATED FROM PYTHON SOURCE LINES 107-117

Then, to execute the search we provide two interfaces. 

Ask and Tell Interface
~~~~~~~~~~~~~~~~~~~~~~

The first interface is the classic ``configurations = search.ask(...)`` and ``search.tell(configurations_with_objective)``. 
In this case, you need to manage the computation of objectives yourself. This interface is more flexible.
However, asynchronous parallel evaluations are not managed for you.

Here is an example:

.. GENERATED FROM PYTHON SOURCE LINES 117-126

.. code-block:: Python


    search = create_search()
    max_evals = 100
    for i in range(max_evals):
        config = search.ask(1)[0]
        y = -config["x"] ** 2
        print(f"[{i=:03d}] >>> f(x={config['x']:.3f}) = {y:.3f}")
        search.tell([(config, y)])





.. rst-class:: sphx-glr-script-out

 .. code-block:: none

    [i=000] >>> f(x=-0.150) = -0.022
    [i=001] >>> f(x=-9.819) = -96.421
    [i=002] >>> f(x=3.473) = -12.065
    [i=003] >>> f(x=-1.518) = -2.305
    [i=004] >>> f(x=-3.703) = -13.709
    [i=005] >>> f(x=-0.002) = -0.000
    [i=006] >>> f(x=-0.501) = -0.251
    [i=007] >>> f(x=-0.878) = -0.771
    [i=008] >>> f(x=0.194) = -0.038
    [i=009] >>> f(x=-0.610) = -0.372
    [i=010] >>> f(x=-0.814) = -0.662
    [i=011] >>> f(x=-0.195) = -0.038
    [i=012] >>> f(x=-0.089) = -0.008
    [i=013] >>> f(x=-0.433) = -0.188
    [i=014] >>> f(x=1.639) = -2.685
    [i=015] >>> f(x=-1.606) = -2.580
    [i=016] >>> f(x=0.245) = -0.060
    [i=017] >>> f(x=-0.028) = -0.001
    [i=018] >>> f(x=-0.062) = -0.004
    [i=019] >>> f(x=0.003) = -0.000
    [i=020] >>> f(x=0.082) = -0.007
    [i=021] >>> f(x=-0.060) = -0.004
    [i=022] >>> f(x=0.091) = -0.008
    [i=023] >>> f(x=0.097) = -0.009
    [i=024] >>> f(x=0.394) = -0.155
    [i=025] >>> f(x=0.668) = -0.446
    [i=026] >>> f(x=0.085) = -0.007
    [i=027] >>> f(x=0.002) = -0.000
    [i=028] >>> f(x=-0.085) = -0.007
    [i=029] >>> f(x=-0.099) = -0.010
    [i=030] >>> f(x=-0.064) = -0.004
    [i=031] >>> f(x=-0.050) = -0.003
    [i=032] >>> f(x=-0.056) = -0.003
    [i=033] >>> f(x=-0.017) = -0.000
    [i=034] >>> f(x=0.443) = -0.196
    [i=035] >>> f(x=-0.216) = -0.046
    [i=036] >>> f(x=0.187) = -0.035
    [i=037] >>> f(x=-0.080) = -0.006
    [i=038] >>> f(x=-0.042) = -0.002
    [i=039] >>> f(x=0.084) = -0.007
    [i=040] >>> f(x=-0.010) = -0.000
    [i=041] >>> f(x=0.021) = -0.000
    [i=042] >>> f(x=0.021) = -0.000
    [i=043] >>> f(x=0.022) = -0.000
    [i=044] >>> f(x=-0.305) = -0.093
    [i=045] >>> f(x=0.262) = -0.069
    [i=046] >>> f(x=-0.007) = -0.000
    [i=047] >>> f(x=0.023) = -0.001
    [i=048] >>> f(x=0.031) = -0.001
    [i=049] >>> f(x=0.030) = -0.001
    [i=050] >>> f(x=0.026) = -0.001
    [i=051] >>> f(x=0.022) = -0.000
    [i=052] >>> f(x=0.016) = -0.000
    [i=053] >>> f(x=0.020) = -0.000
    [i=054] >>> f(x=0.287) = -0.082
    [i=055] >>> f(x=-0.123) = -0.015
    [i=056] >>> f(x=0.102) = -0.010
    [i=057] >>> f(x=0.015) = -0.000
    [i=058] >>> f(x=-0.008) = -0.000
    [i=059] >>> f(x=-0.007) = -0.000
    [i=060] >>> f(x=-0.006) = -0.000
    [i=061] >>> f(x=-0.019) = -0.000
    [i=062] >>> f(x=-0.013) = -0.000
    [i=063] >>> f(x=-0.008) = -0.000
    [i=064] >>> f(x=0.132) = -0.017
    [i=065] >>> f(x=0.016) = -0.000
    [i=066] >>> f(x=0.016) = -0.000
    [i=067] >>> f(x=0.013) = -0.000
    [i=068] >>> f(x=0.015) = -0.000
    [i=069] >>> f(x=-0.011) = -0.000
    [i=070] >>> f(x=-0.006) = -0.000
    [i=071] >>> f(x=0.008) = -0.000
    [i=072] >>> f(x=0.012) = -0.000
    [i=073] >>> f(x=0.014) = -0.000
    [i=074] >>> f(x=0.033) = -0.001
    [i=075] >>> f(x=0.041) = -0.002
    [i=076] >>> f(x=0.004) = -0.000
    [i=077] >>> f(x=0.010) = -0.000
    [i=078] >>> f(x=0.007) = -0.000
    [i=079] >>> f(x=0.009) = -0.000
    [i=080] >>> f(x=0.007) = -0.000
    [i=081] >>> f(x=0.005) = -0.000
    [i=082] >>> f(x=0.004) = -0.000
    [i=083] >>> f(x=0.005) = -0.000
    [i=084] >>> f(x=0.050) = -0.002
    [i=085] >>> f(x=-0.010) = -0.000
    [i=086] >>> f(x=0.011) = -0.000
    [i=087] >>> f(x=0.000) = -0.000
    [i=088] >>> f(x=-0.010) = -0.000
    [i=089] >>> f(x=-0.011) = -0.000
    [i=090] >>> f(x=-0.010) = -0.000
    [i=091] >>> f(x=-0.009) = -0.000
    [i=092] >>> f(x=0.003) = -0.000
    [i=093] >>> f(x=-0.008) = -0.000
    [i=094] >>> f(x=0.063) = -0.004
    [i=095] >>> f(x=-0.005) = -0.000
    [i=096] >>> f(x=-0.007) = -0.000
    [i=097] >>> f(x=0.003) = -0.000
    [i=098] >>> f(x=-0.001) = -0.000
    [i=099] >>> f(x=-0.001) = -0.000




.. GENERATED FROM PYTHON SOURCE LINES 127-132

Search Interface
~~~~~~~~~~~~~~~~

The second interface is ``results = search.search(evaluator, ...)`` that is binded to the ``evaluator`` and manages the loop for asynchronous parallel evaluations for you.
We can execute the search for a given number of iterations by using the ``search.search(evaluator, max_evals=...)``. It is also possible to use the ``timeout`` parameter if one needs a specific time budget (e.g., restricted computational time in machine learning competitions, allocation time in HPC).

.. GENERATED FROM PYTHON SOURCE LINES 132-136

.. code-block:: Python


    search = create_search()
    results = search.search(evaluator, max_evals)





.. rst-class:: sphx-glr-script-out

 .. code-block:: none

      0%|          | 0/100 [00:00<?, ?it/s]      1%|          | 1/100 [00:00<00:00, 5370.43it/s, failures=0, objective=-0.51]      2%|▏         | 2/100 [00:00<00:00, 4888.47it/s, failures=0, objective=-0.51]      3%|▎         | 3/100 [00:00<00:00, 5745.62it/s, failures=0, objective=-0.51]      4%|▍         | 4/100 [00:00<00:00, 6708.20it/s, failures=0, objective=-0.51]      5%|▌         | 5/100 [00:00<00:16,  5.72it/s, failures=0, objective=-0.51]        5%|▌         | 5/100 [00:00<00:16,  5.72it/s, failures=0, objective=-0.51]      6%|▌         | 6/100 [00:00<00:16,  5.72it/s, failures=0, objective=-0.51]      7%|▋         | 7/100 [00:00<00:16,  5.72it/s, failures=0, objective=-0.51]      8%|▊         | 8/100 [00:00<00:16,  5.72it/s, failures=0, objective=-0.51]      9%|▉         | 9/100 [00:01<00:17,  5.34it/s, failures=0, objective=-0.51]      9%|▉         | 9/100 [00:01<00:17,  5.34it/s, failures=0, objective=-0.51]     10%|█         | 10/100 [00:01<00:16,  5.34it/s, failures=0, objective=-0.51]     11%|█         | 11/100 [00:01<00:16,  5.34it/s, failures=0, objective=-0.51]     12%|█▏        | 12/100 [00:01<00:16,  5.34it/s, failures=0, objective=-0.51]     13%|█▎        | 13/100 [00:02<00:16,  5.18it/s, failures=0, objective=-0.51]     13%|█▎        | 13/100 [00:02<00:16,  5.18it/s, failures=0, objective=-0.26]     14%|█▍        | 14/100 [00:02<00:16,  5.18it/s, failures=0, objective=-0.0695]     15%|█▌        | 15/100 [00:02<00:16,  5.18it/s, failures=0, objective=-0.000646]     16%|█▌        | 16/100 [00:02<00:16,  5.18it/s, failures=0, objective=-0.000646]     17%|█▋        | 17/100 [00:03<00:16,  5.14it/s, failures=0, objective=-0.000646]     17%|█▋        | 17/100 [00:03<00:16,  5.14it/s, failures=0, objective=-0.000646]     18%|█▊        | 18/100 [00:03<00:15,  5.14it/s, failures=0, objective=-0.000646]     19%|█▉        | 19/100 [00:03<00:15,  5.14it/s, failures=0, objective=-0.000646]     20%|██        | 20/100 [00:03<00:15,  5.14it/s, failures=0, objective=-0.000646]     21%|██        | 21/100 [00:04<00:15,  5.13it/s, failures=0, objective=-0.000646]     21%|██        | 21/100 [00:04<00:15,  5.13it/s, failures=0, objective=-0.000646]     22%|██▏       | 22/100 [00:04<00:15,  5.13it/s, failures=0, objective=-0.000646]     23%|██▎       | 23/100 [00:04<00:15,  5.13it/s, failures=0, objective=-0.000406]     24%|██▍       | 24/100 [00:04<00:14,  5.13it/s, failures=0, objective=-0.000406]     25%|██▌       | 25/100 [00:04<00:14,  5.12it/s, failures=0, objective=-0.000406]     25%|██▌       | 25/100 [00:04<00:14,  5.12it/s, failures=0, objective=-0.000406]     26%|██▌       | 26/100 [00:04<00:14,  5.12it/s, failures=0, objective=-0.000406]     27%|██▋       | 27/100 [00:04<00:14,  5.12it/s, failures=0, objective=-0.000406]     28%|██▊       | 28/100 [00:04<00:14,  5.12it/s, failures=0, objective=-0.000406]     29%|██▉       | 29/100 [00:05<00:13,  5.11it/s, failures=0, objective=-0.000406]     29%|██▉       | 29/100 [00:05<00:13,  5.11it/s, failures=0, objective=-0.000406]     30%|███       | 30/100 [00:05<00:13,  5.11it/s, failures=0, objective=-0.000406]     31%|███       | 31/100 [00:05<00:13,  5.11it/s, failures=0, objective=-0.000406]     32%|███▏      | 32/100 [00:06<00:13,  5.02it/s, failures=0, objective=-0.000406]     32%|███▏      | 32/100 [00:06<00:13,  5.02it/s, failures=0, objective=-0.000406]     33%|███▎      | 33/100 [00:06<00:13,  5.14it/s, failures=0, objective=-0.000406]     33%|███▎      | 33/100 [00:06<00:13,  5.14it/s, failures=0, objective=-0.000406]     34%|███▍      | 34/100 [00:06<00:12,  5.14it/s, failures=0, objective=-0.000406]     35%|███▌      | 35/100 [00:06<00:12,  5.14it/s, failures=0, objective=-0.000406]     36%|███▌      | 36/100 [00:07<00:12,  5.00it/s, failures=0, objective=-0.000406]     36%|███▌      | 36/100 [00:07<00:12,  5.00it/s, failures=0, objective=-0.000406]     37%|███▋      | 37/100 [00:07<00:12,  5.14it/s, failures=0, objective=-0.000406]     37%|███▋      | 37/100 [00:07<00:12,  5.14it/s, failures=0, objective=-0.000406]     38%|███▊      | 38/100 [00:07<00:12,  5.14it/s, failures=0, objective=-0.000406]     39%|███▉      | 39/100 [00:07<00:11,  5.14it/s, failures=0, objective=-0.000406]     40%|████      | 40/100 [00:07<00:12,  4.80it/s, failures=0, objective=-0.000406]     40%|████      | 40/100 [00:07<00:12,  4.80it/s, failures=0, objective=-0.000406]     41%|████      | 41/100 [00:08<00:11,  4.98it/s, failures=0, objective=-0.000406]     41%|████      | 41/100 [00:08<00:11,  4.98it/s, failures=0, objective=-0.000406]     42%|████▏     | 42/100 [00:08<00:11,  4.98it/s, failures=0, objective=-0.000406]     43%|████▎     | 43/100 [00:08<00:11,  4.98it/s, failures=0, objective=-0.000406]     44%|████▍     | 44/100 [00:08<00:11,  4.87it/s, failures=0, objective=-0.000406]     44%|████▍     | 44/100 [00:08<00:11,  4.87it/s, failures=0, objective=-0.000406]     45%|████▌     | 45/100 [00:08<00:10,  5.05it/s, failures=0, objective=-0.000406]     45%|████▌     | 45/100 [00:08<00:10,  5.05it/s, failures=0, objective=-0.000406]     46%|████▌     | 46/100 [00:08<00:10,  5.05it/s, failures=0, objective=-0.000406]     47%|████▋     | 47/100 [00:08<00:10,  5.05it/s, failures=0, objective=-0.000406]     48%|████▊     | 48/100 [00:09<00:10,  4.92it/s, failures=0, objective=-0.000406]     48%|████▊     | 48/100 [00:09<00:10,  4.92it/s, failures=0, objective=-0.000406]     49%|████▉     | 49/100 [00:09<00:09,  5.10it/s, failures=0, objective=-0.000406]     49%|████▉     | 49/100 [00:09<00:09,  5.10it/s, failures=0, objective=-0.000229]     50%|█████     | 50/100 [00:09<00:09,  5.10it/s, failures=0, objective=-0.000229]     51%|█████     | 51/100 [00:09<00:09,  5.10it/s, failures=0, objective=-0.000229]     52%|█████▏    | 52/100 [00:10<00:09,  4.95it/s, failures=0, objective=-0.000229]     52%|█████▏    | 52/100 [00:10<00:09,  4.95it/s, failures=0, objective=-0.000229]     53%|█████▎    | 53/100 [00:10<00:09,  5.12it/s, failures=0, objective=-0.000229]     53%|█████▎    | 53/100 [00:10<00:09,  5.12it/s, failures=0, objective=-0.000229]     54%|█████▍    | 54/100 [00:10<00:08,  5.12it/s, failures=0, objective=-0.000229]     55%|█████▌    | 55/100 [00:10<00:08,  5.12it/s, failures=0, objective=-0.000229]     56%|█████▌    | 56/100 [00:11<00:08,  4.95it/s, failures=0, objective=-0.000229]     56%|█████▌    | 56/100 [00:11<00:08,  4.95it/s, failures=0, objective=-0.000229]     57%|█████▋    | 57/100 [00:11<00:08,  5.12it/s, failures=0, objective=-0.000229]     57%|█████▋    | 57/100 [00:11<00:08,  5.12it/s, failures=0, objective=-1.36e-7]      58%|█████▊    | 58/100 [00:11<00:08,  5.12it/s, failures=0, objective=-1.36e-7]     59%|█████▉    | 59/100 [00:11<00:08,  5.12it/s, failures=0, objective=-1.36e-7]     60%|██████    | 60/100 [00:11<00:08,  4.93it/s, failures=0, objective=-1.36e-7]     60%|██████    | 60/100 [00:11<00:08,  4.93it/s, failures=0, objective=-1.36e-7]     61%|██████    | 61/100 [00:12<00:07,  5.12it/s, failures=0, objective=-1.36e-7]     61%|██████    | 61/100 [00:12<00:07,  5.12it/s, failures=0, objective=-1.36e-7]     62%|██████▏   | 62/100 [00:12<00:07,  5.12it/s, failures=0, objective=-1.36e-7]     63%|██████▎   | 63/100 [00:12<00:07,  5.12it/s, failures=0, objective=-1.36e-7]     64%|██████▍   | 64/100 [00:12<00:07,  4.95it/s, failures=0, objective=-1.36e-7]     64%|██████▍   | 64/100 [00:12<00:07,  4.95it/s, failures=0, objective=-1.36e-7]     65%|██████▌   | 65/100 [00:12<00:06,  5.12it/s, failures=0, objective=-1.36e-7]     65%|██████▌   | 65/100 [00:12<00:06,  5.12it/s, failures=0, objective=-1.36e-7]     66%|██████▌   | 66/100 [00:12<00:06,  5.12it/s, failures=0, objective=-1.36e-7]     67%|██████▋   | 67/100 [00:12<00:06,  5.12it/s, failures=0, objective=-1.36e-7]     68%|██████▊   | 68/100 [00:13<00:06,  4.94it/s, failures=0, objective=-1.36e-7]     68%|██████▊   | 68/100 [00:13<00:06,  4.94it/s, failures=0, objective=-1.36e-7]     69%|██████▉   | 69/100 [00:13<00:06,  5.11it/s, failures=0, objective=-1.36e-7]     69%|██████▉   | 69/100 [00:13<00:06,  5.11it/s, failures=0, objective=-1.36e-7]     70%|███████   | 70/100 [00:13<00:05,  5.11it/s, failures=0, objective=-1.36e-7]     71%|███████   | 71/100 [00:13<00:05,  5.11it/s, failures=0, objective=-1.36e-7]     72%|███████▏  | 72/100 [00:14<00:05,  4.91it/s, failures=0, objective=-1.36e-7]     72%|███████▏  | 72/100 [00:14<00:05,  4.91it/s, failures=0, objective=-1.36e-7]     73%|███████▎  | 73/100 [00:14<00:05,  4.82it/s, failures=0, objective=-1.36e-7]     73%|███████▎  | 73/100 [00:14<00:05,  4.82it/s, failures=0, objective=-1.36e-7]     74%|███████▍  | 74/100 [00:14<00:05,  4.82it/s, failures=0, objective=-1.36e-7]     75%|███████▌  | 75/100 [00:14<00:05,  4.82it/s, failures=0, objective=-1.36e-7]     76%|███████▌  | 76/100 [00:15<00:05,  4.77it/s, failures=0, objective=-1.36e-7]     76%|███████▌  | 76/100 [00:15<00:05,  4.77it/s, failures=0, objective=-1.36e-7]     77%|███████▋  | 77/100 [00:15<00:04,  4.95it/s, failures=0, objective=-1.36e-7]     77%|███████▋  | 77/100 [00:15<00:04,  4.95it/s, failures=0, objective=-1.36e-7]     78%|███████▊  | 78/100 [00:15<00:04,  4.95it/s, failures=0, objective=-1.36e-7]     79%|███████▉  | 79/100 [00:15<00:04,  4.95it/s, failures=0, objective=-1.36e-7]     80%|████████  | 80/100 [00:15<00:04,  4.85it/s, failures=0, objective=-1.36e-7]     80%|████████  | 80/100 [00:15<00:04,  4.85it/s, failures=0, objective=-1.36e-7]     81%|████████  | 81/100 [00:16<00:03,  5.04it/s, failures=0, objective=-1.36e-7]     81%|████████  | 81/100 [00:16<00:03,  5.04it/s, failures=0, objective=-1.36e-7]     82%|████████▏ | 82/100 [00:16<00:03,  5.04it/s, failures=0, objective=-1.36e-7]     83%|████████▎ | 83/100 [00:16<00:03,  5.04it/s, failures=0, objective=-1.36e-7]     84%|████████▍ | 84/100 [00:16<00:03,  4.88it/s, failures=0, objective=-1.36e-7]     84%|████████▍ | 84/100 [00:16<00:03,  4.88it/s, failures=0, objective=-1.36e-7]     85%|████████▌ | 85/100 [00:16<00:02,  5.06it/s, failures=0, objective=-1.36e-7]     85%|████████▌ | 85/100 [00:16<00:02,  5.06it/s, failures=0, objective=-1.36e-7]     86%|████████▌ | 86/100 [00:16<00:02,  5.06it/s, failures=0, objective=-1.36e-7]     87%|████████▋ | 87/100 [00:16<00:02,  5.06it/s, failures=0, objective=-1.36e-7]     88%|████████▊ | 88/100 [00:17<00:02,  4.90it/s, failures=0, objective=-1.36e-7]     88%|████████▊ | 88/100 [00:17<00:02,  4.90it/s, failures=0, objective=-1.36e-7]     89%|████████▉ | 89/100 [00:17<00:02,  5.08it/s, failures=0, objective=-1.36e-7]     89%|████████▉ | 89/100 [00:17<00:02,  5.08it/s, failures=0, objective=-1.36e-7]     90%|█████████ | 90/100 [00:17<00:01,  5.08it/s, failures=0, objective=-1.36e-7]     91%|█████████ | 91/100 [00:17<00:01,  5.08it/s, failures=0, objective=-1.36e-7]     92%|█████████▏| 92/100 [00:18<00:01,  4.91it/s, failures=0, objective=-1.36e-7]     92%|█████████▏| 92/100 [00:18<00:01,  4.91it/s, failures=0, objective=-1.36e-7]     93%|█████████▎| 93/100 [00:18<00:01,  5.09it/s, failures=0, objective=-1.36e-7]     93%|█████████▎| 93/100 [00:18<00:01,  5.09it/s, failures=0, objective=-1.36e-7]     94%|█████████▍| 94/100 [00:18<00:01,  5.09it/s, failures=0, objective=-1.36e-7]     95%|█████████▌| 95/100 [00:18<00:00,  5.09it/s, failures=0, objective=-1.36e-7]     96%|█████████▌| 96/100 [00:19<00:00,  4.92it/s, failures=0, objective=-1.36e-7]     96%|█████████▌| 96/100 [00:19<00:00,  4.92it/s, failures=0, objective=-1.36e-7]     97%|█████████▋| 97/100 [00:19<00:00,  5.09it/s, failures=0, objective=-1.36e-7]     97%|█████████▋| 97/100 [00:19<00:00,  5.09it/s, failures=0, objective=-1.36e-7]     98%|█████████▊| 98/100 [00:19<00:00,  5.09it/s, failures=0, objective=-1.36e-7]     99%|█████████▉| 99/100 [00:19<00:00,  5.09it/s, failures=0, objective=-1.36e-7]    100%|██████████| 100/100 [00:19<00:00,  4.91it/s, failures=0, objective=-1.36e-7]    100%|██████████| 100/100 [00:19<00:00,  4.91it/s, failures=0, objective=-1.36e-7]    100%|██████████| 100/100 [00:19<00:00,  5.02it/s, failures=0, objective=-1.36e-7]




.. GENERATED FROM PYTHON SOURCE LINES 137-145

Finally, let us visualize the results. The ``search(...)`` returns a DataFrame also saved locally under ``results.csv`` (in case of crash we don't want to lose the possibly expensive evaluations already performed).

The DataFrame contains as columns:

1. the optimized hyperparameters: such as :math:`x` with name ``p:x``.
2. the ``objective`` **maximised** which directly match the results of the :math:`f` function in our example.
3. the ``job_id`` of each evaluated function (increased incrementally following the order of created evaluations).
4. the time of creation/collection of each task ``timestamp_submit`` and ``timestamp_gather`` respectively (in secondes, since the creation of the Evaluator).

.. GENERATED FROM PYTHON SOURCE LINES 147-149

.. code-block:: Python

    results






.. raw:: html

    <div class="output_subarea output_html rendered_html output_result">
    <div>
    <style scoped>
        .dataframe tbody tr th:only-of-type {
            vertical-align: middle;
        }

        .dataframe tbody tr th {
            vertical-align: top;
        }

        .dataframe thead th {
            text-align: right;
        }
    </style>
    <table border="1" class="dataframe">
      <thead>
        <tr style="text-align: right;">
          <th></th>
          <th>p:x</th>
          <th>objective</th>
          <th>job_id</th>
          <th>job_status</th>
          <th>m:timestamp_submit</th>
          <th>m:timestamp_gather</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <th>0</th>
          <td>0.714013</td>
          <td>-0.509815</td>
          <td>0</td>
          <td>DONE</td>
          <td>16.055601</td>
          <td>16.056108</td>
        </tr>
        <tr>
          <th>1</th>
          <td>-7.299946</td>
          <td>-53.289215</td>
          <td>2</td>
          <td>DONE</td>
          <td>16.055627</td>
          <td>16.062735</td>
        </tr>
        <tr>
          <th>2</th>
          <td>2.997893</td>
          <td>-8.987361</td>
          <td>1</td>
          <td>DONE</td>
          <td>16.055620</td>
          <td>16.062853</td>
        </tr>
        <tr>
          <th>3</th>
          <td>8.294617</td>
          <td>-68.800670</td>
          <td>3</td>
          <td>DONE</td>
          <td>16.055632</td>
          <td>16.062946</td>
        </tr>
        <tr>
          <th>4</th>
          <td>5.378610</td>
          <td>-28.929448</td>
          <td>4</td>
          <td>DONE</td>
          <td>16.936808</td>
          <td>16.937233</td>
        </tr>
        <tr>
          <th>...</th>
          <td>...</td>
          <td>...</td>
          <td>...</td>
          <td>...</td>
          <td>...</td>
          <td>...</td>
        </tr>
        <tr>
          <th>98</th>
          <td>-0.260893</td>
          <td>-0.068065</td>
          <td>96</td>
          <td>DONE</td>
          <td>35.183628</td>
          <td>35.345498</td>
        </tr>
        <tr>
          <th>99</th>
          <td>-0.330581</td>
          <td>-0.109284</td>
          <td>99</td>
          <td>DONE</td>
          <td>35.345077</td>
          <td>35.986678</td>
        </tr>
        <tr>
          <th>100</th>
          <td>-0.267424</td>
          <td>-0.071516</td>
          <td>102</td>
          <td>DONE</td>
          <td>35.986451</td>
          <td>36.149026</td>
        </tr>
        <tr>
          <th>101</th>
          <td>-0.047429</td>
          <td>-0.002249</td>
          <td>100</td>
          <td>DONE</td>
          <td>35.986431</td>
          <td>36.149059</td>
        </tr>
        <tr>
          <th>102</th>
          <td>-0.062054</td>
          <td>-0.003851</td>
          <td>101</td>
          <td>DONE</td>
          <td>35.986446</td>
          <td>36.149077</td>
        </tr>
      </tbody>
    </table>
    <p>103 rows × 6 columns</p>
    </div>
    </div>
    <br />
    <br />

.. GENERATED FROM PYTHON SOURCE LINES 150-151

To get the parameters at the observed maximum value we can use the :func:`deephyper.analysis.hpo.parameters_at_max`:

.. GENERATED FROM PYTHON SOURCE LINES 151-160

.. code-block:: Python


    from deephyper.analysis.hpo import parameters_at_max


    parameters, objective = parameters_at_max(results)
    print("\nOptimum values")
    print("x:", parameters["x"])
    print("objective:", objective)





.. rst-class:: sphx-glr-script-out

 .. code-block:: none


    Optimum values
    x: -0.00036876827022958025
    objective: -1.3599003712811672e-07




.. GENERATED FROM PYTHON SOURCE LINES 161-162

We can also plot the evolution of the objective to verify that we converge correctly toward :math:`0`.

.. GENERATED FROM PYTHON SOURCE LINES 162-174

.. code-block:: Python


    import matplotlib.pyplot as plt
    from deephyper.analysis.hpo import plot_search_trajectory_single_objective_hpo


    WIDTH_PLOTS = 8
    HEIGHT_PLOTS = WIDTH_PLOTS / 1.618

    fig, ax = plt.subplots(figsize=(WIDTH_PLOTS, HEIGHT_PLOTS))
    plot_search_trajectory_single_objective_hpo(results, mode="min", ax=ax)
    _ = plt.title("Search Trajectory")
    _ = plt.yscale("log")



.. image-sg:: /examples/examples_bbo/images/sphx_glr_plot_black_box_optimization_001.png
   :alt: Search Trajectory
   :srcset: /examples/examples_bbo/images/sphx_glr_plot_black_box_optimization_001.png
   :class: sphx-glr-single-img






.. rst-class:: sphx-glr-timing

   **Total running time of the script:** (0 minutes 37.458 seconds)


.. _sphx_glr_download_examples_examples_bbo_plot_black_box_optimization.py:

.. only:: html

  .. container:: sphx-glr-footer sphx-glr-footer-example

    .. container:: sphx-glr-download sphx-glr-download-jupyter

      :download:`Download Jupyter notebook: plot_black_box_optimization.ipynb <plot_black_box_optimization.ipynb>`

    .. container:: sphx-glr-download sphx-glr-download-python

      :download:`Download Python source code: plot_black_box_optimization.py <plot_black_box_optimization.py>`

    .. container:: sphx-glr-download sphx-glr-download-zip

      :download:`Download zipped: plot_black_box_optimization.zip <plot_black_box_optimization.zip>`


.. only:: html

 .. rst-class:: sphx-glr-signature

    `Gallery generated by Sphinx-Gallery <https://sphinx-gallery.github.io>`_
