Skip to content

Commit dddf407

Browse files
committed
add data namespace to experiment
1 parent a24bf9e commit dddf407

1 file changed

Lines changed: 58 additions & 0 deletions

File tree

src/hyperactive/base/_experiment.py

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,15 @@
22

33
# copyright: hyperactive developers, MIT License (see LICENSE file)
44

5+
from __future__ import annotations
6+
7+
import time
8+
59
import numpy as np
610
from skbase.base import BaseObject
711

12+
from hyperactive.base._history import SearchHistory
13+
814

915
class BaseExperiment(BaseObject):
1016
"""Base class for experiment."""
@@ -21,6 +27,7 @@ class BaseExperiment(BaseObject):
2127

2228
def __init__(self):
2329
super().__init__()
30+
self._history = SearchHistory()
2431

2532
def __call__(self, params):
2633
"""Score parameters. Same as score call, returns only a first element."""
@@ -77,8 +84,20 @@ def evaluate(self, params):
7784
f"Parameters passed to {type(self)}.evaluate do not match: "
7885
f"expected {paramnames}, got {list(params.keys())}."
7986
)
87+
88+
start_time = time.perf_counter()
8089
res, metadata = self._evaluate(params)
90+
eval_time = time.perf_counter() - start_time
91+
8192
res = np.float64(res)
93+
94+
self._history.record(
95+
params=params,
96+
score=res,
97+
metadata=metadata,
98+
eval_time=eval_time,
99+
)
100+
82101
return res, metadata
83102

84103
def _evaluate(self, params):
@@ -141,3 +160,42 @@ def score(self, params):
141160
metadata = eval_res[1]
142161

143162
return sign * value, metadata
163+
164+
@property
165+
def data(self) -> SearchHistory:
166+
"""Access the collected data from optimization runs.
167+
168+
Tracks all evaluations during optimization. Data accumulates across
169+
multiple optimization runs on the same experiment instance.
170+
171+
Returns
172+
-------
173+
SearchHistory
174+
The data object with the following attributes and methods:
175+
176+
Attributes:
177+
- ``history``: list[dict] - all recorded evaluations
178+
- ``n_trials``: int - total number of trials
179+
- ``n_runs``: int - number of optimization runs
180+
- ``best_trial``: dict | None - trial with highest score
181+
- ``best_score``: float | None - highest score
182+
- ``best_params``: dict | None - parameters of best trial
183+
184+
Methods:
185+
- ``get_run(run_id)``: get trials from specific run
186+
- ``clear()``: reset all data
187+
- ``new_run()``: signal start of new run (call before each run)
188+
189+
Examples
190+
--------
191+
>>> experiment.data.history # all evaluations as list of dicts
192+
>>> experiment.data.best_score # highest score
193+
>>> experiment.data.get_run(0) # evaluations from first run
194+
>>> experiment.data.clear() # reset data
195+
196+
To convert to a pandas DataFrame::
197+
198+
import pandas as pd
199+
df = pd.DataFrame(experiment.data.history)
200+
"""
201+
return self._history

0 commit comments

Comments
 (0)