Source code for pysatl_cpd.analysis.metrics.multiple_run.classification.recall

# -*- coding: ascii -*-

"""Micro-averaged recall over multiple runs."""

__author__ = "Danil Totmyanin"
__copyright__ = "Copyright (c) 2026 PySATL project"
__license__ = "SPDX-License-Identifier: MIT"

from collections.abc import Mapping
from typing import Any

from pysatl_cpd.analysis.metrics.abstracts.imultiple_run_metric import IMultipleRunMetric
from pysatl_cpd.analysis.metrics.multiple_run.classification.base import TotalFN, TotalTP
from pysatl_cpd.analysis.metrics.multiple_run.derived_metric import DerivedMetric
from pysatl_cpd.core.detection_trace import DetectionTrace
from pysatl_cpd.data.providers.labeled.labeled_data import LabeledData as LabeledData
from pysatl_cpd.typedefs import Number


[docs] class RecallMetric[TraceT: DetectionTrace, ProviderT: LabeledData[Any, Any]]( DerivedMetric[TraceT, ProviderT, Number, float] ): """Configure the recall metric with an error margin. Parameters ---------- error_margin Allowed (left, right) margin around each true change point for matching detections. """
[docs] def __init__(self, error_margin: tuple[int, int]) -> None: self._bases = { "tp": TotalTP[TraceT, ProviderT](error_margin), "fn": TotalFN[TraceT, ProviderT](error_margin), }
@property def bases(self) -> Mapping[str, IMultipleRunMetric[TraceT, ProviderT, int]]: """Underlying TP and FN metrics. Returns ------- Mapping[str, IMultipleRunMetric] """ return self._bases
[docs] def compute(self, values: Mapping[str, Number]) -> float: """Compute recall as TP / (TP + FN). Parameters ---------- values Must contain ``tp`` and ``fn`` keys. Returns ------- float The recall score. Returns 0.0 when TP + FN is zero. """ tp = values["tp"] fn = values["fn"] return float(tp / (tp + fn)) if (tp + fn) > 0 else 0.0