bayesian-optimization 3.1.0__tar.gz → 3.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: bayesian-optimization
3
- Version: 3.1.0
3
+ Version: 3.2.0
4
4
  Summary: Bayesian Optimization package
5
5
  Author: Fernando Nogueira
6
6
  Author-email: Fernando Nogueira <fmfnogueira@gmail.com>
@@ -21,9 +21,11 @@ Classifier: Programming Language :: Python :: 3.10
21
21
  Classifier: Programming Language :: Python :: 3.11
22
22
  Classifier: Programming Language :: Python :: 3.12
23
23
  Classifier: Programming Language :: Python :: 3.13
24
+ Classifier: Programming Language :: Python :: 3.14
24
25
  Requires-Dist: colorama>=0.4.6
25
26
  Requires-Dist: numpy>=1.25 ; python_full_version < '3.13'
26
27
  Requires-Dist: numpy>=2.1.3 ; python_full_version >= '3.13'
28
+ Requires-Dist: packaging>=20.0
27
29
  Requires-Dist: scikit-learn>=1.0.0
28
30
  Requires-Dist: scipy>=1.0.0 ; python_full_version < '3.13'
29
31
  Requires-Dist: scipy>=1.14.1 ; python_full_version >= '3.13'
@@ -8,6 +8,7 @@ from __future__ import annotations
8
8
 
9
9
  import json
10
10
  from collections import deque
11
+ from collections.abc import Iterable
11
12
  from os import PathLike
12
13
  from pathlib import Path
13
14
  from typing import TYPE_CHECKING, Any
@@ -175,6 +176,92 @@ class BayesianOptimization:
175
176
  """
176
177
  return self._space.res()
177
178
 
179
+ def predict(
180
+ self,
181
+ params: dict[str, Any] | Iterable[dict[str, Any]],
182
+ return_std=False,
183
+ return_cov=False,
184
+ fit_gp=True,
185
+ ) -> float | NDArray[Float] | tuple[float | NDArray[Float], float | NDArray[Float]]:
186
+ """Predict the target function value at given parameters.
187
+
188
+ Parameters
189
+ ---------
190
+ params: dict or iterable of dicts
191
+ The parameters where the prediction is made.
192
+
193
+ return_std: bool, optional(default=False)
194
+ If True, the standard deviation of the prediction is returned.
195
+
196
+ return_cov: bool, optional(default=False)
197
+ If True, the covariance of the prediction is returned.
198
+
199
+ fit_gp: bool, optional(default=True)
200
+ If True, the internal Gaussian Process model is fitted before
201
+ making the prediction.
202
+
203
+ Returns
204
+ -------
205
+ mean: float or np.ndarray
206
+ The predicted mean of the target function at the given parameters.
207
+ When params is a dict, returns a scalar. When params is an iterable,
208
+ returns a 1D array.
209
+
210
+ std_or_cov: float or np.ndarray (only if return_std or return_cov is True)
211
+ The predicted standard deviation or covariance of the target function
212
+ at the given parameters.
213
+ """
214
+ # Validate param types
215
+ if isinstance(params, dict):
216
+ params_array = self._space.params_to_array(params).reshape(1, -1)
217
+ single_param = True
218
+ elif isinstance(params, Iterable) and not isinstance(params, str):
219
+ # convert iterable of dicts to 2D array
220
+ params_array = np.array([self._space.params_to_array(p) for p in params])
221
+ single_param = False
222
+ else:
223
+ msg = f"params must be a dict or iterable of dicts, got {type(params).__name__}"
224
+ raise TypeError(msg)
225
+
226
+ # Validate mutual exclusivity of return_std and return_cov
227
+ if return_std and return_cov:
228
+ msg = "return_std and return_cov cannot both be True"
229
+ raise ValueError(msg)
230
+
231
+ if fit_gp:
232
+ if len(self._space) == 0:
233
+ msg = (
234
+ "The Gaussian Process model cannot be fitted with zero observations. To use predict(), "
235
+ "without fitting the GP, set fit_gp=False. The predictions will then be made using the "
236
+ "GP prior."
237
+ )
238
+ raise RuntimeError(msg)
239
+ self.acquisition_function._fit_gp(self._gp, self._space)
240
+
241
+ res = self._gp.predict(params_array, return_std=return_std, return_cov=return_cov)
242
+
243
+ if return_std or return_cov:
244
+ mean, std_or_cov = res
245
+ else:
246
+ mean = res
247
+
248
+ # Shape semantics: dict input returns scalars, list input returns arrays
249
+ # Ensure list input always returns arrays (convert scalar to 1D if needed)
250
+ if not single_param and mean.ndim == 0:
251
+ mean = np.atleast_1d(mean)
252
+ # ruff complains when nesting conditionals, so this three-way split is necessary
253
+ if not single_param and (return_std or return_cov) and std_or_cov.ndim == 0:
254
+ std_or_cov = np.atleast_1d(std_or_cov)
255
+
256
+ if single_param and mean.ndim > 0:
257
+ mean = mean[0]
258
+ if single_param and return_std and std_or_cov.ndim > 0:
259
+ std_or_cov = std_or_cov[0]
260
+
261
+ if return_std or return_cov:
262
+ return mean, std_or_cov
263
+ return mean
264
+
178
265
  def register(
179
266
  self, params: ParamsType, target: float, constraint_value: float | NDArray[Float] | None = None
180
267
  ) -> None:
@@ -303,8 +390,8 @@ class BayesianOptimization:
303
390
  probe based on the acquisition function. This means that the GP may
304
391
  not be fitted on all points registered to the target space when the
305
392
  method completes. If you intend to use the GP model after the
306
- optimization routine, make sure to fit it manually, e.g. by calling
307
- ``optimizer._gp.fit(optimizer.space.params, optimizer.space.target)``.
393
+ optimization routine, make sure to call predict() with fit_gp=True.
394
+
308
395
  """
309
396
  # Log optimization start
310
397
  self.logger.log_optimization_start(self._space.keys)
@@ -82,7 +82,7 @@ class ScreenLogger:
82
82
  result = ""
83
83
  width = self._default_cell_size
84
84
  # Keep negative sign, exponent, and as many decimal places as possible
85
- if "-" in s:
85
+ if x < 0:
86
86
  result += "-"
87
87
  width -= 1
88
88
  s = s[1:]
@@ -96,8 +96,6 @@ class ScreenLogger:
96
96
  width -= dot_pos
97
97
  if width > 0:
98
98
  result += s[dot_pos : dot_pos + width]
99
- else:
100
- result += s[:width]
101
99
  if "e" in s:
102
100
  result += end
103
101
  result = result.ljust(self._default_cell_size)
@@ -489,7 +489,10 @@ def wrap_kernel(kernel: kernels.Kernel, transform: Callable[[Any], Any]) -> kern
489
489
  def __reduce__(self) -> str | tuple[Any, ...]:
490
490
  return (wrap_kernel, (kernel, transform))
491
491
 
492
- return WrappedKernel(**kernel.get_params())
492
+ wrapped_instance = WrappedKernel.__new__(WrappedKernel)
493
+ wrapped_instance.__dict__.update(kernel.__dict__)
494
+ wrapped_instance._transform = transform
495
+ return wrapped_instance
493
496
 
494
497
 
495
498
  def _copy_signature(source_fct: Callable[..., Any]) -> Callable[[Callable[..., Any]], Callable[..., Any]]:
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "bayesian-optimization"
3
- version = "3.1.0"
3
+ version = "3.2.0"
4
4
  description = "Bayesian Optimization package"
5
5
  authors = [{ name = "Fernando Nogueira", email = "fmfnogueira@gmail.com" }]
6
6
  license = { file = "LICENSE" }
@@ -15,11 +15,13 @@ classifiers = [
15
15
  "Programming Language :: Python :: 3.11",
16
16
  "Programming Language :: Python :: 3.12",
17
17
  "Programming Language :: Python :: 3.13",
18
+ "Programming Language :: Python :: 3.14",
18
19
  ]
19
20
  dependencies = [
20
21
  "colorama>=0.4.6",
21
22
  "numpy>=1.25; python_version<'3.13'",
22
23
  "numpy>=2.1.3; python_version>='3.13'",
24
+ "packaging>=20.0",
23
25
  "scikit-learn>=1.0.0",
24
26
  "scipy>=1.0.0; python_version<'3.13'",
25
27
  "scipy>=1.14.1; python_version>='3.13'",