gpu-perf-prophet / src /models /metrics.py
vxa8502's picture
Code cleanup
0623ff0
Raw
History Blame Contribute Delete
1.32 kB
"""Evaluation metrics co-reported alongside MAPE: sMAPE and median APE, as plain functions (not sklearn wrappers) so LOGO-CV notebooks and future eval code share one definition."""
from __future__ import annotations
import numpy as np
import numpy.typing as npt
_EPS = np.finfo(float).eps
def smape(y_true: npt.ArrayLike, y_pred: npt.ArrayLike) -> float:
"""Symmetric MAPE: mean(2*|pred-true| / (|true|+|pred|)), as a fraction in [0, 2]; denominator floored at machine epsilon (matches sklearn's convention) so true==pred==0 gives 0 instead of divide-by-zero."""
y_true = np.asarray(y_true, dtype=float)
y_pred = np.asarray(y_pred, dtype=float)
denom = np.abs(y_true) + np.abs(y_pred)
denom = np.where(denom == 0, _EPS, denom)
return float(np.mean(2.0 * np.abs(y_pred - y_true) / denom))
def median_ape(y_true: npt.ArrayLike, y_pred: npt.ArrayLike) -> float:
"""Median absolute percentage error, as a fraction; robust to the single-worst-row blowups that can dominate a small-N fold's mean MAPE (same epsilon-floored denominator convention as smape())."""
y_true = np.asarray(y_true, dtype=float)
y_pred = np.asarray(y_pred, dtype=float)
denom = np.abs(y_true)
denom = np.where(denom == 0, _EPS, denom)
return float(np.median(np.abs(y_pred - y_true) / denom))