Source code for qmlhc.metrics.forecasting

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Forecasting Metrics
-------------------
Evaluation metrics for temporal and predictive performance analysis.

This module provides the following functions:
- ``mape``: Mean Absolute Percentage Error
- ``mase``: Mean Absolute Scaled Error
- ``delta_lag``: Lag anticipation (ΔLag) metric for directional alignment.
"""

from __future__ import annotations

import numpy as np

from ..core.types import Array, TensorLike


[docs] def mape(y_true: TensorLike, y_pred: TensorLike) -> float: """ Mean Absolute Percentage Error (MAPE). Measures the average absolute percentage deviation between the predicted and true values. Parameters ---------- y_true : TensorLike Ground-truth time series or target values. y_pred : TensorLike Predicted time series or model outputs. Returns ------- float Mean absolute percentage error (in percent). Notes ----- A small epsilon (1e-12) is added to the denominator to prevent division by zero. """ t = np.asarray(y_true, dtype=float).reshape(-1) p = np.asarray(y_pred, dtype=float).reshape(-1) eps = 1e-12 return float(np.mean(np.abs((t - p) / (t + eps))) * 100.0)
[docs] def mase(y_true: TensorLike, y_pred: TensorLike, y_naive: TensorLike) -> float: """ Mean Absolute Scaled Error (MASE). Scales the absolute forecast error by the mean absolute difference of a naive forecast model, providing a scale-free error metric that can be compared across datasets. Parameters ---------- y_true : TensorLike Ground-truth time series or target values. y_pred : TensorLike Predicted time series or model outputs. y_naive : TensorLike Naive baseline time series (e.g., lag-1 shifted version of y_true). Returns ------- float Mean absolute scaled error. Notes ----- Values below 1.0 indicate that the model outperforms the naive baseline. """ t = np.asarray(y_true, dtype=float).reshape(-1) p = np.asarray(y_pred, dtype=float).reshape(-1) n = np.asarray(y_naive, dtype=float).reshape(-1) denom = np.mean(np.abs(t - n)) + 1e-12 return float(np.mean(np.abs(t - p)) / denom)
[docs] def delta_lag(y_true_seq: Array, y_pred_seq: Array) -> float: """ Lag anticipation metric (ΔLag). Measures alignment between the predicted and actual change directions in a temporal sequence. It compares the sign of consecutive differences and computes their mean product. Parameters ---------- y_true_seq : Array Ground-truth sequence of values. y_pred_seq : Array Predicted sequence of values. Returns ------- float Mean signed alignment between predicted and true change directions, ranging from ``-1`` (complete anti-alignment) to ``1`` (perfect alignment). Notes ----- A value near zero implies random or lagged responses. """ t = np.asarray(y_true_seq, dtype=float).reshape(-1) p = np.asarray(y_pred_seq, dtype=float).reshape(-1) dt_true = np.diff(t) dt_pred = np.diff(p) sign_true = np.sign(dt_true) sign_pred = np.sign(dt_pred) alignment = (sign_true * sign_pred).mean() return float(alignment)
[docs] def rmse(y_true: np.ndarray, y_pred: np.ndarray) -> float: """Root Mean Squared Error (RMSE).""" y_true = np.asarray(y_true, dtype=float) y_pred = np.asarray(y_pred, dtype=float) return float(np.sqrt(np.mean((y_pred - y_true) ** 2)))