Skip to content

Commit

Permalink
Merge pull request #205 from ChristopherMayes/select_best_improvements
Browse files Browse the repository at this point in the history
add returning best param set to vocs method,
  • Loading branch information
roussel-ryan authored Apr 15, 2024
2 parents cd2278f + 46090c1 commit a613b00
Show file tree
Hide file tree
Showing 14 changed files with 273 additions and 140 deletions.
140 changes: 93 additions & 47 deletions docs/examples/basic/xopt_basic.ipynb

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions tests/generators/test_neldermead.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ def wrap(x):
data = X.vocs.variable_data(X.data).to_numpy()
assert np.array_equal(data, scipy_data)

idx, best = X.vocs.select_best(X.data)
idx, best, _ = X.vocs.select_best(X.data)
xbest = X.vocs.variable_data(X.data.loc[idx, :]).to_numpy().flatten()
assert np.array_equal(
xbest, result.x
Expand Down Expand Up @@ -216,7 +216,7 @@ def wrap(x):
assert data.shape == scipy_data.shape
assert np.allclose(data, scipy_data, rtol=0, atol=1e-10)

idx, best = X.vocs.select_best(X.data)
idx, best, _ = X.vocs.select_best(X.data)
xbest = X.vocs.variable_data(X.data.loc[idx, :]).to_numpy().flatten()
assert np.array_equal(
xbest, result.x
Expand Down
10 changes: 5 additions & 5 deletions tests/test_vocs.py
Original file line number Diff line number Diff line change
Expand Up @@ -208,29 +208,29 @@ def test_select_best(self):

# test maximization
vocs.objectives[vocs.objective_names[0]] = "MAXIMIZE"
idx, val = vocs.select_best(test_data)
idx, val, _ = vocs.select_best(test_data)
assert idx == [2]
assert val == [1.0]

vocs.constraints = {}
idx, val = vocs.select_best(test_data)
idx, val, _ = vocs.select_best(test_data)
assert idx == [3]
assert val == [1.5]

# test returning multiple best values -- sorted by best value
idx, val = vocs.select_best(test_data, 2)
idx, val, _ = vocs.select_best(test_data, 2)
assert np.allclose(idx, np.array([3, 2]))
assert np.allclose(val, np.array([1.5, 1.0]))

# test minimization
vocs.objectives[vocs.objective_names[0]] = "MINIMIZE"
vocs.constraints = {"c1": ["GREATER_THAN", 0.5]}
idx, val = vocs.select_best(test_data)
idx, val, _ = vocs.select_best(test_data)
assert idx == [0]
assert val == [0.5]

vocs.constraints = {}
idx, val = vocs.select_best(test_data)
idx, val, _ = vocs.select_best(test_data)
assert idx == 1
assert val == 0.1

Expand Down
3 changes: 2 additions & 1 deletion xopt/asynchronous.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ def submit_data(
"""
Submit data to evaluator and return futures indexed to internal futures list.
Args:
Parameters
----------
input_data: dataframe containing input data
"""
Expand Down
9 changes: 6 additions & 3 deletions xopt/generators/bayesian/bax/acquisition.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ class ModelListExpectedInformationGain(MultiObjectiveAnalyticAcquisitionFunction
>>> EIG = ExpectedInformationGain(model, algo)
>>> eig = EIG(test_X)
Args:
Parameters
----------
model: A fitted independent multi-output (ModelList) model.
"""

Expand Down Expand Up @@ -62,13 +63,15 @@ def __init__(self, model: Model, algorithm: Algorithm, bounds: Tensor) -> None:
def forward(self, X: Tensor) -> Tensor:
r"""Evaluate Expected Information Gain on the candidate set X.
Args:
Parameters
----------
X: A `(b1 x ... bk) x 1 x d`-dim batched tensor of `d`-dim design points.
Expected Information Gain is computed for each point individually,
i.e., what is considered are the marginal posteriors, not the
joint.
Returns:
Returns
-------
A `(b1 x ... bk)`-dim tensor of Expected Information Gain values at the
given design points `X`.
"""
Expand Down
10 changes: 7 additions & 3 deletions xopt/generators/bayesian/bayesian_exploration.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ def __init__(
X_pending: Optional[Tensor] = None,
) -> None:
r"""q-Upper Confidence Bound.
Args:
Parameters
----------
model: A fitted model.
sampler: The sampler used to draw base samples. Defaults to
`SobolQMCNormalSampler(num_samples=512, collapse_batch_dims=True)`
Expand All @@ -79,10 +80,13 @@ def __init__(
@t_batch_mode_transform()
def forward(self, X: Tensor) -> Tensor:
r"""Evaluate qUpperConfidenceBound on the candidate set `X`.
Args:
Parameters
----------
X: A `batch_sahpe x q x d`-dim Tensor of t-batches with `q` `d`-dim design
points each.
Returns:
Returns
-------
A `batch_shape'`-dim Tensor of Upper Confidence Bound values at the given
design points `X`, where `batch_shape'` is the broadcasted batch shape of
model and input `X`.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ def ones_callable(Z, X=None):
def forward(self, samples: Tensor, X: Optional[Tensor] = None) -> Tensor:
r"""Evaluate the feasibility-weighted objective on the samples.
Args:
Parameters
----------
samples: A `sample_shape x batch_shape x q x m`-dim Tensors of
samples from a model posterior.
X: A `batch_shape x q x d`-dim tensor of inputs. Relevant only if
Expand Down
3 changes: 2 additions & 1 deletion xopt/generators/bayesian/custom_botorch/heteroskedastic.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ def __init__(
to specify mean and covariance modules.
Args:
Parameters
----------
train_X: A `batch_shape x n x d` tensor of training features.
train_Y: A `batch_shape x n x m` tensor of training observations.
train_Yvar: A `batch_shape x n x m` tensor of observed measurement
Expand Down
7 changes: 5 additions & 2 deletions xopt/generators/bayesian/custom_botorch/identity.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,13 @@ def __init__(self, model) -> None:
@t_batch_mode_transform()
def forward(self, X: Tensor) -> Tensor:
r"""Evaluate qUpperConfidenceBound on the candidate set `X`.
Args:
Parameters
----------
X: A `batch_sahpe x q x d`-dim Tensor of t-batches with `q` `d`-dim design
points each.
Returns:
Returns
-------
A `batch_shape'`-dim Tensor of Upper Confidence Bound values at the given
design points `X`, where `batch_shape'` is the broadcasted batch shape of
model and input `X`.
Expand Down
12 changes: 8 additions & 4 deletions xopt/generators/bayesian/custom_botorch/proximal.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ def __init__(
r"""Derived Acquisition Function weighted by proximity to recently
observed point.
Args:
Parameters
----------
acq_function: The base acquisition function, operating on input tensors
of feature dimension `d`.
proximal_weights: A `d` dim tensor used to bias locality
Expand Down Expand Up @@ -89,10 +90,12 @@ def __init__(
def forward(self, X: Tensor) -> Tensor:
r"""Evaluate base acquisition function with proximal weighting.
Args:
Parameters
----------
X: Input tensor of feature dimension `d` .
Returns:
Returns
-------
Base acquisition function evaluated on tensor `X` multiplied by proximal
weighting.
"""
Expand Down Expand Up @@ -143,7 +146,8 @@ def _validate_model(model: Model, proximal_weights: Tensor) -> None:
Perform vaidation checks on model used in base acquisition function to make sure
it is compatible with proximal weighting.
Args:
Parameters
----------
model: Model associated with base acquisition function to be validated.
proximal_weights: A `d` dim tensor used to bias locality
along each axis.
Expand Down
3 changes: 2 additions & 1 deletion xopt/generators/bayesian/models/prior_mean.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ def __init__(
):
"""Custom prior mean for a GP based on an arbitrary model.
Args:
Parameters
----------
model: Representation of the model.
input_transformer: Module used to transform inputs in the GP.
outcome_transformer: Module used to transform outcomes in the GP.
Expand Down
42 changes: 28 additions & 14 deletions xopt/generators/bayesian/visualize.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,22 +22,36 @@ def visualize_generator_model(
hollow red "o". Feasibility is calculated with respect to all constraints unless the selected output is a
constraint itself, in which case only that one is considered.
Args:
generator: Bayesian generator object.
output_names: Outputs for which the GP models are displayed. Defaults to all outputs in generator.vocs.
variable_names: The variables with respect to which the GP models are displayed (maximum of 2).
Defaults to generator.vocs.variable_names.
idx: Index of the last sample to use. This also selects the point of reference in higher dimensions unless
an explicit reference_point is given.
reference_point: Reference point determining the value of variables in generator.vocs.variable_names,
but not in variable_names (slice plots in higher dimensions). Defaults to last used sample.
show_samples: Whether samples are shown.
show_prior_mean: Whether the prior mean is shown.
show_feasibility: Whether the feasibility region is shown.
show_acquisition: Whether the acquisition function is computed and shown.
n_grid: Number of grid points per dimension used to display the model predictions.
Parameters
----------
generator : Generator
Bayesian generator object.
output_names : List[str]
Outputs for which the GP models are displayed. Defaults to all outputs in
generator.vocs.
variable_names : List[str]
The variables with respect to which the GP models are displayed (maximum
of 2). Defaults to generator.vocs.variable_names.
idx : int
Index of the last sample to use. This also selects the point of reference in
higher dimensions unless an explicit reference_point is given.
reference_point : dict
Reference point determining the value of variables in
generator.vocs.variable_names, but not in variable_names (slice plots in
higher dimensions). Defaults to last used sample.
show_samples : bool, optional
Whether samples are shown.
show_prior_mean : bool, optional
Whether the prior mean is shown.
show_feasibility : bool, optional
Whether the feasibility region is shown.
show_acquisition : bool, optional
Whether the acquisition function is computed and shown.
n_grid : int, optional
Number of grid points per dimension used to display the model predictions.
Returns:
--------
The matplotlib figure and axes objects.
"""

Expand Down
6 changes: 4 additions & 2 deletions xopt/pydantic.py
Original file line number Diff line number Diff line change
Expand Up @@ -600,12 +600,14 @@ def get_callable_from_string(callable: str, bind: Any = None) -> Callable:
"""Get callable from a string. In the case that the callable points to a bound method,
the function returns a callable taking the bind instance as the first arg.
Args:
Parameters
----------
callable: String representation of callable abiding convention
__module__:callable
bind: Class to bind as self
Returns:
Returns
-------
Callable
"""
callable_split = callable.rsplit(".", 1)
Expand Down
Loading

0 comments on commit a613b00

Please sign in to comment.