The loss_functions module defines reusable deterministic and probabilistic forecasting loss/metric functions implemented with JAX tensors for model training and evaluation.
mean_absolute_error
chronax.loss_functions.mean_absolute_error
Compute the mean absolute error between observed and predicted values.
mean_absolute_error(y: Array, y_pred: Array) -> Array
Computes the average of the absolute element-wise differences between the target array y and the prediction array y_pred. This is a scale-dependent metric: larger magnitudes in the data yield larger MAE. Used throughout the module as the primary L1 loss and as the denominator in scaled metrics (e.g. MASE, relative MAE).
| Parameter | Type | Default | Description |
|---|---|---|---|
y |
Array |
- | Observed or true values; any shape supported by JAX. |
y_pred |
Array |
- | Predicted values; must be broadcast-compatible with y. |
Returns: Array (Scalar (0-dimensional) JAX array containing the mean absolute error. Typically converted to float for reporting.)
mean_squared_error
chronax.loss_functions.mean_squared_error
Compute the mean squared error between observed and predicted values.
mean_squared_error(y: Array, y_pred: Array) -> Array
Computes the average of the squared element-wise errors (y - y_pred)^2. MSE is scale-dependent and penalizes large errors more than MAE. It is differentiable everywhere and is commonly used as a training objective and for variance estimation in scaled metrics (e.g. MSSE, RMSSE).
| Parameter | Type | Default | Description |
|---|---|---|---|
y |
Array |
- | Observed or true values; any shape supported by JAX. |
y_pred |
Array |
- | Predicted values; must be broadcast-compatible with y. |
Returns: Array (Scalar (0-dimensional) JAX array containing the mean squared error. Units are the square of the original variable.)
root_mean_squared_error
chronax.loss_functions.root_mean_squared_error
Compute the root mean squared error (RMSE) between observed and predicted values.
root_mean_squared_error(y: Array, y_pred: Array) -> Array
Computes the square root of the mean squared error so that the result is in the same units as the target variable. RMSE is scale-dependent and is widely used for point-forecast accuracy reporting and comparison across models.
| Parameter | Type | Default | Description |
|---|---|---|---|
y |
Array |
- | Observed or true values; any shape supported by JAX. |
y_pred |
Array |
- | Predicted values; must be broadcast-compatible with y. |
Returns: Array (Scalar (0-dimensional) JAX array containing RMSE, in same units as y and y_pred.)
bias
chronax.loss_functions.bias
Compute the signed forecast error (prediction minus actual) at each element.
bias(y: Array, y_pred: Array) -> Array
Returns the element-wise difference y_pred - y, i.e. positive values indicate over-forecasting and negative values indicate under-forecasting. Used to assess systematic bias in forecasts and in inventory/stock applications where sign of error matters.
| Parameter | Type | Default | Description |
|---|---|---|---|
y |
Array |
- | Observed or true values. |
y_pred |
Array |
- | Predicted values; must be broadcast-compatible with y. |
Returns: Array (Same shape as (broadcast of) y and y_pred, containing signed errors. Not aggregated; callers may sum or average as needed.)
cfe
chronax.loss_functions.cfe
Compute the cumulative sum of forecast errors (actual minus predicted) over time.
cfe(y: Array, y_pred: Array) -> Array
Forms the sequence of running totals of (y - y_pred). Positive values indicate persistent under-forecasting (actuals exceed predictions); negative values indicate persistent over-forecasting. Used in inventory and demand planning to track bias accumulation over the horizon.
| Parameter | Type | Default | Description |
|---|---|---|---|
y |
Array |
- | Observed values, typically a 1D time series. |
y_pred |
Array |
- | Predicted values; same length/shape as y for meaningful interpretation. |
Returns: Array (Cumulative sum of (y - y_pred), same shape as the flattened difference. For 1D inputs, shape (n,) with the i-th element being the sum of the first i errors.)
pis
chronax.loss_functions.pis
Compute the absolute cumulative forecast error (Period In Stock style).
pis(y: Array, y_pred: Array) -> Array
Takes the cumulative sum of (y - y_pred) and returns its element-wise absolute value. Measures the magnitude of accumulated bias over time regardless of direction, used in inventory contexts to quantify cumulative deviation from forecasts.
| Parameter | Type | Default | Description |
|---|---|---|---|
y |
Array |
- | Observed values (e.g. demand or sales). |
y_pred |
Array |
- | Predicted values; same shape as y for interpretation. |
Returns: Array (Absolute values of the cumulative sum of (y - y_pred), same shape as the cumulative sum.)
spis
chronax.loss_functions.spis
Compute the scaled absolute cumulative forecast error (SPIS).
spis(y: Array, y_pred: Array) -> Array
Computes the absolute cumulative error (PIS), then scales it by its mean so that the resulting sequence has mean 1.0. This yields a scale-independent view of how cumulative error evolves relative to its typical magnitude, used for cross-series comparison in inventory and demand forecasting.
| Parameter | Type | Default | Description |
|---|---|---|---|
y |
Array |
- | Observed values. |
y_pred |
Array |
- | Predicted values; same shape as y. |
Returns: Array (PIS values divided by their mean; same shape as PIS. Mean of the output is 1.0 (unless PIS is all zeros, in which case division may produce non-finite values).)
mean_absolute_percentage_error
chronax.loss_functions.mean_absolute_percentage_error
Compute the mean absolute percentage error (MAPE).
mean_absolute_percentage_error(y: Array, y_pred: Array) -> Array
Computes the mean of |y - y_pred| / (|y| + eps), with a small epsilon to avoid division by zero. MAPE is scale-independent and expressed as a proportion (e.g. 0.05 for 5% average error). It is undefined or unstable when true values are zero or very small.
| Parameter | Type | Default | Description |
|---|---|---|---|
y |
Array |
- | Observed or true values. Should be non-zero for meaningful interpretation; zeros are stabilized with 1e-8. |
y_pred |
Array |
- | Predicted values; broadcast-compatible with y. |
Returns: Array (Scalar mean absolute percentage error (fraction, not percentage). Multiply by 100 for percentage units.)
symmetric_mean_absolute_percentage_error
chronax.loss_functions.symmetric_mean_absolute_percentage_error
Compute the symmetric mean absolute percentage error (SMAPE).
symmetric_mean_absolute_percentage_error(y: Array, y_pred: Array) -> Array
Computes the mean of |y - y_pred| / (|y| + |y_pred|), which is symmetric in actual and predicted and bounded between 0 and 1. Unlike MAPE, it remains defined when actuals or predictions are zero (except when both are zero at the same point). Commonly used in forecasting benchmarks as a scale-independent metric.
| Parameter | Type | Default | Description |
|---|---|---|---|
y |
Array |
- | Observed or true values. |
y_pred |
Array |
- | Predicted values; broadcast-compatible with y. |
Returns: Array (Scalar SMAPE (fraction in [0, 1]). Multiply by 100 for percentage.)
mean_absolute_scaled_error
chronax.loss_functions.mean_absolute_scaled_error
Compute the mean absolute scaled error (MASE) using a seasonal naive baseline.
mean_absolute_scaled_error(y: Array, y_pred: Array, y_seasonal: Array) -> Array
Scales the mean absolute error of the model (|y - y_pred|) by the mean absolute error of a seasonal naive forecast (|y - y_seasonal|). Values below 1.0 indicate the model outperforms the naive baseline; above 1.0 indicates worse performance. MASE is scale-independent and comparable across series with different units.
| Parameter | Type | Default | Description |
|---|---|---|---|
y |
Array |
- | Observed values (typically out-of-sample). |
y_pred |
Array |
- | Model predictions; same shape as y. |
y_seasonal |
Array |
- | Seasonal naive baseline (e.g. previous season same period); same shape as y. Often y_seasonal[t] = y[t - period]. |
Returns: Array (Scalar MASE. Ratio of model MAE to baseline MAE; denominator is stabilized with 1e-8 internally where needed.)
relative_mean_absolute_error
chronax.loss_functions.relative_mean_absolute_error
Compute the relative mean absolute error (RelMAE) against an arbitrary baseline.
relative_mean_absolute_error(y: Array, y_pred: Array, y_base: Array) -> Array
Divides the mean absolute error of the model (|y - y_pred|) by the mean absolute error of a baseline forecast (|y - y_base|). Values below 1.0 mean the model beats the baseline; above 1.0 means the baseline is better. The baseline can be naive, seasonal naive, or another model's forecasts, enabling flexible pairwise comparison.
| Parameter | Type | Default | Description |
|---|---|---|---|
y |
Array |
- | Observed values. |
y_pred |
Array |
- | Model predictions; same shape as y. |
y_base |
Array |
- | Baseline forecast values; same shape as y. |
Returns: Array (Scalar RelMAE. Ratio of model MAE to baseline MAE.)
normalized_deviation
chronax.loss_functions.normalized_deviation
Compute the normalized total absolute deviation by total observed value.
normalized_deviation(y: Array, y_pred: Array) -> Array
Divides the sum of absolute errors (|y - y_pred|) by the sum of observed values (y). Yields a scale-independent ratio interpretable as total absolute error per unit of total demand/volume. Used in inventory and demand contexts where total volume is the natural scale.
| Parameter | Type | Default | Description |
|---|---|---|---|
y |
Array |
- | Observed values (e.g. demand); typically non-negative. |
y_pred |
Array |
- | Predicted values; same shape as y. |
Returns: Array (Scalar ratio. Sum(|y - y_pred|) / Sum(y). No explicit denominator stabilization; caller should ensure sum(y) > 0.)
mean_squared_scaled_error
chronax.loss_functions.mean_squared_scaled_error
Compute the mean squared scaled error (MSSE) using a seasonal baseline.
mean_squared_scaled_error(y: Array, y_pred: Array, y_seasonal: Array) -> Array
Scales the mean squared error of the model by the MSE of a seasonal naive forecast (y vs y_seasonal). Analogous to MASE but for squared errors; values below 1.0 indicate the model outperforms the baseline. Scale-independent and useful when squared-error loss is the objective.
| Parameter | Type | Default | Description |
|---|---|---|---|
y |
Array |
- | Observed values. |
y_pred |
Array |
- | Model predictions; same shape as y. |
y_seasonal |
Array |
- | Seasonal naive baseline; same shape as y. |
Returns: Array (Scalar MSSE. Ratio of model MSE to baseline MSE.)
root_mean_squared_scaled_error
chronax.loss_functions.root_mean_squared_scaled_error
Compute the root mean squared scaled error (RMSSE) using a seasonal baseline.
root_mean_squared_scaled_error(y: Array, y_pred: Array, y_seasonal: Array) -> Array
Computes the element-wise squared error scaled by baseline MSE, then takes the mean of the square roots (so each term is in "RMSE units" relative to the baseline), and returns the mean of those. Produces a scale-independent metric that penalizes large relative errors. Used in forecasting competitions and benchmarks.
| Parameter | Type | Default | Description |
|---|---|---|---|
y |
Array |
- | Observed values. |
y_pred |
Array |
- | Model predictions; same shape as y. |
y_seasonal |
Array |
- | Seasonal naive baseline; same shape as y. |
Returns: Array (Scalar RMSSE. Mean of sqrt((y - y_pred)^2 / baseline_MSE).)
quantile_loss
chronax.loss_functions.quantile_loss
Compute the mean quantile (pinball) loss for a single quantile level.
quantile_loss(y: jnp.ndarray, y_pred: jnp.ndarray, q: float) -> jnp.ndarray
For each observation, the loss is q * (y - y_pred) when y > y_pred (under-prediction) and (q - 1) * (y - y_pred) when y <= y_pred (over-prediction). The mean over all observations is returned. This loss is minimized when y_pred equals the q-quantile of the conditional distribution of y. Used for quantile regression and prediction interval estimation.
| Parameter | Type | Default | Description |
|---|---|---|---|
y |
jnp.ndarray |
- | True observed values; typically shape (N,) or broadcast-compatible. |
y_pred |
jnp.ndarray |
- | Predicted quantile values; same shape as y. |
q |
float |
- | Quantile level in (0, 1), e.g. 0.5 for median, 0.1 for lower tail, 0.9 for upper tail. |
Returns: jnp.ndarray (Scalar mean pinball loss. Same dtype as inputs.)
scaled_quantile_loss
chronax.loss_functions.scaled_quantile_loss
Compute the scaled quantile loss (SQL): quantile loss normalized by baseline MAE.
scaled_quantile_loss(y: jnp.ndarray, y_pred: jnp.ndarray, q: float, y_seasonal: jnp.ndarray) -> jnp.ndarray
Computes the mean quantile (pinball) loss for level q, then divides by the mean absolute error of a seasonal naive baseline (y vs y_seasonal). This makes the metric scale-independent and comparable across series. Values below 1.0 indicate the quantile forecast beats the naive baseline.
| Parameter | Type | Default | Description |
|---|---|---|---|
y |
jnp.ndarray |
- | Test (out-of-sample) actual values; shape (N,) or compatible. |
y_pred |
jnp.ndarray |
- | Test (out-of-sample) quantile predictions for level q; same shape as y. |
q |
float |
- | Quantile level in (0, 1). |
y_seasonal |
jnp.ndarray |
- | In-sample seasonal baseline (e.g. previous season same period); same shape as y. Used to compute denominator MAE. |
Returns: jnp.ndarray (Scalar SQL. Quantile loss / (MAE of baseline); denominator is stabilized with 1e-8.)
multi_quantile_loss
chronax.loss_functions.multi_quantile_loss
Compute the mean multi-quantile (pinball) loss across multiple quantile levels.
multi_quantile_loss(y: jnp.ndarray, y_pred: jnp.ndarray, quantiles: jnp.ndarray) -> jnp.ndarray
For each quantile level and each observation, computes the pinball loss (as in quantile_loss). The implementation uses broadcasting: errors = y - y_pred (across quantiles), then applies max(q * errors, (q - 1) * errors) per quantile and takes the mean over all elements. Used to evaluate full predictive distributions via several quantile predictions (e.g. 0.1, 0.5, 0.9).
| Parameter | Type | Default | Description |
|---|---|---|---|
y |
jnp.ndarray |
- | True values. May be (N,) expanded to (N, Q) or (N, Q) directly; must broadcast with y_pred. |
y_pred |
jnp.ndarray |
- | Predicted quantiles; shape (N, Q) for N samples and Q quantile levels. |
quantiles |
jnp.ndarray |
- | Quantile levels, shape (Q,), e.g. [0.1, 0.5, 0.9]. |
Returns: jnp.ndarray (Scalar mean loss across all samples and quantiles.)
scaled_multi_quantile_loss
chronax.loss_functions.scaled_multi_quantile_loss
Compute the scaled multi-quantile loss (SMQL): MQL normalized by baseline MAE.
scaled_multi_quantile_loss(y: jnp.ndarray, y_pred_quantiles: jnp.ndarray, quantiles: jnp.ndarray, y_seasonal: jnp.ndarray) -> jnp.ndarray
Computes the multi-quantile (pinball) loss across all quantile levels, then divides by the mean absolute error of a seasonal naive baseline (y vs y_seasonal). Yields a scale-independent score for full probabilistic forecasts; values below 1.0 indicate the model outperforms the baseline on average across quantiles.
| Parameter | Type | Default | Description |
|---|---|---|---|
y |
jnp.ndarray |
- | Actual out-of-sample values; (N,) or compatible. |
y_pred_quantiles |
jnp.ndarray |
- | Predicted quantiles for each level; shape (N, Q). |
quantiles |
jnp.ndarray |
- | Quantile levels, shape (Q,). |
y_seasonal |
jnp.ndarray |
- | Seasonal naive baseline; same length as y. Used as denominator MAE. |
Returns: jnp.ndarray (Scalar SMQL. MQL / (MAE of baseline); denominator stabilized with 1e-8.)
coverage
chronax.loss_functions.coverage
Compute the empirical coverage rate of a prediction interval.
coverage(y: jnp.ndarray, y_lo: jnp.ndarray, y_hi: jnp.ndarray) -> jnp.ndarray
Counts the fraction of observations where the true value y lies within the interval [y_lo, y_hi]. For a well-calibrated (1 - alpha) interval (e.g. 90%), coverage should be close to (1 - alpha). Used to assess whether prediction intervals are too narrow (under-coverage) or too wide (over-coverage).
| Parameter | Type | Default | Description |
|---|---|---|---|
y |
jnp.ndarray |
- | True target values; shape (N,) or compatible. |
y_lo |
jnp.ndarray |
- | Lower bound of the prediction interval (e.g. 5th percentile); same shape as y. |
y_hi |
jnp.ndarray |
- | Upper bound (e.g. 95th percentile); same shape as y. |
Returns: jnp.ndarray (Scalar in [0, 1]. Proportion of points with y_lo <= y <= y_hi.)
calibration
chronax.loss_functions.calibration
Compute the empirical calibration rate for a quantile forecast.
calibration(y: jnp.ndarray, y_pred: jnp.ndarray) -> jnp.ndarray
Returns the fraction of observations where the true value y is less than or equal to the predicted quantile y_pred. For a correctly calibrated q-quantile forecast, this fraction should be close to q. Used to check whether quantile predictions are well-calibrated (e.g. 50% of actuals below median forecast).
| Parameter | Type | Default | Description |
|---|---|---|---|
y |
jnp.ndarray |
- | True target values; shape (N,) or compatible. |
y_pred |
jnp.ndarray |
- | Predicted quantile values (e.g. median or other level); same shape as y. |
Returns: jnp.ndarray (Scalar in [0, 1]. Proportion of points with y <= y_pred.)
scaled_crps
chronax.loss_functions.scaled_crps
Compute a scaled approximation to the Continuous Ranked Probability Score (CRPS).
scaled_crps(y: jnp.ndarray, y_pred: jnp.ndarray, quantiles: jnp.ndarray) -> jnp.ndarray
Uses the multi-quantile loss (MQL) as a discrete approximation to the CRPS, then scales by (2 * MQL * N) / (sum of |y|) so the result is scale-independent and comparable across series. Larger values indicate worse probabilistic forecasts. The formula rewards sharpness and calibration of the predictive distribution represented by the quantiles.
| Parameter | Type | Default | Description |
|---|---|---|---|
y |
jnp.ndarray |
- | True observed values; shape (N,). |
y_pred |
jnp.ndarray |
- | Predicted quantiles for each observation; shape (N, Q) for Q quantile levels. |
quantiles |
jnp.ndarray |
- | Quantile levels, shape (Q,), e.g. [0.1, 0.5, 0.9]. |
Returns: jnp.ndarray (Scalar scaled CRPS. Denominator uses sum(|y|) with epsilon stabilization to avoid division by zero.)
tweedie_deviance
chronax.loss_functions.tweedie_deviance
Compute the Tweedie deviance for exponential-dispersion family distributions.
tweedie_deviance(y: jnp.ndarray, y_pred: jnp.ndarray, power: float) -> jnp.ndarray
Evaluates the unit deviance for the Tweedie family parameterized by power. Special cases: power=0 (Gaussian/MSE), power=1 (Poisson), power=2 (Gamma). For 1 < power < 2 the distribution is compound Poisson-Gamma; for power > 2, inverse Gaussian. Used in generalized linear models and loss functions for non-negative or count targets. Returns the mean deviance over observations (and over models if y_pred has an extra dimension).
| Parameter | Type | Default | Description |
|---|---|---|---|
y |
jnp.ndarray |
- | True observed values; shape (N,) or (N,) for broadcasting. Must be non-negative for power >= 1; strictly positive for power >= 2. |
y_pred |
jnp.ndarray |
- | Predicted values; shape (N,) or (N, M) for M models. Must be strictly positive. |
power |
float |
- | Tweedie power parameter: 0 (Gaussian), 1 (Poisson), in (1, 2) (compound Poisson-Gamma), 2 (Gamma), >2 (inverse Gaussian). |
Returns: jnp.ndarray (Mean deviance (scalar or per-model if y_pred is (N, M)). Same units as squared error for power=0.)
Raises:
* ValueError: If power < 0; if power >= 2 and any y <= 0; if any y_pred <= 0.