Utilities¶
BayBE comes with a set of useful functions that can make your life easier in certain scenarios.
Search Space Memory Estimation¶
In search spaces that have discrete parts, the memory needed to store the respective data can become excessively large as the number of points grows with the amount of possible combinations arising form all discrete parameter values.
The SearchSpace.estimate_product_space_size
and SubspaceDiscrete.estimate_product_space_size
utilities allow estimating the memory needed to represent the discrete subspace.
They return a MemorySize
object that
contains some relevant estimates:
import numpy as np
from baybe.parameters import NumericalDiscreteParameter
from baybe.searchspace import SearchSpace
# This creates 10 parameters with 20 values each.
# The resulting space would have 20^10 entries, requiring around 745 TB of memory for
# both experimental and computational representation of the search space.
parameters = [
NumericalDiscreteParameter(name=f"p{k+1}", values=np.linspace(0, 100, 20))
for k in range(10)
]
# Estimate the required memory for such a space
mem_estimate = SearchSpace.estimate_product_space_size(parameters)
# Print quantities of interest
print("Experimental Representation")
print(f"Estimated size: {mem_estimate.exp_rep_human_readable}")
print(f"Estimated size in Bytes: {mem_estimate.exp_rep_bytes}")
print(f"Expected data frame shape: {mem_estimate.exp_rep_shape}")
print("Computational Representation")
print(f"Estimated size: {mem_estimate.comp_rep_human_readable}")
print(f"Estimated size in Bytes: {mem_estimate.comp_rep_bytes}")
print(f"Expected data frame shape: {mem_estimate.comp_rep_shape}")
Estimation with Constraints
estimate_product_space_size()
currently does not include the influence of potential constraints in your search space
as it is generally very hard to incorporate the effect of arbitrary constraints without
actually building the entire space. Hence, you should always treat the number you get
as upper bound of required memory. This can still be useful – for instance if your
estimate already is several Exabytes, it is unlikely that most computers would be able
to handle the result even if there are constraints present.
Memory During Optimization
estimate_product_space_size()
only estimates the memory required to handle the search space. It does not estimate
the memory required during optimization, which can be of a similar magnitude, but
generally depends on additional factors.
Influence of Continuous Parameters
Continuous parameters do not influence the size of the discrete search space part as they do not contribute to the combinatorial configurations like discrete parameters. Hence, they are ignored by the utility.
Efficient Search Space Creation
If you run into issues creating large search spaces, as for instance in mixture
use cases, you should consider resorting to more specialized ways of creation by
invoking alternative search space constructors like
from_dataframe()
or
from_simplex()
.
Instead of creating a product space first and then filtering it down
according to constraints, they offer a more direct and thus efficient path to the
desired result, typically requiring substantially less memory.
For example, from_simplex()
includes the mixture constraint already during the product creation.
In addition, BayBE can also be installed with its optional polars
dependency
(pip install baybe[polars]
) that activates efficient machinery for constraint handling.
Reproducibility¶
In some scenarios, for instance when testing your code setup, it can be useful to fix
the random seeds for all relevant engines to generate reproducible results. BayBE offers
the set_random_seed
utility for this purpose:
from baybe.utils.random import set_random_seed
# Set the global random seed for all relevant engines
set_random_seed(1337)
# Assuming we have a prepared campaign
campaign.recommend(5)
Setting the global random seed can be undesirable if there are other packages in your
setup that might unintentionally be influenced by this. For this, BayBE offers
temporary_seed
:
from baybe.utils.random import temporary_seed
# Set the random seed for all relevant engines temporarily within the context
with temporary_seed(1337):
campaign.recommend(5)
Adding Fake Target Measurements and Parameter Noise¶
When creating test scripts, it is often useful to try the recommendation loop for a few
iterations. However, this requires some arbitrary target measurements to be set. Instead
of coming up with a custom logic every time, you can use the
add_fake_measurements
utility to add fake target
measurements and the add_parameter_noise
utility to add artificial parameter noise:
from baybe.utils.dataframe import add_fake_measurements, add_parameter_noise
# Get recommendations
recommendations = campaign.recommend(5)
# Add fake target measurements and artificial parameter noise to the recommendations.
# The utilities modify the dataframes inplace.
measurements = recommendations.copy()
add_fake_measurements(measurements, campaign.targets)
add_parameter_noise(measurements, campaign.parameters)
# Now continue the loop, e.g. by adding the measurements...