Source code for deephyper.ensemble.aggregator._mean

from typing import List, Optional, Union

import numpy as np

from deephyper.ensemble.aggregator._aggregator import Aggregator


[docs] class MeanAggregator(Aggregator): """Aggregate predictions using the mean. Supports both NumPy arrays and masked arrays. .. list-table:: :widths: 25 25 :header-rows: 1 * - Array (Fixed Set) - MaskedArray * - ✅ - ✅ Args: with_scale (bool, optional): a boolean that sets if the standard deviation of the predictions should be returned when calling the aggregator. Defaults to ``False``. """ def __init__(self, with_scale: bool = False): self.with_scale = with_scale
[docs] def aggregate( self, y: List[Union[np.ndarray, np.ma.MaskedArray]], weights: Optional[List[float]] = None, ) -> Union[np.ndarray, np.ma.MaskedArray]: """Aggregate predictions using the mean. Args: y (List[np.ndarray | np.ma.MaskedArray]): List of prediction arrays, each of shape ``(n_samples, n_outputs)``. weights (Optional[List[float]]): Optional weights for the predictors. If provided, must have the same length as `y`. Returns: np.ndarray: Aggregated predictions of shape ``(n_samples, n_outputs)``. Raises: ValueError: If `weights` length does not match the number of predictors in `y`. """ if weights is not None and len(weights) != len(y): raise ValueError("The length of `weights` must match the number of predictors in `y`.") # Ensure `y` is a valid list of arrays if not all(isinstance(pred, (np.ndarray, np.ma.MaskedArray)) for pred in y): raise TypeError("All elements of `y` must be numpy.ndarray or numpy.ma.MaskedArray.") self._np = np if all(isinstance(pred, np.ma.MaskedArray) for pred in y): self._np = np.ma # Stack predictions for aggregation stacked_y = self._np.stack(y, axis=0) avg = self._np.average(stacked_y, axis=0, weights=weights) if not self.with_scale: return avg scale = self._np.sqrt( self._np.average(self._np.square(stacked_y - avg), axis=0, weights=weights) ) return {"loc": avg, "scale": scale}