Skip to content

Forecast Metrics

Published:
•25 min read

These are my notes on forecast metrics, written in three parts while working on a weekly sales forecast for a retailer.

Definitions

The 3 core metrics are:

Scale Dependent Metrics

MAE

MAE = (1/n) Σ |Actual - Forecast|

calculates the average errors [sales]

ex: if mae=3 -> on average, we miss/overforecast 3 sales per forecast

Advantages: very simple and understandable

Disadvantages: doesn’t reflect the fact that misses on high sellers are more important

BIAS

Bias or Mean error

BIAS = (1/n) Σ (Forecast - Actual)

-> gives additional information about the bias but not intended to evaluate accuracy because positive and negative errors cancel out

Technical Characteristics:

Interpretation:

Percentage Metrics

MAPE

MAPE = (1/n) Σ |(Actual - Forecast) / Actual|

calculates the average percentage error [%]

ex: if mape=0.2 -> on average, we forecast 20% more or less sales per forecast

Advantages: simple and understandable

Disadvantages: undefined for 0 sales (not an issue if 0 sales aren’t your primary concern)

Declinations

sMAPE: more robust against 0 sales, does not penalise positive and negative forecast errors equally (Hyndman)

-> 0 sales and 0 forecast are still a problem. if forecast <1 it explodes

sMAPE = (2/n) Σ |Actual - Forecast| / (|Actual| + |Forecast|)

MAAPE: is defined even when sales =0 (maape=pi/2)

-> doesn’t offer any value cause you can’t aggregate the value pi/2 with other values

MAAPE = (1/N) Σ arctan( |(A_t - F_t) / A_t| )

WAPE

WAPE: scaled to the sum of sales

WAPE = Σ_s Σ_t |Actual_s,t - Forecast_s,t|  /  Σ_s Σ_t Actual_s,t

s = 1..C series, t = 1..H weeks

Advantages:

Disadvantages:

Technical Characteristics:

Critical Limitation:

WAPE masks small-volume SKU performance. If 80% of your SKUs are low-volume but only represent 20% of total sales, their forecast quality is essentially invisible in WAPE. You must segment by volume cohorts or selling class to get meaningful insights.

How to use:

When NOT to use:

Relative Metrics (relative to a naive forecast)

Each of these divides the forecast’s error by the error of a naive forecast. The literature calls MASE and RMSSE scaled errors: they divide by the naive’s error on the training history (Hyndman and Koehler 2006, FPP3 5.8). It calls RelMAE and RelMSE relative measures: they divide by the naive’s error over the same test weeks (Hyndman and Koehler 2006, Hewamalage, Ackermann and Bergmeir 2023).

MASE

MASE = MAE / MAE_in-sample,naive

MASE = (1/n) Σ_i |y_i - ŷ_i|  /  ( (1/(T-m)) Σ_{t=m+1..T} |y_t - y_{t-m}| )

The denominator is the MAE of the seasonal naive forecast (the same week one season earlier) over the T weeks of the training set, with m the season length, 52 for weekly data.

Technical Characteristics:

Advantages:

Disadvantages:

RMSSE

RMSSE = sqrt( (1/n) Σ MSE / MSE_naiveModel )

RMSSE = sqrt( (1/n) Σ_j (y_j - ŷ_j)²  /  ( (1/(T-m)) Σ_{t=m+1..T} (y_t - y_{t-m})² ) )

Technical Characteristics:

Advantages:

Disadvantages:

RelMAE

RelMAE = MAE / MAE_naive = Σ_j |y_j - ŷ_j|  /  Σ_j |y_j - ŷ_naive,j|

The MAE of the forecast divided by the MAE of the naive forecast, both over the same test weeks j. <1 -> our errors are smaller than the naive’s on those weeks, >1 -> larger. unit [-]

RelMSE

RelMSE = MSE / MSE_naive = Σ_j (y_j - ŷ_j)²  /  Σ_j (y_j - ŷ_naive,j)²

The same ratio with squared errors, so large misses weigh more, as with RMSSE compared to MASE. There is no square root, so it moves further from 1 than a ratio of RMSEs would.

Weighted Metric : wRMSSE / wMASE

Weighted metrics allow the aggregation of the metric across multiple time series using a certain weight, the higher the weight of a given time series, the more it influences the aggregated value of the metric

for example for the M5 competition, they used:

w_i = Σ_{t=n-27..n} (p_t,i × Y_t,i)  /  Σ_j Σ_{t=n-27..n} (p_t,j × Y_t,j)

WRMSSE = Σ_{i=1..42,840} w_i × RMSSE_i

where p(t,i) and Y(t,i) are the price and units sold of item i at day t

so for products that are very rarely sold or are very cheap the weights are very close to 0

In our case, we’ve identified 3 types of weights that could be of use: price, volume and turnover (price x volume). These weights are computed as the average value on the last 2 years of historical data (or whatever duration is available)

Interpretations & Examples

MAE vs MAPE vs WAPE

WAPE favors the high sellers when aggregating over high and low sellers

w1w2w3MAEMAPEWAPEglobal WAPEweightsglobal wWAPE
High sellerSales200502000.670.33%0.44%0.88%12.58%
forecast19950199
Low sellerSales2010.6750.00%66.67%5
forecast100

Two series of three weeks. A high seller sells 200, 50 and 200 and is forecast 199, 50 and 199. A low seller sells 2, 0 and 1 and is forecast 1, 0 and 0. Both have an MAE of 0.67. WAPE is 0.44 percent for the high seller, 66.67 percent for the low seller and 0.88 percent for both together; with a weight of 5 on the low seller the weighted WAPE is 2.58 percent.

MASE vs WAPE

Two made up weekly series of 156 weeks from my notebook, with a train/test split at week 104. The high seasonal seller swings between about 80 and 120; the low seasonal seller sells up to about 12 in season and 0 out of season. In both, the forecast is a flat line at the training mean, and the naive follows the actual sales closely in the test weeks.

High seasonal sellers

MetricForecastNaive
Bias-0.0045-0.0048
MAE12.86873.4808
MAPE0.13160.0344
MAAPE0.13010.0344
WAPE0.12820.0347
MASE4.26221.1529
RMSSE3.88101.1096

Low seasonal sellers

MetricForecastNaive
Bias0.09130.1667
MAE2.92901.2500
MAPE0.70260.9050
WAPE1.20880.5159
MASE2.58151.1017
RMSSE1.50121.0038

MASE: the naive does not get a score of exactly 1 (here 1.1017) cause the denominator is calculated on the training set

RMSSE vs MASE

Case 1: RMSSE > MASE

Possible interpretations:

Case 2: RMSSE <= MASE

Possible interpretations:

Weighted vs Unweighted

MASE_volume < MASE_unweighted (or RMSSE)

MASE_turnover < MASE_unweighted (or RMSSE)

Week-by-Week Progression

Why Track MASE/RMSSE Week-by-Week? Unlike WAPE, MASE and RMSSE are unweighted by volume, making weekly tracking meaningful:

MASE/RMSSE weekly trends show pure forecast quality evolution, independent of business volume changes. This is critical for model monitoring and A/B testing.

MASE/RMSSE are scale free meaning Each time series MASE is normalized by its own baseline so the interpretation remains consistent across different levels (high vs low season)

Aggregating

Below is an example where 4 types of time series are studied: mix of flat/seasonal and high/low axes

For the remainder of the plots, our forecast (in red) is average value over the training set

Filtering on the high sellers seasonal

Top: one made up high seasonal series with its flat forecast and the naive. Bottom: for every high seasonal series, WAPE against MAE lies on a tight straight line, from about 0.12 to 0.14; MASE against MAE is a wide cloud between about 3 and 5.

MASE reflects that our forecast is far from the ideal forecast, wape doesn’t very much

Filtering on the high flat

Top: one made up high flat series around 100, where the forecast and the naive are the same flat line. Bottom: for every high flat series, WAPE against MAE is a straight line from about 0.020 to 0.030; MASE against MAE is a cloud between about 0.6 and 1.1.

MASE reflects that our forecast is very close to the basic (naive) forecast.

Filtering on all the dataset

Two scatter plots against MAE for all made up series. WAPE: two blobs high up, between about 0.65 and 1.3, at MAE 1.5 to 3.5, and two blobs near zero, at MAE about 2.5 and about 13. MASE: two blobs near 0.8 at MAE 1.5 to 3, one blob between 1.5 and 3.6 at MAE about 3, and one blob between 3 and 5 at MAE about 13.

4 different blobs are distinguishable in the MASE plot, the 2 blobs with the lowest MAE and MASE correspond to flat series when our average forecast provides a pretty good accuracy. The other 2 blobs correspond to the seasonal series for which the denominator is high due to varying naive forecast errors. The blob with the highest MASE and MAE is for high seasonal and the other for low seasonal.

Notice that for the WAPE, we also have 4 blobs but they are inverted, the ones with the highest WAPE are for flat series while the lowest WAPEs are for seasonal. This is counterintuitive, in fact, from the plot we can clearly see that our forecast (mean over training set) is way better for flat series than for seasonal but the WAPE doesn’t reflect that.

Conclusion

Metrics differ in sensitivity: Absolute ones (e.g., MAE) treat a missed sale equally regardless of volume, which might undervalue high-seller impacts, while relative ones (e.g., MAPE) amplify errors on low sellers but can distort with zeros. WAPE, which you’re using, weights by volume, making errors on high sellers more prominent

For our data science use case, we believe that MASE, RMSSE, BIAS and WPE are essential tools that allow us to evaluate the efficacy of a new modeling strategy. WAPE remains a business facing metrics and can also be used as a data science metric when comparing similar scopes.

Decision matrix

Below is a set of criteria to verify during each modeling experiment

#MetricInterpretation
1MASE_volume / RMSSE_volume < CurrentHigh-volume Time Series improved
2RMSSE_volume < RMSSEImproved forecast where it matters (high volume items)
3Abs(Bias) < CurrentImproved Bias
4RMSSE_volume < MASE_volumeImproved stability of forecast
5WAPE < CurrentOverall accuracy weighted by volume is better

Replacing volume with turnover in the table above is equally valuable as it gives a more direct business value estimation.

Moreover, we can also examine the following:

Business KPIs

In order to evaluate our performance from a point of view of business, we’re suggesting computing bias metrics

We would like to quantify the improvement of our modeling strategy from a business perspective. We want to use turnover information to conduct an analysis of potential gains unlocked with the forecast provided

Based on experts’ estimates from operational experience and supply chain economics, the cost incurred by an equivalent magnitude of underforecasting is estimated to be 3 to 4 times higher than the cost generated by overforecasting (represented primarily by the costs of the additional stock that must be kept and managed).

This fundamental asymmetry necessitates the processing of under and over forecasting differently so that we may evaluate each part. In conclusion:

Beyond Bias

The current Bias is aggregated on the entire dataset and compensates under and over forecast to give a final value which represents the tendency of the entire forecastable time series. Even with the addition of cohorts, which allow to see a bit clearer the tendencies of bias for the different cohorts. We’re still missing the under and over forecasting components essential to evaluate the business impact but also to evaluate the weaknesses of the model (ex: underforecasting a specific family while overforecasting when we aggregate on the department level)

For these reasons, we propose the definition of SignedBias which allows:

The over component keeps only the errors where the forecast is above sales, the under component only those where it is below.

ex:

Four panels of five rows, each bar the change of the new model relative to the production model. Normalised over-forecast in turnover: -3.4, -8.8, -18.5, -25.0 and -28.6 percent. Normalised under-forecast in volume: +3.4, +2.3, +3.0, +8.0 and +16.7 percent. Absolute over-forecast in volume: -1.4, -8.9, -13.6, -19.1 and -22.7 percent; in turnover: -4.0, -10.0, -17.7, -26.7 and -30.7 percent.

A decision diagram in three steps. First, are we worried about lost sales (high cost risk, focus on the negative bias), excess stock (holding cost, focus on the positive bias), or the total bias? Second, is the impact operational (logistics and space, in volume) or financial (turnover: revenue / margin, volume times the average reference price)? Third, do we need raw numbers (absolute) or relative context (normalised, percent of sales)? Examples: negative plus turnover plus percent is a strategic stock-out risk KPI; the positive bias is a tactical overstock KPI; the percentage is the standard forecast accuracy.

Censored Demand & Models Backtesting

During the testing of a new modeling strategy (model2) vs an existing model (model1) we face an immediate issue for a fair comparison. model1 has been used (partially or entirely) for the definition of available stock for items x stores. This is the issue of censored demand:

This is particularly apparent after the definition in the section above of under and over forecast components.

Therefore we have 2 solutions:

No solution is perfect, however the evaluation on available stocks seems closer to reality. We recommend the use of this solution (in addition to the first solution if we want a bigger picture) for cases of backtesting of a new modeling strategy

We compared the results between normalization and the previous model using the 2 methods (sales reconstructed and true demand) the result confirms that there is a reduced underforecast when using sales reconstructed for the prod model but it’s a very slight difference because we’re using sales reconstruction. If raw sales are used, the difference should be larger

Improved MASE / RMSSE

See MASE and RMSSE above for the definitions and implementation of the current mase/rmsse metrics.

We’ve observed that in some cases, the values of mase/rmsse are significantly higher than 100 which would mean that our forecast is really bad compared to a naive forecast. However, upon examination of the forecasts in question, it’s not the case.

Example (a made-up series, not the real one):

A made up weekly series with a yearly pattern. The last 39 training weeks are shown, then a 13 week test phase in which sales jump to about twice their usual level for four weeks, a peak the training data never showed. The forecast follows the yearly pattern; the seasonal naive repeats last year. The forecast's MASE is 490 and the naive's 508, both on a scale where 100 is the naive's error on the training set.

Here our forecast is not perfect, or more particularly, sales were difficult to predict since the peak is totally unexpected.

As we observe, the real problem is that during the test phase in question, we observe an unusual peak (a non seasonal peak that hasn’t been witnessed during training). This makes the numerator (calculated on the test set) of the mase/rmsse very high compared to the denominator (calculated on the train set). Since the denominator is used to gauge the performance of the naive forecast against which we compare our model forecast, this makes our model appear worse than the naive one when in fact it’s the test phase that is harder than the train set.

To remedy this issue, we propose to calculate the mase/rmsse for the naive forecast as well so that we can compare the performance of our forecast & that of the naive in the test phase compared to the performance of the naive on the train set.

This analysis is the same for Mase/Rmsse with or without weights.

Rq:

I’ve improved the implementation of MASE/RMSSE by calculating the naive statistics per sku, store, cutoff, horizon. I then calculated the MASE/RMSSE by aggregating on (series, horizon) first then on all horizons second.

MASE/RMSSE usefulness

mase naive and rmsse naive tell us how the test set is compared to the training set, however in practice, often we find that mase and rmsse naive are:

therefore having just relMae & relMse is good enough

First MASE table, each model relative to the naive (naive = 100):

no weatherweatherreal weather
87.587.586.2
88.088.087.0
84.684.684.6
81.780.780.7
74.074.074.0

cases where naive forecast <100 and naive forecast > prod model (metrics computed per family x country x sales cohort x horizon x cutoff)

A bar chart of the slices of my second MASE table, sorted. Each bar is the model's MASE relative to the naive's MASE on the same slice; every bar is below zero, from about 2 to about 39 percent lower. Slices where the test phase is harder than the train phase and slices where it is not both appear.

scatter plot of ranks of the worst performances of prod model computed using both metrics -> correlation ~= 70%

A scatter of the worst performances of the production model, each placed by its rank under RMSSE and its rank under WAPE, both scaled to the largest rank shown, with a fitted line rising from the bottom left to the top right. The correlation is about 70 percent.

I implemented SignedBias class & RelMse and RelMae

SignedBias allows to compute the cost of overforecast & underforecast independently

RelMAE (Relative Mean Absolute Error): mae(forecast)/mae(naive)

RelMAE relative to the no weather model (no weather = 100):

rowweatherreal weather
1100.0100.0
298.998.9
398.997.8
498.897.7
598.796.2

RelMSE (Relative Mean Squared Error): mse(forecast)/mse(naive)

RelMSE relative to the no weather model (no weather = 100):

rowweatherreal weather
1100.0100.0
2100.097.3
3100.097.1
498.595.5
5100.092.9

All three models are below the naive in every row, for both metrics.

Both produce a single percentage. < 100 means your model beats the naive baseline; > 100 means it’s worse.

We compared the gains of Wape & RelMse of weather implementation vs no weather (metrics computed per product category x sales cohort x horizon x cutoff, compared per product category)

as a result of its Scale independence, RelMse gives more homogeneous gains across categories (fewer outliers) than Wape when aggregating across time series with different sales volumes

References

Newsletter subscriptions are not currently available.