Demand forecasting : Double exponential smoothing
The drawback of simple exponential smoothing is that it can only see a level (the average value around which the demand varies over time) and is unable to identify and project a trend. Double exponential smoothing brings together "level" and "trend" to generate forecasts.
For a given period, "t" with demand, d, the "Level" and "Trend" can be expressed as:
$$ a_{t}, b_{t}$$
The "Level", which is a function of demand and forecast, can be calculated as:
$$ a_{t}=\alpha d_{t}+(1-\alpha)(a_{t-1}+b_{t-1})$$
and the "Trend", which is a function of the difference in levels as well as the previous trend, can be calculated as:
$$ b_{t}=\beta (a_{t}-a_{t-1}) + (1-\beta) b_{t-1}$$
Forecast = Level + Trend
$$f_{t+1}=a_{t}+b_{t}$$
for a generalised forecast, the expression can be written as:
$$f_{t+\lambda}=a_{t}+\lambda b_{t}$$
Now moving on to the implementation of the Double Exponential smoothing model.
The simplest way to initialise the model is to assign
$$ a_{0} = d_{0}$$
$$ b_{0} = d_{1}-d_{0}$$
def double_exp_smooth(d,alpha, beta):
f=np.full(len(d)+1,np.nan)
level=np.full(len(d)+1,np.nan)
trend=np.full(len(d)+1,np.nan)
d=np.append(d,[np.nan])
#Initialising forecast
level[0]=d[0]
trend[0]=d[1]-d[0]
#Creating t+1 forecast
for t in range (1,len(d)):
f[t]= level[t-1]+trend[t-1]
level[t]= alpha*d[t-1]+(1-alpha)*(level[t-1]+trend[t-1])
trend[t]= beta*(level[t]-level[t-1])+(1-beta)* trend[t-1]
# f[t+1]=level[t]+trend[t]
df=pd.DataFrame.from_dict({'Demand':d,'Forecast':f,'Level':level,'Trend':trend,'Error':d-f})
return df
# For my test, I have used a csv file with demand data for the last 50 periods.
# The contents were generated using the random() function in excel.
import pandas as pd
import numpy as np
df_read=pd.read_csv('Demand50.csv')
d=df_read.values
# Calling the Double exponential smoothing function
df_smooth= double_exp_smooth(d,0.4,0.4)
df_smooth.index.name ='Period'
df_smooth[['Demand','Forecast']].plot()
Comments
Post a Comment