Design with explicit Formula¶
This tutorial notebook shows how to setup a D-optimal design with BoFire while providing an explicit formula and not just one of the four available keywords linear
, linear-and-interaction
, linear-and-quadratic
, fully-quadratic
.
Make sure that cyipopt
is installed. The recommend way is the installation via conda conda install -c conda-forge cyipopt
.
Imports¶
In [ ]:
Copied!
import bofire.strategies.api as strategies
from bofire.data_models.api import Domain, Inputs
from bofire.data_models.features.api import ContinuousInput
from bofire.data_models.strategies.api import DoEStrategy
from bofire.data_models.strategies.doe import DOptimalityCriterion
from bofire.utils.doe import get_confounding_matrix
import bofire.strategies.api as strategies
from bofire.data_models.api import Domain, Inputs
from bofire.data_models.features.api import ContinuousInput
from bofire.data_models.strategies.api import DoEStrategy
from bofire.data_models.strategies.doe import DOptimalityCriterion
from bofire.utils.doe import get_confounding_matrix
Setup of the problem¶
In [ ]:
Copied!
input_features = Inputs(
features=[
ContinuousInput(key="a", bounds=(0, 5)),
ContinuousInput(key="b", bounds=(40, 800)),
ContinuousInput(key="c", bounds=(80, 180)),
ContinuousInput(key="d", bounds=(200, 800)),
],
)
domain = Domain(inputs=input_features)
input_features = Inputs(
features=[
ContinuousInput(key="a", bounds=(0, 5)),
ContinuousInput(key="b", bounds=(40, 800)),
ContinuousInput(key="c", bounds=(80, 180)),
ContinuousInput(key="d", bounds=(200, 800)),
],
)
domain = Domain(inputs=input_features)
Definition of the formula for which the optimal points should be found¶
In [ ]:
Copied!
model_type = "a + {a**2} + b + c + d + a:b + a:c + a:d + b:c + b:d + c:d"
model_type
model_type = "a + {a**2} + b + c + d + a:b + a:c + a:d + b:c + b:d + c:d"
model_type
Out[ ]:
'a + {a**2} + b + c + d + a:b + a:c + a:d + b:c + b:d + c:d'
Find D-optimal Design¶
In [ ]:
Copied!
data_model = DoEStrategy(
domain=domain,
criterion=DOptimalityCriterion(formula=model_type),
ipopt_options={"max_iter": 100, "print_level": 0},
)
strategy = strategies.map(data_model=data_model)
design = strategy.ask(17)
design
data_model = DoEStrategy(
domain=domain,
criterion=DOptimalityCriterion(formula=model_type),
ipopt_options={"max_iter": 100, "print_level": 0},
)
strategy = strategies.map(data_model=data_model)
design = strategy.ask(17)
design
Tried to set Option: disp. It is not a valid option. Please check the list of available options.
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) Cell In[4], line 7 1 data_model = DoEStrategy( 2 domain=domain, 3 criterion=DOptimalityCriterion(formula=model_type), 4 ipopt_options={"max_iter": 100, "disp": 0}, 5 ) 6 strategy = strategies.map(data_model=data_model) ----> 7 design = strategy.ask(17) 8 design File ~/Documents/temporary/bofire/bofire/strategies/strategy.py:128, in Strategy.ask(self, candidate_count, add_pending, raise_validation_error) 123 if not self.has_sufficient_experiments(): 124 raise ValueError( 125 "Not enough experiments available to execute the strategy.", 126 ) --> 128 candidates = self._ask(candidate_count=candidate_count) 130 self.domain.validate_candidates( 131 candidates=candidates, 132 only_inputs=True, 133 raise_validation_error=raise_validation_error, 134 ) 136 if candidate_count is not None: File ~/Documents/temporary/bofire/bofire/strategies/doe_strategy.py:113, in DoEStrategy._ask(self, candidate_count) 103 num_discrete_vars = len(new_discretes) 104 if ( 105 self.data_model.optimization_strategy == "relaxed" 106 or (num_binary_vars == 0 and num_discrete_vars == 0) (...) 111 ) 112 ): --> 113 design = find_local_max_ipopt( 114 new_domain, 115 n_experiments=_candidate_count, 116 fixed_experiments=None, 117 partially_fixed_experiments=adapted_partially_fixed_candidates, 118 ipopt_options=self.data_model.ipopt_options, 119 criterion=self.data_model.criterion, 120 use_hessian=self.data_model.use_hessian, 121 ) 122 # TODO adapt to when exhaustive search accepts discrete variables 123 elif ( 124 self.data_model.optimization_strategy == "exhaustive" 125 and num_discrete_vars == 0 126 ): File ~/Documents/temporary/bofire/bofire/strategies/doe/design.py:188, in find_local_max_ipopt(domain, n_experiments, criterion, ipopt_options, sampling, fixed_experiments, partially_fixed_experiments, use_hessian) 182 problem = FirstOrderDoEProblem( 183 doe_objective=objective_function, 184 bounds=bounds, 185 constraints=constraints, 186 ) 187 for key in _ipopt_options.keys(): --> 188 problem.add_option(key, _ipopt_options[key]) 190 x, info = problem.solve(x0) 192 design = pd.DataFrame( 193 x.reshape(n_experiments, len(domain.inputs)), 194 columns=domain.inputs.get_keys(), 195 index=[f"exp{i}" for i in range(n_experiments)], 196 ) File ~/anaconda3/envs/bofire/lib/python3.11/site-packages/cyipopt/cython/ipopt_wrapper.pyx:495, in ipopt_wrapper.Problem.add_option() TypeError: Error while assigning an option
Analyze Confounding¶
In [ ]:
Copied!
import matplotlib
import matplotlib.pyplot as plt
import seaborn as sns
matplotlib.rcParams["figure.dpi"] = 120
m = get_confounding_matrix(
domain.inputs,
design=design,
interactions=[2, 3],
powers=[2],
)
sns.heatmap(m, annot=True, annot_kws={"fontsize": 7}, fmt="2.1f")
plt.show()
import matplotlib
import matplotlib.pyplot as plt
import seaborn as sns
matplotlib.rcParams["figure.dpi"] = 120
m = get_confounding_matrix(
domain.inputs,
design=design,
interactions=[2, 3],
powers=[2],
)
sns.heatmap(m, annot=True, annot_kws={"fontsize": 7}, fmt="2.1f")
plt.show()