log_cosh(y_true, y_pred, mask=None, axis=0, name='Mae')

Calculate the log of the cosh of the error with a temperature factor to control the transition between the quadratic and linear regions.

Parameters:

Name Type Description Default
y_true TensorLike

The true values of the time series.

required
y_pred TensorLike

The forecasted values of the time series.

required
mask TensorLike

Mask to be applied on the time series. Defaults to None.

None
axis int

Axis along which metrics are computed. Defaults to 0.

0
name str

Python str name prefixed to ops created by this function.

'Mae'

Returns:

Type Description
Tensor

tf.Tensor: The mean log cosh of the error calculated along axis.

Source code in wt_ml/utils/metrics.py
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
@metric_with_variants
def log_cosh(
    y_true: TensorLike, y_pred: TensorLike, mask: TensorLike | None = None, axis: int = 0, name: str = "Mae"
) -> tf.Tensor:
    """Calculate the log of the cosh of the error with a temperature factor to control the
    transition between the quadratic and linear regions.

    Args:
        y_true (TensorLike): The true values of the time series.
        y_pred (TensorLike): The forecasted values of the time series.
        mask (TensorLike): Mask to be applied on the time series. Defaults to None.
        axis (int, optional): Axis along which metrics are computed. Defaults to 0.
        name (str, optional): Python str name prefixed to ops created by this function.

    Returns:
        tf.Tensor: The mean log cosh of the error calculated along `axis`.
    """
    TEMPERATURE = 1e4
    with tf.name_scope(name) as scope:
        abs_residual = tf.abs(residuals(y_true, y_pred, mask)) / TEMPERATURE
        return TEMPERATURE * weighted_mean(
            abs_residual + tf.math.softplus(-2.0 * abs_residual) - tf.math.log(2.0), mask, axis=axis, name=scope
        )

mae(y_true, y_pred, mask=None, axis=0, name='Mae')

Calculate the mean absolute error which is the mean of the absolute value of the residuals.

Parameters:

Name Type Description Default
y_true TensorLike

The true values of the time series.

required
y_pred TensorLike

The forecasted values of the time series.

required
mask TensorLike

Mask to be applied on the time series. Defaults to None.

None
axis int

Axis along which metrics are computed. Defaults to 0.

0
name str

Python str name prefixed to ops created by this function.

'Mae'

Returns:

Type Description
Tensor

tf.Tensor: The mean absolute error calculated along axis.

Source code in wt_ml/utils/metrics.py
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
@metric_with_variants
def mae(
    y_true: TensorLike, y_pred: TensorLike, mask: TensorLike | None = None, axis: int = 0, name: str = "Mae"
) -> tf.Tensor:
    """Calculate the mean absolute error which is the mean of the absolute value of the residuals.

    Args:
        y_true (TensorLike): The true values of the time series.
        y_pred (TensorLike): The forecasted values of the time series.
        mask (TensorLike): Mask to be applied on the time series. Defaults to None.
        axis (int, optional): Axis along which metrics are computed. Defaults to 0.
        name (str, optional): Python str name prefixed to ops created by this function.

    Returns:
        tf.Tensor: The mean absolute error calculated along `axis`.
    """
    with tf.name_scope(name) as scope:
        return weighted_mean(tf.abs(residuals(y_true, y_pred, mask)), mask, axis=axis, name=scope)

mape(y_true, y_pred, mask=None, axis=0, name='Mape')

Calculate the mean absolute percentage error. This is the mean of the residuals divided by the true values.

Parameters:

Name Type Description Default
y_true TensorLike

The true values of the time series.

required
y_pred TensorLike

The forecasted values of the time series.

required
mask TensorLike

Mask to be applied on the time series. Defaults to None.

None
axis int

Axis along which metrics are computed. Defaults to 0.

0
name str

Python str name prefixed to ops created by this function.

'Mape'

Returns:

Type Description
Tensor

tf.Tensor: The mean absolute percentage error calculated along axis.

Source code in wt_ml/utils/metrics.py
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
@metric_with_variants
def mape(
    y_true: TensorLike, y_pred: TensorLike, mask: TensorLike | None = None, axis: int = 0, name: str = "Mape"
) -> tf.Tensor:
    """Calculate the mean absolute percentage error. This is the mean of the residuals
       divided by the true values.

    Args:
        y_true (TensorLike): The true values of the time series.
        y_pred (TensorLike): The forecasted values of the time series.
        mask (TensorLike): Mask to be applied on the time series. Defaults to None.
        axis (int, optional): Axis along which metrics are computed. Defaults to 0.
        name (str, optional): Python str name prefixed to ops created by this function.

    Returns:
        tf.Tensor: The mean absolute percentage error calculated along `axis`.
    """
    with tf.name_scope(name) as scope:
        if mask is None:
            mask = tf.ones_like(y_true)
        return weighted_mean(tf.abs(residuals(y_true, y_pred, mask) / (y_true + EPSILON)), mask, axis=axis, name=scope)

mase(y_true, y_pred, mask=None, axis=0, name='Mase')

Computes the Mean Absolute Scaled Error (MASE).

MASE is a metric used to evaluate forecast accuracy. It measures the performance of a forecasting method against a naive baseline, considering the scale of the time series.

Parameters:

Name Type Description Default
y_true TensorLike

The true values of the time series.

required
y_pred TensorLike

The forecasted values of the time series.

required
mask TensorLike

Mask to be applied on the time series. Defaults to None.

None
axis int

Axis along which metrics are computed. Defaults to 0.

0
name str

Python str name prefixed to ops created by this function.

'Mase'

Returns:

Type Description
Tensor

tf.Tensor: Calculated Mean Absolute Scaled Error.

Source code in wt_ml/utils/metrics.py
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
@metric
def mase(
    y_true: TensorLike, y_pred: TensorLike, mask: TensorLike | None = None, axis: int = 0, name: str = "Mase"
) -> tf.Tensor:
    """
    Computes the Mean Absolute Scaled Error (MASE).

    MASE is a metric used to evaluate forecast accuracy. It measures the performance
    of a forecasting method against a naive baseline, considering the scale of the time series.

    Args:
        y_true (TensorLike): The true values of the time series.
        y_pred (TensorLike): The forecasted values of the time series.
        mask (TensorLike): Mask to be applied on the time series. Defaults to None.
        axis (int, optional): Axis along which metrics are computed. Defaults to 0.
        name (str, optional): Python str name prefixed to ops created by this function.

    Returns:
        tf.Tensor: Calculated Mean Absolute Scaled Error.
    """
    with tf.name_scope(name) as scope:
        mask = tf.convert_to_tensor(mask, dtype_hint=tf.bool, name="mask")
        numeric_mask = tf.cast(mask, dtype=y_true.dtype, name="numeric_mask")
        naive_mae = tf.abs(tf.experimental.numpy.diff(y_true * numeric_mask, axis=axis))
        weighted_naive_mae = tf.math.divide_no_nan(
            tf.reduce_sum(naive_mae, axis=axis),
            tf.reduce_sum(numeric_mask, axis=axis),
        )
        return mae(y_true, y_pred, mask, axis, scope) / (weighted_naive_mae + EPSILON)

metric(func)

Denotes a metric function.

Source code in wt_ml/utils/metrics.py
18
19
20
21
22
23
def metric(func: MetricFunc) -> MetricFunc:
    """Denotes a metric function."""
    # TODO (legendof-selda) check if metric is following the same Protocol
    global METRICS
    METRICS[func.__name__] = func
    return func

mse(y_true, y_pred, mask, axis=0, name='MSE')

Calculate the mean squared error which is the mean of the square of the residuals.

Parameters:

Name Type Description Default
y_true TensorLike

The true values of the time series.

required
y_pred TensorLike

The forecasted values of the time series.

required
mask TensorLike

Mask to be applied on the time series. Defaults to None.

required
axis int

Axis along which metrics are computed. Defaults to 0.

0
name str

Python str name prefixed to ops created by this function.

'MSE'

Returns:

Type Description
Tensor

tf.Tensor: The mean squared error calculated along axis.

Source code in wt_ml/utils/metrics.py
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
@metric_with_variants
def mse(y_true: TensorLike, y_pred: TensorLike, mask: TensorLike, axis: int = 0, name: str = "MSE") -> tf.Tensor:
    """Calculate the mean squared error which is the mean of the square of the residuals.

    Args:
        y_true (TensorLike): The true values of the time series.
        y_pred (TensorLike): The forecasted values of the time series.
        mask (TensorLike): Mask to be applied on the time series. Defaults to None.
        axis (int, optional): Axis along which metrics are computed. Defaults to 0.
        name (str, optional): Python str name prefixed to ops created by this function.

    Returns:
        tf.Tensor: The mean squared error calculated along `axis`.
    """
    with tf.name_scope(name) as scope:
        return weighted_mean(tf.square(residuals(y_true, y_pred, mask)), mask, axis=axis, name=scope)

residuals(y_true, y_pred, mask)

Calculate the residuals which are the difference between the true and forecased values.

Parameters:

Name Type Description Default
y_true TensorLike

The true values of the time series.

required
y_pred TensorLike

The forecasted values of the time series.

required
mask TensorLike | None

The values which should be masked out of the calculation.

required

Returns:

Type Description
Tensor

tf.Tensor: The masked absolute difference between y_true and y_pred.

Source code in wt_ml/utils/metrics.py
273
274
275
276
277
278
279
280
281
282
283
284
285
def residuals(y_true: TensorLike, y_pred: TensorLike, mask: TensorLike | None) -> tf.Tensor:
    """Calculate the residuals which are the difference between the true and forecased values.

    Args:
        y_true (TensorLike): The true values of the time series.
        y_pred (TensorLike): The forecasted values of the time series.
        mask (TensorLike | None): The values which should be masked out of the calculation.

    Returns:
        tf.Tensor: The masked absolute difference between y_true and y_pred.
    """
    res = y_true - y_pred
    return res if mask is None else res * tf.cast(mask, dtype=res.dtype)

rmse(y_true, y_pred, mask, axis=0, name='RMSE')

Calculate the root mean squared error which is the square root of the mean squared error. We take the square root so the result has the same units as the input.

Parameters:

Name Type Description Default
y_true TensorLike

The true values of the time series.

required
y_pred TensorLike

The forecasted values of the time series.

required
mask TensorLike

Mask to be applied on the time series. Defaults to None.

required
axis int

Axis along which metrics are computed. Defaults to 0.

0
name str

Python str name prefixed to ops created by this function.

'RMSE'

Returns:

Type Description
Tensor

tf.Tensor: The root mean squared error calculated along axis.

Source code in wt_ml/utils/metrics.py
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
@metric_with_variants
def rmse(y_true: TensorLike, y_pred: TensorLike, mask: TensorLike, axis: int = 0, name: str = "RMSE") -> tf.Tensor:
    """Calculate the root mean squared error which is the square root of the mean squared error.
       We take the square root so the result has the same units as the input.

    Args:
        y_true (TensorLike): The true values of the time series.
        y_pred (TensorLike): The forecasted values of the time series.
        mask (TensorLike): Mask to be applied on the time series. Defaults to None.
        axis (int, optional): Axis along which metrics are computed. Defaults to 0.
        name (str, optional): Python str name prefixed to ops created by this function.

    Returns:
        tf.Tensor: The root mean squared error calculated along `axis`.
    """
    with tf.name_scope(name) as scope:
        return tf.sqrt(mse(y_true, y_pred, mask, axis=axis, name=scope))

smape(y_true, y_pred, mask=None, axis=0, name='SMape')

Calculate the symmetric mean absolute percentage error. This calculates the percentage errors as twice the residual divided by the sum of forecasted and true values.

Parameters:

Name Type Description Default
y_true TensorLike

The true values of the time series.

required
y_pred TensorLike

The forecasted values of the time series.

required
mask TensorLike

Mask to be applied on the time series. Defaults to None.

None
axis int

Axis along which metrics are computed. Defaults to 0.

0
name str

Python str name prefixed to ops created by this function.

'SMape'

Returns:

Type Description
Tensor

tf.Tensor: The symmetric mean absolute percentage error calculated along axis.

Source code in wt_ml/utils/metrics.py
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
@metric_with_variants
def smape(
    y_true: TensorLike, y_pred: TensorLike, mask: TensorLike | None = None, axis: int = 0, name: str = "SMape"
) -> tf.Tensor:
    """Calculate the symmetric mean absolute percentage error. This calculates the percentage
       errors as twice the residual divided by the sum of forecasted and true values.

    Args:
        y_true (TensorLike): The true values of the time series.
        y_pred (TensorLike): The forecasted values of the time series.
        mask (TensorLike): Mask to be applied on the time series. Defaults to None.
        axis (int, optional): Axis along which metrics are computed. Defaults to 0.
        name (str, optional): Python str name prefixed to ops created by this function.

    Returns:
        tf.Tensor: The symmetric mean absolute percentage error calculated along `axis`.
    """
    with tf.name_scope(name) as scope:
        return weighted_mean(
            2 * tf.abs(residuals(y_true, y_pred, mask) / (tf.abs(y_true) + tf.abs(y_pred) + EPSILON)),
            mask,
            axis=axis,
            name=scope,
        )

weighted_mean(data, mask, axis=None, keepdims=False, name='WeightedMean')

Calculate the mean of the input array weighted by the mask along axis. Requires time axis at 0. Args: data (TensorLike): The array to take the mean over. mask (TensorLike | None): The weights (or mask if it is all 0's and 1's) to use when taking the mean. None would simply take mean over the given axis. axis (int | Sequence[int] | None, optional): The axis to take the mean over. Defaults to None. keepdims (bool, optional): Whether to keep the dimensions we take the mean over. Defaults to False. name (str, optional): Python str name prefixed to ops created by this function.

Returns:

Type Description

tf.Tensor: The weighted mean of data.

Source code in wt_ml/utils/metrics.py
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
def weighted_mean(
    data: TensorLike,
    mask: TensorLike | None,
    axis: list[int] | tuple[int, ...] | int | None = None,
    keepdims: bool = False,
    name: str = "WeightedMean",
):
    """Calculate the mean of the input array weighted by the mask along axis.
        Requires time axis at 0.
    Args:
        data (TensorLike): The array to take the mean over.
        mask (TensorLike | None): The weights (or mask if it is all 0's and 1's) to use when taking the mean.
                None would simply take mean over the given axis.
        axis (int | Sequence[int] | None, optional): The axis to take the mean over. Defaults to None.
        keepdims (bool, optional): Whether to keep the dimensions we take the mean over. Defaults to False.
        name (str, optional): Python str name prefixed to ops created by this function.

    Returns:
        tf.Tensor: The weighted mean of data.
    """
    with tf.name_scope(name) as scope:
        if mask is None:
            return tf.reduce_mean(data, axis=axis, keepdims=keepdims)

        data = tf.convert_to_tensor(data, dtype_hint=data.dtype, name="data")
        mask = tf.convert_to_tensor(mask, dtype_hint=tf.bool, name="mask")
        numeric_mask = tf.cast(mask, dtype=data.dtype, name="numeric_mask")
        return tf.math.divide_no_nan(
            tf.math.reduce_sum(data * numeric_mask, axis=axis, keepdims=keepdims),
            tf.math.reduce_sum(numeric_mask, axis=axis, keepdims=keepdims),
            name=scope,
        )

weighted_metric(func)

Wraps a metric function so that it can calculate weighted average on the metric.

Source code in wt_ml/utils/metrics.py
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
def weighted_metric(func: MetricFunc) -> WeightedMetricFunc:
    """Wraps a metric function so that it can calculate weighted average on the metric."""

    @wraps(func)
    def wrapped(
        y_true: TensorLike,
        y_pred: TensorLike,
        mask: TensorLike,
        weights: TensorLike | None = None,
        axis: int = 0,
        keepdims: bool = False,
        name: str = f"Weighted{func.__name__}",
    ) -> tf.Tensor:
        f"""Calculate the weighted {func.__name__} metric.

        Args:
            y_true (TensorLike): The true values of the time series.
            y_pred (TensorLike): The forecasted values of the time series.
            mask (TensorLike): Mask to be applied on the time series. Defaults to None.
            weights (TensorLike | None): An array of weights associated with the values in `metric_result`.
                Each value in `metric_result` contributes to the average according to its associated weight.
                The weights array can either be 1-D (in which case its length must be the size of a along the given
                axis) or of the same shape as a.
                If weights=None, then we don't perform weighted average and return the `metric_result`.
                Defaults to None.
            axis (int, optional): Axis along which metrics are computed. Defaults to 0.
            keepdims (bool, optional): Whether to keep the dimensions we take the mean over. Defaults to False.
            name (str, optional): Python str name prefixed to ops created by this function.

        Returns:
            tf.Tensor: Weighted {func.__name__} calculated along `axis`.
        """
        with tf.name_scope(name) as scope:
            metric_result = func(y_true, y_pred, mask, axis, scope)
            if weights is None:
                return metric_result
            else:
                return weighted_mean(
                    metric_result, weights, axis=axis - 1 if axis > 0 else -1, keepdims=keepdims, name=scope
                )

    return wrapped

wmape(y_true, y_pred, mask=None, axis=0, name='WMape')

Calculate the weighted mean absolute percentage error. This is the mean of the individual absolute percentage errors weighted by the true value.

Parameters:

Name Type Description Default
y_true TensorLike

The true values of the time series.

required
y_pred TensorLike

The forecasted values of the time series.

required
mask TensorLike

Mask to be applied on the time series. Defaults to None.

None
axis int

Axis along which metrics are computed. Defaults to 0.

0
name str

Python str name prefixed to ops created by this function.

'WMape'

Returns:

Type Description
Tensor

tf.Tensor: The weighted mean absolute percentage error calculated along axis.

Source code in wt_ml/utils/metrics.py
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
@metric_with_variants
def wmape(
    y_true: TensorLike, y_pred: TensorLike, mask: TensorLike | None = None, axis: int = 0, name: str = "WMape"
) -> tf.Tensor:
    """Calculate the weighted mean absolute percentage error. This is the mean of the individual
       absolute percentage errors weighted by the true value.

    Args:
        y_true (TensorLike): The true values of the time series.
        y_pred (TensorLike): The forecasted values of the time series.
        mask (TensorLike): Mask to be applied on the time series. Defaults to None.
        axis (int, optional): Axis along which metrics are computed. Defaults to 0.
        name (str, optional): Python str name prefixed to ops created by this function.

    Returns:
        tf.Tensor: The weighted mean absolute percentage error calculated along `axis`.
    """
    with tf.name_scope(name):
        return tf.reduce_sum(tf.abs(residuals(y_true, y_pred, mask)), axis=axis) / (
            tf.reduce_sum(mask * y_true, axis=axis) + EPSILON
        )