harden model registry persistence and evaluation

This commit is contained in:
2026-06-11 21:06:39 +02:00
parent 3bed5e790a
commit 471146761e
4 changed files with 129 additions and 19 deletions

View File

@@ -1,11 +1,10 @@
from __future__ import annotations
import logging
from dataclasses import dataclass, field
from typing import Sequence
from collections.abc import Sequence
from dataclasses import dataclass
from app.ml.feature_store import FeatureVector
from app.ml.training import TrainingPipeline, TrainedArtifact
from app.ml.training import TrainingPipeline
logger = logging.getLogger(__name__)
@@ -29,15 +28,16 @@ class Evaluator:
self._pipeline = pipeline
def evaluate(self, artifact_id: str, predictions: Sequence[str]) -> EvalReport:
artifacts = list(self._pipeline._artifacts)
if not artifacts:
raise ValueError("Kein trainiertes Modell für Evaluation vorhanden.")
try:
supported_sensors = set(self._pipeline.export(artifact_id).supported_sensors)
except KeyError as exc:
raise ValueError("Kein trainiertes Modell für Evaluation vorhanden.") from exc
supported_sensors = self._pipeline.export(artifact_id).supported_sensors
unknown_hits = sum(1 for prediction in predictions if ":" not in prediction)
supported_references = sum(1 for sensor in supported_sensors for prediction in predictions if sensor in prediction)
parsed_sensors = [_prediction_sensor(prediction) for prediction in predictions]
supported_hits = sum(sensor in supported_sensors for sensor in parsed_sensors)
unknown_hits = sum(sensor not in supported_sensors for sensor in parsed_sensors)
sample_size = len(predictions)
coverage = supported_references / sample_size if sample_size else 0.0
coverage = supported_hits / sample_size if sample_size else 0.0
unknown_rate = unknown_hits / sample_size if sample_size else 0.0
coverage_metric = Metric(name="coverage", value=coverage, threshold=0.8)
@@ -54,4 +54,11 @@ class Evaluator:
coverage,
unknown_rate,
)
return report
return report
def _prediction_sensor(prediction: str) -> str | None:
parts = prediction.split(":", 2)
if len(parts) != 3 or not parts[0] or not parts[1]:
return None
return parts[1]