Example for using exclusion constraints in discrete searchspaces¶
This examples shows how an exclusion constraint can be created for a discrete searchspace. This can be used if some parameter values are incompatible with values of another parameter.
This example assumes some basic familiarity with using BayBE.
We thus refer to campaign
for a basic example.
Necessary imports for this example¶
import numpy as np
from baybe import Campaign
from baybe.constraints import (
DiscreteExcludeConstraint,
SubSelectionCondition,
ThresholdCondition,
)
from baybe.objectives import SingleTargetObjective
from baybe.parameters import (
CategoricalParameter,
NumericalDiscreteParameter,
SubstanceParameter,
)
from baybe.searchspace import SearchSpace
from baybe.targets import NumericalTarget
from baybe.utils.dataframe import add_fake_results
Experiment setup¶
We begin by setting up some parameters for our experiments.
dict_solvent = {
"water": "O",
"C1": "C",
"C2": "CC",
"C3": "CCC",
"C4": "CCCC",
"C5": "CCCCC",
"c6": "c1ccccc1",
"C6": "CCCCCC",
}
solvent = SubstanceParameter(name="Solv", data=dict_solvent, encoding="RDKIT")
speed = CategoricalParameter(
name="Speed",
values=["very slow", "slow", "normal", "fast", "very fast"],
encoding="INT",
)
temperature = NumericalDiscreteParameter(
name="Temp", values=list(np.linspace(100, 200, 15)), tolerance=0.4
)
pressure = NumericalDiscreteParameter(
name="Pressure", values=[1, 2, 5, 10], tolerance=0.4
)
parameters = [solvent, speed, temperature, pressure]
Creating the constraint¶
This constraint simulates a situation where solvents C2
and C4
are not
compatible with temperatures larger than 151 and should thus be excluded.
constraint_1 = DiscreteExcludeConstraint(
parameters=["Temp", "Solv"],
combiner="AND",
conditions=[
ThresholdCondition(threshold=151, operator=">"),
SubSelectionCondition(selection=["C4", "C2"]),
],
)
This constraint simulates a situation where solvents C5
and C6
are not
compatible with pressures larger than 5 and should thus be excluded.
constraint_2 = DiscreteExcludeConstraint(
parameters=["Pressure", "Solv"],
combiner="AND",
conditions=[
ThresholdCondition(threshold=5, operator=">"),
SubSelectionCondition(selection=["C5", "C6"]),
],
)
This constraint simulates a situation where pressures below 3 should never be combined with temperatures above 120.
constraint_3 = DiscreteExcludeConstraint(
parameters=["Pressure", "Temp"],
combiner="AND",
conditions=[
ThresholdCondition(threshold=3.0, operator="<"),
ThresholdCondition(threshold=120.0, operator=">"),
],
)
Creating the searchspace and the objective¶
We now create the searchspace using the previously defined constraints.
searchspace = SearchSpace.from_product(
parameters=parameters, constraints=[constraint_1, constraint_2, constraint_3]
)
[08:37:21] DEPRECATION WARNING: please use MorganGenerator
[08:37:21] DEPRECATION WARNING: please use MorganGenerator
[08:37:21] DEPRECATION WARNING: please use MorganGenerator
[08:37:21] DEPRECATION WARNING: please use MorganGenerator
[08:37:21] DEPRECATION WARNING: please use MorganGenerator
[08:37:21] DEPRECATION WARNING: please use MorganGenerator
[08:37:21] DEPRECATION WARNING: please use MorganGenerator
[08:37:21] DEPRECATION WARNING: please use MorganGenerator
[08:37:21] DEPRECATION WARNING: please use MorganGenerator
[08:37:21] DEPRECATION WARNING: please use MorganGenerator
[08:37:21] DEPRECATION WARNING: please use MorganGenerator
[08:37:21] DEPRECATION WARNING: please use MorganGenerator
[08:37:21] DEPRECATION WARNING: please use MorganGenerator
[08:37:21] DEPRECATION WARNING: please use MorganGenerator
[08:37:21] DEPRECATION WARNING: please use MorganGenerator
[08:37:21] DEPRECATION WARNING: please use MorganGenerator
[08:37:21] DEPRECATION WARNING: please use MorganGenerator
[08:37:21] DEPRECATION WARNING: please use MorganGenerator
[08:37:21] DEPRECATION WARNING: please use MorganGenerator
[08:37:21] DEPRECATION WARNING: please use MorganGenerator
[08:37:21] DEPRECATION WARNING: please use MorganGenerator
[08:37:21] DEPRECATION WARNING: please use MorganGenerator
[08:37:21] DEPRECATION WARNING: please use MorganGenerator
[08:37:21] DEPRECATION WARNING: please use MorganGenerator
objective = SingleTargetObjective(target=NumericalTarget(name="Target_1", mode="MAX"))
### Creating and printing the campaign
campaign = Campaign(searchspace=searchspace, objective=objective)
print(campaign)
[1mCampaign[0m
[1mMeta Data[0m
Batches Done: 0
Fits Done: 0
[1mSearch Space[0m
[1mSearch Space Type: [0mDISCRETE
[1mDiscrete Search Space[0m
[1mDiscrete Parameters[0m
Name Type Num_Values Encoding
0 Solv SubstanceParameter 8 SubstanceEncoding.RDKIT
1 Speed CategoricalParameter 5 CategoricalEncoding.INT
2 Temp NumericalDiscreteParameter 15 None
3 Pressure NumericalDiscreteParameter 4 None
[1mExperimental Representation[0m
Solv Speed Temp Pressure
0 water very slow 100.000000 1.0
1 water very slow 100.000000 2.0
2 water very slow 100.000000 5.0
... ... ... ... ...
1147 C6 very fast 185.714286 5.0
1148 C6 very fast 192.857143 5.0
1149 C6 very fast 200.000000 5.0
[1150 rows x 4 columns]
[1mMetadata:[0m
was_recommended: 0/1150
was_measured: 0/1150
dont_recommend: 0/1150
[1mConstraints[0m
Type Affected_Parameters
0 DiscreteExcludeConstraint [Temp, Solv]
1 DiscreteExcludeConstraint [Pressure, Solv]
2 DiscreteExcludeConstraint [Pressure, Temp]
[1mComputational Representation[0m
Solv_RDKIT_MaxAbsEStateIndex Solv_RDKIT_MaxPartialCharge ... Temp
Pressure 0 0.000000 -0.411510 … 100.000000 1.0 1 0.000000 -0.411510 … 100.000000 2.0 2 0.000000 -0.411510 … 100.000000 5.0 … … … … … … 1147 2.231806 -0.053579 … 185.714286 5.0 1148 2.231806 -0.053579 … 192.857143 5.0 1149 2.231806 -0.053579 … 200.000000 5.0
[1150 rows x 9 columns]
[1mObjective[0m
[1mType: [0mSingleTargetObjective
[1mTargets [0m
Type Name Mode Lower_Bound Upper_Bound Transformation
0 NumericalTarget Target_1 MAX -inf inf None
TwoPhaseMetaRecommender(initial_recommender=RandomRecommender(allow_repeated_recomm
endations=False, allow_recommending_already_measured=True), recommender=BotorchRecommender(allow_repeated_recommendations=False, allow_recommending_already_measured=True, surrogate_model=GaussianProcessSurrogate(kernel_factory=DefaultKernelFactory(), _model=None), acquisition_function=qLogExpectedImprovement(), _botorch_acqf=None, acquisition_function_cls=None, sequential_continuous=False, hybrid_sampler=None, sampling_percentage=1.0), switch_after=1)
Manual verification of the constraints¶
The following loop performs some iterations and manually verifies the given constraints.
N_ITERATIONS = 3
for kIter in range(N_ITERATIONS):
print(f"\n\n#### ITERATION {kIter+1} ####")
print("## ASSERTS ##")
print(
"Number of entries with either Solvents C2 or C4 and a temperature above 151: ",
(
campaign.searchspace.discrete.exp_rep["Temp"].apply(lambda x: x > 151)
& campaign.searchspace.discrete.exp_rep["Solv"].apply(
lambda x: x in ["C2", "C4"]
)
).sum(),
)
print(
"Number of entries with either Solvents C5 or C6 and a pressure above 5: ",
(
campaign.searchspace.discrete.exp_rep["Pressure"].apply(lambda x: x > 5)
& campaign.searchspace.discrete.exp_rep["Solv"].apply(
lambda x: x in ["C5", "C6"]
)
).sum(),
)
print(
"Number of entries with pressure below 3 and temperature above 120: ",
(
campaign.searchspace.discrete.exp_rep["Pressure"].apply(lambda x: x < 3)
& campaign.searchspace.discrete.exp_rep["Temp"].apply(lambda x: x > 120)
).sum(),
)
rec = campaign.recommend(batch_size=5)
add_fake_results(rec, campaign.targets)
campaign.add_measurements(rec)
#### ITERATION 1 ####
## ASSERTS ##
Number of entries with either Solvents C2 or C4 and a temperature above 151: 0
Number of entries with either Solvents C5 or C6 and a pressure above 5: 0
Number of entries with pressure below 3 and temperature above 120: 0
#### ITERATION 2 ####
## ASSERTS ##
Number of entries with either Solvents C2 or C4 and a temperature above 151: 0
Number of entries with either Solvents C5 or C6 and a pressure above 5: 0
Number of entries with pressure below 3 and temperature above 120: 0
#### ITERATION 3 ####
## ASSERTS ##
Number of entries with either Solvents C2 or C4 and a temperature above 151: 0
Number of entries with either Solvents C5 or C6 and a pressure above 5: 0
Number of entries with pressure below 3 and temperature above 120: 0