Coverage for mlinsights/timeseries/metrics.py: 100%

20 statements  

« prev     ^ index     » next       coverage.py v7.1.0, created at 2023-02-28 08:46 +0100

1""" 

2@file 

3@brief Timeseries metrics. 

4""" 

5import numpy 

6 

7 

8def ts_mape(expected_y, predicted_y, sample_weight=None): 

9 """ 

10 Computes :math:`\\frac{\\sum_i | \\hat{Y_t} - Y_t |} 

11 {\\sum_i | Y_t - Y_{t-1} |}`. 

12 It compares the prediction to what a dummy 

13 predictor would do by using the previous day 

14 as a prediction. 

15 

16 @param expected_y expected values 

17 @param predicted_y predictions 

18 @return metrics 

19 """ 

20 if len(expected_y) != len(predicted_y): 

21 raise ValueError( # pragma: no cover 

22 f'Size mismatch {len(expected_y)} != {len(predicted_y)}.') 

23 expected_y = numpy.squeeze(expected_y) 

24 predicted_y = numpy.squeeze(predicted_y) 

25 mask = numpy.isnan(predicted_y) 

26 mask2 = mask.copy() 

27 mask2[1:] |= numpy.isnan(predicted_y[:-1]) 

28 expected_y = numpy.ma.masked_array(expected_y, mask=mask) 

29 predicted_y = numpy.ma.masked_array(predicted_y, mask=mask2) 

30 if sample_weight is None: 

31 dy1 = numpy.sum(numpy.abs(expected_y[:-1] - expected_y[1:])) 

32 dy2 = numpy.sum(numpy.abs(predicted_y[1:] - expected_y[1:])) 

33 else: 

34 dy1 = numpy.sum( 

35 (numpy.abs(expected_y[:-1] - expected_y[1:]) * sample_weight[1:])) 

36 dy2 = numpy.sum( 

37 (numpy.abs(predicted_y[1:] - expected_y[1:]) * sample_weight[1:])) 

38 dy1 = dy1.sum() 

39 dy2 = dy2.sum() 

40 if dy1 == 0: 

41 return 0 if dy2 == 0 else numpy.infty 

42 return dy2 / dy1