<jupyter_start><jupyter_text>Introduction To Exponential Smoothing Import packages and set up the notebook<jupyter_code>import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sktime.forecasting.exp_smoothing import ExponentialSmoothing as ets
from sktime.forecasting.ets import AutoETS

plt.rcParams['figure.figsize'] = [12, 8]
plt.rcParams['figure.dpi'] = 50
import warnings
warnings.filterwarnings('ignore')<jupyter_output><empty_output><jupyter_text>Load sample data (prepared earlier)<jupyter_code># Read in the data
df = pd.read_csv("../../data/intro_ets.csv")
# Examine the start of 
df.head()<jupyter_output><empty_output><jupyter_text>Simple Exponential Smoothing Formula for simple exponential smoothing... ![Screen%20Shot%202021-09-06%20at%2019.05.21.png](attachment:Screen%20Shot%202021-09-06%20at%2019.05.21.png) Lets now try out simple exponential smoothing on a time series<jupyter_code>plt.plot(df['t1'])
plt.xlabel("t")
plt.ylabel("y(t1)")
plt.title('Time Series #1')<jupyter_output><empty_output><jupyter_text>Train the model with arbitrary smoothing_level (alpha) parameter:<jupyter_code># Simple exponential smoothing
ets_model = ets(trend=None,
               damped=False,
               seasonal=None,
               smoothing_level = 0.2, # Single exponential smoothing (Alpha )
               smoothing_slope = None, # Double Exponential smoothing (Beta)
               smoothing_seasonal = None ) # Triple Exponential smoothing (Gamma)
# Extract the fits
def extract_fit(y, model_object):
    y_fit = [np.nan, np.nan]
    for i in range(3,len(y)):  
        model_object.fit(y.iloc[:i])
        yh = model_object.predict(fh=0)
        y_fit.append(yh.to_numpy()[0])
    
    return np.array(y_fit)<jupyter_output><empty_output><jupyter_text>The plot below shows the original time series and the backfit exponential smoothing values. Adjusting the alpha parameter controls the smoothness. Values of alpha near 1 put larger weights on more recent values. Values of alpha near 0 put larger weights on older values and hence we get a smoother fit.<jupyter_code>y_fit = extract_fit(df['t1'], ets_model)
ets_model.fit(df['t1'])
y_h = ets_model.predict(fh=np.arange(0,20))

plt.plot(df['t1'])
plt.plot(y_fit)
plt.xlabel("t")
plt.ylabel("y(t)1")
plt.show()<jupyter_output><empty_output><jupyter_text>Now lets look at the forecast:<jupyter_code># Forecast
plt.plot(df['t1'])
plt.plot(y_h)
plt.xlabel("t")
plt.ylabel("y(t)1")
plt.show()<jupyter_output><empty_output><jupyter_text>What happens when we try it on a a series with a trend?<jupyter_code>plt.plot(df['t2'])
plt.xlabel("t")
plt.ylabel("y(t)2")
plt.title('Time Series #2')
y_fit = extract_fit(df['t2'], ets_model)
ets_model.fit(df['t2'])
y_h = ets_model.predict(fh=np.arange(0,20))

plt.plot(df['t2'])
plt.plot(y_h)
plt.xlabel("t")
plt.ylabel("y(t)2")
plt.show()<jupyter_output><empty_output><jupyter_text>Double Exponential Smoothing ![Screen%20Shot%202021-09-06%20at%2019.04.35.png](attachment:Screen%20Shot%202021-09-06%20at%2019.04.35.png)<jupyter_code># Simple exponential smoothing
ets_model = ets(trend="additive",
               damped=False,
               seasonal=None,
               smoothing_level = 0.5, # Single exponential smoothing (Alpha )
               smoothing_slope = 0.5, # Double Exponential smoothing (Beta)
               smoothing_seasonal = None ) # Triple Exponential smoothing (Gamma)
y_fit = extract_fit(df['t2'], ets_model)
ets_model.fit(df['t2'])
y_h = ets_model.predict(fh=np.arange(0,20))

plt.plot(df['t2'])
plt.plot(y_h)
plt.xlabel("t")
plt.ylabel("y(t)2")
plt.show()<jupyter_output><empty_output><jupyter_text>Ok, that works on simple series, but what if we want to exploit a known seasonal pattern?<jupyter_code>plt.plot(df['t3'])
plt.xlabel("t")
plt.ylabel("y(t3)")
plt.title('Time Series #3')<jupyter_output><empty_output><jupyter_text>Triple Exponential Smoothing  Add in a another formula to account for periodic cycles!  Triple Exponential Smoothing (Additive)![Screen%20Shot%202021-09-07%20at%2015.01.51.png](attachment:Screen%20Shot%202021-09-07%20at%2015.01.51.png)<jupyter_code>ets_model = ets(trend="additive",
               damped=False,
               seasonal="additive",
              sp = 20,
               smoothing_level = 0.4, # Single exponential smoothing (Alpha )
               smoothing_slope = 0.3, # Double Exponential smoothing (Beta)
               smoothing_seasonal = 0.2 ) # Triple Exponential smoothing (Gamma)
ets_model.fit(df['t3'])
y_h = ets_model.predict(fh=np.arange(0,20))

plt.plot(df['t3'])
plt.plot(y_h)
plt.xlabel("t")
plt.ylabel("y(t)3")
plt.title("Forecast using Triple Exponential Smoothing")
plt.show()<jupyter_output><empty_output><jupyter_text>Exponential Growth<jupyter_code>plt.plot(df['t4'])
plt.xlabel("t")
plt.ylabel("y(t4)")
plt.title('Time Series #4')
# Simple exponential smoothing
ets_model = ets(trend="multiplicative",
               damped=False,
               seasonal=None,
               smoothing_level = 0.6, # Single exponential smoothing (Alpha )
               smoothing_slope = 0.7, # Double Exponential smoothing (Beta)
               smoothing_seasonal = None ) # Triple Exponential smoothing (Gamma)


                
ets_model.fit(df['t4'])
y_h = ets_model.predict(fh=np.arange(0,20))

plt.plot(df['t4'])
plt.plot(y_h)
plt.xlabel("t")
plt.ylabel("y(t)4")
plt.title("Forecast using Triple Exponential Smoothing")
plt.show()<jupyter_output><empty_output><jupyter_text>Choosing alpha, beta, gamma with AutoETS https://www.sktime.org/en/v0.4.3/modules/auto_generated/sktime.forecasting.ets.AutoETS.html The SKTime package has compiled an AutoETS feature that will find the best parameters of alpha, beta and gamma via backfitting. Once you have chosen the appropriate model above, then this a great option to get a fast baseline.<jupyter_code>ets_model = AutoETS(trend="additive",
               damped=False,
               seasonal="additive",
               sp = 20 ) 
ets_model.fit(df['t3'])

y_h = ets_model.predict(fh=np.arange(0,20))

plt.plot(df['t3'])
plt.plot(y_h)
plt.xlabel("t")
plt.ylabel("y(t)3")
plt.title("Forecast using Triple Exponential Smoothing")
plt.show()<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.13449163449163448, 'fraction_numerical': 0.03507078507078507, 'mean_word_length': 4.651818181818181, 'pattern_counts': {'":': 0, '<': 49, '<?xml version=': 0, '>': 49, 'https://': 1, 'lorem ipsum': 0, 'www.': 1, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '12', 'dir': 'jupyter-structured-clean-dedup', 'id': '648642', 'license': 'MIT', 'n_tokens_mistral': 2455, 'n_tokens_neox': 2190, 'n_words': 448, 'path': 'python/intro_forecasting/intro_exponential_smoothing.ipynb', 'repo_name': 'datenzauberai/btsa', 'size': '6216'}