Example for using the multi target mode for the objective

Example for using the multi target mode for the objective. It uses a desirability value to handle several targets.

This example assumes some basic familiarity with using BayBE. We thus refer to campaign for a basic example.

Necessary imports for this example

from baybe import Campaign
from baybe.objective import Objective
from baybe.parameters import CategoricalParameter, NumericalDiscreteParameter
from baybe.searchspace import SearchSpace
from baybe.targets import NumericalTarget
from baybe.utils.dataframe import add_fake_results

Experiment setup and creating the searchspace

Categorical_1 = CategoricalParameter("Cat_1", values=["22", "33"], encoding="OHE")
Categorical_2 = CategoricalParameter(
    "Cat_2",
    values=["very bad", "bad", "OK", "good", "very good"],
    encoding="INT",
)
Num_disc_1 = NumericalDiscreteParameter(
    "Num_disc_1", values=[1, 2, 3, 4, 6, 8, 10], tolerance=0.3
)
Num_disc_2 = NumericalDiscreteParameter(
    "Num_disc_2", values=[-1, -3, -6, -9], tolerance=0.3
)
parameters = [Categorical_1, Categorical_2, Num_disc_1, Num_disc_2]
searchspace = SearchSpace.from_product(parameters=parameters)

Defining the targets

The multi target mode is handled when creating the objective object. Thus we first need to define the different targets.

This examples has different targets with different modes. The first target is maximized and while the second one is minimized. Note that in this multi target mode, the user must specify bounds for each target.

Target_1 = NumericalTarget(
    name="Target_1", mode="MAX", bounds=(0, 100), transformation="LINEAR"
)
Target_2 = NumericalTarget(
    name="Target_2", mode="MIN", bounds=(0, 100), transformation="LINEAR"
)

For each target it is also possible to specify a target_transform function. A detailed discussion of this functionality can be found at the end of this example.

In this example, define a third target working with the mode MATCH. We furthermore use target_transform="BELL".

Target_3 = NumericalTarget(
    name="Target_3", mode="MATCH", bounds=(45, 55), transformation="BELL"
)

Note that the MATCH mode seeks to have the target at the mean between the two bounds. For example, choosing 95 and 105 will lead the algorithm seeking 100 as the optimal value. Thus, using the bounds, it is possible to control both the match target and the range around this target that is considered viable.

Creating the objective

Now to work with these three targets the objective object must be properly created. The mode is set to DESIRABILITY and the targets are described in a list.

targets = [Target_1, Target_2, Target_3]

As the recommender requires a single function, the different targets need to be combined. Thus, a combine_function is used to create a single target out of the several targets given. The combine function can either be the mean MEAN or the geometric mean GEOM_MEAN. Per default, GEOM_MEAN is used. Weights for each target can also be specified as a list of floats in the arguments Per default, weights are equally distributed between all targets and are normalized internally. It is thus not necessary to handle normalization or scaling.

objective = Objective(
    mode="DESIRABILITY",
    targets=targets,
    weights=[20, 20, 60],
    combine_func="MEAN",
)
print(objective)
Objective
         
 Mode: DESIRABILITY
         
 Targets 
               Type      Name   Mode  Lower_Bound  Upper_Bound Transformation  \
 0  NumericalTarget  Target_1    MAX          0.0        100.0         LINEAR   
 1  NumericalTarget  Target_2    MIN          0.0        100.0         LINEAR   
 2  NumericalTarget  Target_3  MATCH         45.0         55.0           BELL   
 
    Weight  
 0    20.0  
 1    20.0  
 2    60.0  
         
 Combine Function: MEAN

Creating and printing the campaign

campaign = Campaign(searchspace=searchspace, objective=objective)
print(campaign)
Campaign
         
 Meta Data
 Batches Done: 0

Fits Done: 0

 Search Space
          
  Search Space Type: DISCRETE
  
  Discrete Search Space
               
   Discrete Parameters
            Name                        Type  Num_Values                 Encoding
   0       Cat_1        CategoricalParameter           2  CategoricalEncoding.OHE
   1       Cat_2        CategoricalParameter           5  CategoricalEncoding.INT
   2  Num_disc_1  NumericalDiscreteParameter           7                     None
   3  Num_disc_2  NumericalDiscreteParameter           4                     None
               
   Experimental Representation
               
   Cat_1      Cat_2  Num_disc_1  Num_disc_2
   0      22   very bad         1.0        -9.0
   1      22   very bad         1.0        -6.0
   2      22   very bad         1.0        -3.0
   ..    ...        ...         ...         ...
   277    33  very good        10.0        -6.0
   278    33  very good        10.0        -3.0
   279    33  very good        10.0        -1.0
   
   [280 rows x 4 columns]
   
   Metadata:

was_recommended: 0/280

was_measured: 0/280

dont_recommend: 0/280

   Constraints
   Empty DataFrame
   Columns: []
   Index: []
               
   Computational Representation
               
    Cat_1_22  Cat_1_33  ...  Num_disc_1  Num_disc_2
   0           1         0  ...         1.0        -9.0
   1           1         0  ...         1.0        -6.0
   2           1         0  ...         1.0        -3.0
   ..        ...       ...  ...         ...         ...
   277         0         1  ...        10.0        -6.0
   278         0         1  ...        10.0        -3.0
   279         0         1  ...        10.0        -1.0
   
   [280 rows x 5 columns]
 
 Objective
          
  Mode: DESIRABILITY
          
  Targets 
                Type      Name   Mode  Lower_Bound  Upper_Bound Transformation  \
  0  NumericalTarget  Target_1    MAX          0.0        100.0         LINEAR   
  1  NumericalTarget  Target_2    MIN          0.0        100.0         LINEAR   
  2  NumericalTarget  Target_3  MATCH         45.0         55.0           BELL   
  
     Weight  
  0    20.0  
  1    20.0  
  2    60.0  
          
  Combine Function: MEAN
 
 TwoPhaseMetaRecommender(allow_repeated_recommendations=None,

allow_recommending_already_measured=None, initial_recommender=RandomRecommender(allow_repeated_recommendations=False, allow_recommending_already_measured=True), recommender=SequentialGreedyRecommender(allow_repeated_recommendations=False, allow_recommending_already_measured=True, surrogate_model=GaussianProcessSurrogate(model_params={}, _model=None), acquisition_function_cls=’qEI’, _acquisition_function=None, hybrid_sampler=’None’, sampling_percentage=1.0), switch_after=1)

Performing some iterations

The following loop performs some recommendations and adds fake results. It also prints what happens to internal data.

N_ITERATIONS = 3
for kIter in range(N_ITERATIONS):
    print(f"\n\n#### ITERATION {kIter+1} ####")

    rec = campaign.recommend(batch_size=3)
    print("\nRecommended measurements:\n", rec)

    add_fake_results(rec, campaign)
    print("\nRecommended measurements with fake measured results:\n", rec)

    campaign.add_measurements(rec)

    print("\n\nInternal measurement dataframe computational representation Y:\n")
    print(campaign._measurements_targets_comp)
#### ITERATION 1 ####

Recommended measurements:
     Cat_1     Cat_2  Num_disc_1  Num_disc_2
48     22       bad         8.0        -9.0
103    22      good         6.0        -1.0
14     22  very bad         4.0        -3.0

Recommended measurements with fake measured results:
     Cat_1     Cat_2  Num_disc_1  Num_disc_2   Target_1   Target_2   Target_3
48     22       bad         8.0        -9.0  95.125685  59.299098  56.142094
103    22      good         6.0        -1.0  78.092951  43.348377  55.036203
14     22  very bad         4.0        -3.0  11.706424  26.054258  55.673975


Internal measurement dataframe computational representation Y:

   Comp_Target
0     0.553799
1     0.630773
2     0.486455


#### ITERATION 2 ####



Recommended measurements:
       Cat_1      Cat_2  Num_disc_1  Num_disc_2
index                                         
99       22       good         4.0        -1.0
107      22       good         8.0        -1.0
131      22  very good         6.0        -1.0

Recommended measurements with fake measured results:
       Cat_1      Cat_2  Num_disc_1  Num_disc_2   Target_1   Target_2  \
index                                                                  
99       22       good         4.0        -1.0  73.781845  15.710369   
107      22       good         8.0        -1.0  53.917206   1.300144   
131      22  very good         6.0        -1.0  60.432490  90.678415   

        Target_3  
index             
99     54.211456  
107    52.238506  
131    51.109420  


Internal measurement dataframe computational representation Y:

   Comp_Target
0     0.553799
1     0.630773
2     0.486455
3     0.736962
4     0.848018
5     0.724919


#### ITERATION 3 ####

Recommended measurements:
       Cat_1      Cat_2  Num_disc_1  Num_disc_2
index                                         
55       22        bad        10.0        -1.0
134      22  very good         8.0        -3.0
139      22  very good        10.0        -1.0

Recommended measurements with fake measured results:
       Cat_1      Cat_2  Num_disc_1  Num_disc_2   Target_1   Target_2  \
index                                                                  
55       22        bad        10.0        -1.0   6.296359  10.633811   
134      22  very good         8.0        -3.0  39.891538  87.381180   
139      22  very good        10.0        -1.0   8.648764  94.758383   

        Target_3  
index             
55     54.485167  
134    56.289764  
139    52.813216  


Internal measurement dataframe computational representation Y:

   Comp_Target
0     0.553799
1     0.630773
2     0.486455
3     0.736962
4     0.848018
5     0.724919
6     0.592579
7     0.376995
8     0.539945

Addendum: Description of transformation functions

This function is used to transform target values to the interval [0,1] for MAX/MIN mode. An ascending or decreasing LINEAR function is used per default. This function maps input values in a specified interval [lower, upper] to the interval [0,1]. Outside the specified interval, the function remains constant, that is, 0 or 1.

For the match mode, two functions are available TRIANGULAR and BELL. The TRIANGULAR function is 0 outside a specified interval and linearly increases to 1 from both interval ends, reaching the value 1 at the center of the interval. This function is used per default for MATCH mode. The BELL function is a Gaussian bell curve, specified through the boundary values of the sigma interval, reaching the maximum value of 1 at the interval center.