Source code for alts.core.experiment_modules
#Version 1.1.1 conform as of 18.12.2024
"""
| *alts.core.experiment_modules*
"""
from __future__ import annotations
from typing import TYPE_CHECKING
from dataclasses import dataclass, field
from alts.core.configuration import Configurable, Required, is_set, post_init, pre_init, init
from alts.core.oracle.oracles import Oracles, POracles
from alts.core.subscribable import Publisher
from alts.core.estimator import Estimator
if TYPE_CHECKING:
from alts.core.data.data_pools import DataPools
from alts.core.query.query_selector import QuerySelector
from alts.core.data_process.time_source import TimeSource
from alts.core.query.query_sampler import QuerySampler
from typing_extensions import Self #type: ignore
[docs]
@dataclass
class ExperimentModules(Publisher):
"""
ExperimentModules(query_selector, time_source, data_pools, oracles)
| **Description**
| ExperimentModules is a collection of configured modules necessary for an experiment.
:param query_selector: Decider over the most useful datapoints for continued learning
:type query_selector: QuerySelector
:param time_source: A time source for the experiment
:type time_source: TimeSource
:param data_pools: Collector of already acquired data
:type data_pools: DataPools
:param oracles: The source of new data
:type oracles: Oracles
"""
query_selector: QuerySelector = init()
time_source: TimeSource = post_init()
data_pools: DataPools = post_init()
oracles: Oracles = post_init()
[docs]
def post_init(self):
"""
post_init(self) -> None
| **Description**
| Initializes the ``query_selector`` with its configuration.
"""
super().post_init()
self.query_selector = self.query_selector(exp_modules = self) # type: ignore
[docs]
def initialize(self):
"""
initialize(self) -> None
| **Description**
| Initializes the experiment.
"""
pass
[docs]
def step(self, iteration):
"""
step(self, iteration) -> None
| **Description**
| Does a step in the experiment at time point ``iteration``.
:param iteration: Current iteration of the experiment
:type iteration: int
"""
self.update()
def __call__(self, time_source: Required[TimeSource] = None, data_pools: Required[DataPools] = None, oracles: Required[Oracles] = None, **kwargs) -> Self:
"""
__call_(self, time_source, data_pools, oracles, **kwargs) -> ExperimentModules
| **Description**
| Creates and returns a new insance of itself with the given configuration.
:param query_selector: Decider over the most useful datapoints for continued learning
:type query_selector: QuerySelector
:param time_source: A time source for the experiment
:type time_source: TimeSource
:param data_pools: Collector of already acquired data
:type data_pools: DataPools
:param oracles: The source of new data
:type oracles: Oracles
:return: Newly configured ExperimentModules
:rtype: ExperimentModules
"""
obj = super().__call__(**kwargs)
obj.time_source = is_set(time_source)
obj.data_pools = is_set(data_pools)
obj.oracles = is_set(oracles)
return obj
[docs]
@dataclass
class InitQueryExperimentModules(ExperimentModules):
"""
InitQueryExperimentModules(query_selector, time_source, data_pools, poracles, initial_query_sampler)
| **Description**
| InitQueryExperimentModules additionally has an initial QuerySampler and a Process Oracle.
:param query_selector: Decider over the most useful datapoints for continued learning
:type query_selector: QuerySelector
:param time_source: A time source for the experiment
:type time_source: TimeSource
:param data_pools: Collector of already acquired data
:type data_pools: DataPools
:param oracles: The source of new data
:type oracles: POracles
:param initial_query_sampler: A sampler to get the very first datapoints
:type initial_query_sampler: QuerySampler
"""
initial_query_sampler: QuerySampler = init()
oracles: POracles = post_init()
[docs]
def post_init(self):
"""
post_init(self) -> None
| **Description**
| Initializes the ``query_selector`` and ``init_query_sampler`` with its configuration.
:raises TypeError: If ``oracles`` is not a ``POracle``
"""
super().post_init()
self.initial_query_sampler = self.initial_query_sampler(exp_modules = self) # type: ignore
if not isinstance(self.oracles, POracles):
raise TypeError(f"InitQueryExperimentModules requires POracles")
[docs]
def initialize(self):
"""
initialize(self) -> None
| **Description**
| Initializes the experiment by sampling the first queries for the experiment.
"""
super().initialize()
self.init_queries()
[docs]
def init_queries(self):
"""
init_queries(self) -> None
| **Description**
| Samples the inital queries and adds them to the oracle.
:return: The sampled queries
:rtype: `NDArray <https://numpy.org/doc/stable/reference/arrays.ndarray.html>`_
"""
queries = self.initial_query_sampler.sample()
self.oracles.add(queries)
return queries
[docs]
@dataclass
class EstimatorExperiment(ExperimentModules):
"""
EstimatorExperiment(query_selector, time_source, data_pools, poracles, estimator)
| **Description**
| EstimatorExperiment additionally has an estimator to train on the data.
:param query_selector: Decider over the most useful datapoints for continued learning
:type query_selector: QuerySelector
:param time_source: A time source for the experiment
:type time_source: TimeSource
:param data_pools: Collector of already acquired data
:type data_pools: DataPools
:param oracles: The source of new data
:type oracles: Oracles
:param estimator: An estimator that trains with the acquired data
:type estimator: Estimator
"""
estimator: Estimator = init()
[docs]
def post_init(self):
"""
post_init(self) -> None
| **Description**
| Initializes the ``query_selector`` and ``estimator`` with its configuration.
"""
super().post_init()
self.estimator = self.estimator(exp_modules = self) # type: ignore
[docs]
@dataclass
class InitQueryEstimatorExperiment(InitQueryExperimentModules, EstimatorExperiment):
"""
InitQueryEstimatorExperiment(query_selector, time_source, data_pools, poracles, initial_query_sampler, estimator)
| **Description**
| InitQueryEstimatorExperiment is an experiment setup with an initial query sample and an estimator to train.
:param query_selector: Decider over the most useful datapoints for continued learning
:type query_selector: QuerySelector
:param time_source: A time source for the experiment
:type time_source: TimeSource
:param data_pools: Collector of already acquired data
:type data_pools: DataPools
:param oracles: The source of new data
:type oracles: POracles
:param initial_query_sampler: A sampler to get the very first datapoints
:type initial_query_sampler: QuerySampler
:param estimator: An estimator that trains with the acquired data
:type estimator: Estimator
"""
pass