Source code for seqme.metrics.id

from collections.abc import Callable
from typing import Literal

import numpy as np

from seqme.core.base import Metric, MetricResult


[docs] class ID(Metric): """Applies a user-provided predictor to a list of sequences and returns the mean and standard error of the predictors outputs."""
[docs] def __init__( self, predictor: Callable[[list[str]], np.ndarray], name: str, objective: Literal["minimize", "maximize"], *, deviation: Literal["std", "se", "var"] = "se", estimate: Literal["biased", "unbiased"] = "unbiased", ): """ Initialize the metric. Args: predictor: A function that takes a list of sequences and returns a 1D array of scalar values. name: Name of the metric. objective: Specifies whether lower or higher values of the metric are better. deviation: Type of deviation to compute: - ``'std'``: Standard deviation - ``'se'``: Standard error - ``'var'``: Variance estimate: How to estimate the deviation. """ self.predictor = predictor self._name = name self._objective = objective self.deviation = deviation self.estimate = estimate
[docs] def __call__(self, sequences: list[str]) -> MetricResult: """ Evaluate the predictor on the provided sequences. Applies the predictor to the sequences and returns the mean and standard error of the resulting values (if more than one sequence). Args: sequences: Sequences to evaluate. Returns: MetricResult: Mean predictor value and deviation. """ values = self.predictor(sequences) if len(values) > 1: if self.estimate == "biased": ddof = 0 elif self.estimate == "unbiased": ddof = 1 else: raise ValueError(f"Invalid estimate: {self.estimate}") if self.deviation == "std": deviation = float(values.std(ddof=ddof)) elif self.deviation == "var": deviation = float(values.var(ddof=ddof)) elif self.deviation == "se": deviation = float(values.std(ddof=ddof)) / (len(values) ** 0.5) else: raise ValueError(f"Invalid deviation: {self.deviation}") else: deviation = None return MetricResult(values.mean().item(), deviation)
@property def name(self) -> str: return self._name @property def objective(self) -> Literal["minimize", "maximize"]: return self._objective