Coherent forecasts finance can plan against
Today let's learn how to make a set of forecasts add up, so that finance has one set of numbers to plan against.
Maya is a planning analyst at an outdoor-gear retailer. The company sells in four regions: North, South, East and West. Maya has to prepare the 2024 monthly revenue plan, in dollars.
She fits one forecasting model to each region and one more to the national total. That makes five models, and each one forecasts revenue for 2024. The table below shows the annual plan from each of them.
Add up the four regional plans and you get $22,231,567. But the national plan says $21,932,408. So the same revenue for the same year is planned at two different totals, and they are $299,159 apart.
How four regions and a national total form a hierarchy
Let's start with the structure of Maya's data.
Revenue is recorded for each of the four regions, and the national revenue is the sum of the four in every month. A set of series where some are the sum of others is called a hierarchy. This one has two levels: the national total at the top and the four regions below it.
The rule that a total equals the sum of its parts is the aggregation constraint. Here it says that in every month, National = North + South + East + West.
A set of forecasts is coherent when it obeys the same rule: in every month, the four regional forecasts add up to the national forecast. So in a coherent plan, the regional lines and the national line can never disagree.
First we need the data. We simulate 72 months of revenue in dollars, from January 2019 to December 2024, for the four regions. Each region gets its own starting level, growth rate and seasonal peak month, and one demand shock is shared by all four regions.
simulate_region() builds one region's revenue as its level, times a growth trend, times a seasonal wave, times noise. The shared shock goes into all four regions, so they tend to rise and fall together. The result is stored as a tsibble, a data frame with a time index (month) and a key (region) that says which series each row belongs to.
Next, aggregate_key(region, revenue = sum(revenue)) adds the national series. It creates one new series, shown as <aggregated>, that is the sum of the four regions in each month.
There are now five series with 72 months each. In December 2023 the <aggregated> row is the national revenue, $1,836,400, and the four regions add up to exactly that.
Let's check that this holds in all 72 months. The block takes the largest absolute difference between the national series and the sum of the regions.
So the history obeys the aggregation constraint exactly. The forecasts, as we are about to see, do not have to.
Last, we split the time. The 60 months from 2019 to 2023 are the history the models are fitted on. The 12 months of 2024 are held back as the actuals, the revenue that was really recorded, and they are used only to score the plans once they are made.