Code for Simple Exponential Smoothing and Weighted Moving Average.
df = simulate_data.pandas_time_series()
ts = df['time_series'].to_numpy()
for a in (0.2, 0.4):
df[f'ss_{a}'] = __single(ts=ts, alpha=a)
fig = df.plot(
backend='plotly',
title=f'Single Smoothing',
)
fig.update_layout(template="plotly_dark",)
df = simulate_data.pandas_time_series()
ts = df['time_series'].to_numpy()
for a, b in ((0.25, 0.25), (0.6, 0.6)):
df[f'ds_{a}_{b}'] = __double(
ts=ts,
alpha=a,
beta=b,
)
fig = df.plot(
backend='plotly',
title=f'Double Smoothing',
)
fig.update_layout(template="plotly_dark",)
num_points = 35
m = 1
l = 4
interval = np.linspace(
0,
l * np.pi,
num=num_points + m,
)
level = 3
season = (30 / 1) * np.sin(interval[:-m])
trend = np.vectorize(lambda x: (3 / 1) * x)(interval[:-m])
noise = (4 / 1) * np.random.random((num_points,))
d = level + season + trend + noise
alpha1, alpha2 = 0.5, 0.5
beta1, beta2 = 0.15, 0.2
gamma1 = 0.15
time_series = np.append(d, [np.nan for _ in range(m)])
holtwinters1 = holt_winters(
ts=d,
l=l,
alpha=alpha1,
beta=beta1,
gamma=gamma1,
m=m,
)
df = pd.DataFrame(
{
'time_series': time_series,
f'a_{alpha1}\n b_{beta1}\n g_{gamma1}': holtwinters1,
# f'alph_{alpha2}_bet_{beta2}': smoothing2,
},
index=interval,
)
df.index = interval
fig = df.plot(backend='plotly', title=f'Forecast m={m} time-steps ahead')
fig.update_layout(template="plotly_dark",)
_, fig = SINGLE(.2, .6)
fig.show()
df = pd.read_csv(
'../data/Electric_Production.csv',
index_col='DATE',
parse_dates=['DATE'],
)
ts_col = 'Electric Production'
df.columns = [ts_col]
_, fig = SINGLE(
.25,
.65,
df=df,
ts_col=ts_col,
)
fig.update_layout(
autosize=False,
width=1100,
height=450,
)
fig.update_traces(line=dict(width=0.8))
fig.show()
_, fig = DOUBLE(
[.25, .5],
[.6, .7],
)
fig.show()
df = pd.read_csv(
'../data/Electric_Production.csv',
index_col='DATE',
parse_dates=['DATE'],
)
ts_col = 'Electric Production'
df.columns = [ts_col]
_, fig = DOUBLE(
[.25, .5],
[.4, .6],
df=df,
ts_col=ts_col,
)
fig.update_layout(
autosize=False,
width=1100,
height=450,
)
fig.update_traces(line=dict(width=0.8))
fig.show()
smoothing_level = 0.15
smoothing_trend = 0.15
own_col = 'home_made_holt'
dff = pd.read_csv(
'../data/Electric_Production.csv',
index_col='DATE',
parse_dates=['DATE'],
)
#dff = dff.resample('D').mean()
dff.index = pd.date_range('2020-01-01', periods=len(dff), freq='D')
ts_col = 'Electric Production'
dff.columns = [ts_col]
dff, _ = DOUBLE(
[smoothing_level, smoothing_trend],
df=dff,
ts_col=ts_col,
)
dff.columns = [ts_col, own_col]
stats_holt = Holt(
dff[[ts_col]],
initialization_method="estimated",
).fit(
smoothing_level=smoothing_level,
smoothing_trend=smoothing_trend,
optimized=False,
)
sm_holt = 'sm_holt'
dff[sm_holt] = stats_holt.fittedvalues
dff['sm_level'] = stats_holt.level
dff['sm_trend'] = stats_holt.trend
dff['delta'] = dff[sm_holt] - dff[own_col]
assert all(dff.delta[55:] < 10**(-5))
fig = dff[['delta']].plot(backend='plotly',)
fig.update_layout(template="plotly_dark",)
fig.show()
fig = dff[[ts_col, own_col, sm_holt]].plot(backend='plotly',)
fig.update_layout(template="plotly_dark",)
fig.show()
datafile = '../data/superstore_sales.csv'
dff = pd.read_csv(
datafile,
index_col='Order Date',
dtype={
'Row ID': str,
'Order ID': str,
},
parse_dates=['Order Date', 'Ship Date'],
)
dff.columns = ['_'.join(x.lower().split(' ')) for x in dff.columns]
region = 'Atlantic'
product_category = 'Furniture'
customer_segment = 'Consumer'
query = ' and '.join([
f"region=='{region}'",
f"product_category=='{product_category}'",
f"customer_segment=='{customer_segment}'",
])
dff = dff.query(query)
dff = dff.resample('2W').sum()
ts_col = 'sales'
dff = dff[[ts_col]]
#dff.index = pd.date_range('2020-01-01', periods=len(dff), freq='D')
smoothing_level = 0.5
smoothing_trend = 0.5
own_col = 'home_made_holt'
dff, _ = DOUBLE(
[smoothing_level, smoothing_trend],
df=dff,
ts_col=ts_col,
)
dff.columns = [ts_col, own_col]
fig.update_layout(
autosize=False,
width=1100,
height=450,
)
stats_holt = Holt(dff[[ts_col]], initialization_method="estimated").fit(
smoothing_level=smoothing_level,
smoothing_trend=smoothing_trend,
optimized=False,
)
sm_holt = 'sm_holt'
dff[sm_holt] = stats_holt.fittedvalues
dff['sm_level'] = stats_holt.level
dff['sm_trend'] = stats_holt.trend
dff['delta'] = dff[sm_holt] - dff[own_col]
fig = dff[['delta']].plot(backend='plotly',)
fig.update_layout(template="plotly_dark",)
fig.show()