Spaces:
Build error
Build error
| """ | |
| Modelo de dominio para configuraci贸n de forecasting. | |
| Este m贸dulo define la entidad ForecastConfig, cumpliendo con SRP. | |
| """ | |
| from dataclasses import dataclass, field | |
| from typing import List | |
| class ForecastConfig: | |
| """ | |
| Configuraci贸n para operaciones de forecasting. | |
| Define los par谩metros necesarios para realizar un pron贸stico, | |
| incluyendo horizonte de predicci贸n, cuantiles y frecuencia. | |
| Attributes: | |
| prediction_length: N煤mero de per铆odos a pronosticar | |
| quantile_levels: Cuantiles a calcular (ej: [0.1, 0.5, 0.9]) | |
| freq: Frecuencia temporal (D, H, M, etc.) | |
| Example: | |
| >>> config = ForecastConfig( | |
| ... prediction_length=7, | |
| ... quantile_levels=[0.1, 0.5, 0.9], | |
| ... freq="D" | |
| ... ) | |
| >>> config.has_median | |
| True | |
| """ | |
| prediction_length: int | |
| quantile_levels: List[float] = field(default_factory=lambda: [0.1, 0.5, 0.9]) | |
| freq: str = "D" | |
| def __post_init__(self): | |
| """Validaci贸n y normalizaci贸n autom谩tica""" | |
| self.validate() | |
| self._ensure_median() | |
| self._sort_quantiles() | |
| def has_median(self) -> bool: | |
| """Verifica si el cuantil 0.5 (mediana) est谩 incluido""" | |
| return 0.5 in self.quantile_levels | |
| def validate(self) -> bool: | |
| """ | |
| Valida la configuraci贸n. | |
| Returns: | |
| bool: True si es v谩lida | |
| Raises: | |
| ValueError: Si la configuraci贸n es inv谩lida | |
| """ | |
| # Validar prediction_length | |
| if self.prediction_length < 1: | |
| raise ValueError( | |
| f"prediction_length debe ser >= 1, recibido: {self.prediction_length}" | |
| ) | |
| # Validar quantile_levels | |
| if not self.quantile_levels: | |
| raise ValueError("quantile_levels no puede estar vac铆o") | |
| # Verificar que los cuantiles est茅n en [0, 1] | |
| for q in self.quantile_levels: | |
| if not 0 <= q <= 1: | |
| raise ValueError( | |
| f"Todos los cuantiles deben estar en [0, 1], encontrado: {q}" | |
| ) | |
| # Validar freq | |
| valid_freqs = {"D", "H", "M", "W", "Y", "Q", "S", "T", "min"} | |
| if self.freq not in valid_freqs: | |
| raise ValueError( | |
| f"Frecuencia '{self.freq}' no reconocida. " | |
| f"V谩lidas: {valid_freqs}" | |
| ) | |
| return True | |
| def _ensure_median(self): | |
| """Asegura que la mediana (0.5) est茅 incluida""" | |
| if not self.has_median: | |
| self.quantile_levels.append(0.5) | |
| def _sort_quantiles(self): | |
| """Ordena los cuantiles de menor a mayor""" | |
| self.quantile_levels = sorted(set(self.quantile_levels)) | |
| def default(cls) -> "ForecastConfig": | |
| """ | |
| Crea una configuraci贸n con valores por defecto. | |
| Returns: | |
| ForecastConfig: Configuraci贸n por defecto | |
| - prediction_length: 7 | |
| - quantile_levels: [0.1, 0.5, 0.9] | |
| - freq: "D" | |
| """ | |
| return cls( | |
| prediction_length=7, | |
| quantile_levels=[0.1, 0.5, 0.9], | |
| freq="D" | |
| ) | |
| def to_dict(self) -> dict: | |
| """Serializa la configuraci贸n a diccionario""" | |
| return { | |
| "prediction_length": self.prediction_length, | |
| "quantile_levels": self.quantile_levels, | |
| "freq": self.freq | |
| } | |