1- Introduction to Time Series

Ogulcan Ertunc
Analytics Vidhya
Published in
8 min readApr 29, 2021
Photo by M. B. M. on Unsplash

If I explain the time series in the simplest way; Time series are used for predictions based on the current series, and they are also used in hypothesis tests.

Update: This article is part of a series in which I explored the time series. Check out the full series: Part 1, Part 2, Part 3.

Don’t explain to me, show the code

You can access the GitHub repo here.

Basic concepts in time series:

Photo by Stephen Dawson on Unsplash

Stationary: The statistical properties of the series do not change over time. If the mean, variance, and covariance of a time series remain constant over time, the series is said to be stationary.

Trend (general trend): It is the steady state that occurs after falling and rising periods of time series over a long period of time. Time series tend to rise or fall steadily in terms of the long term.

Seasonality: Refers to the change in time series according to the seasons. Some periods of the data used in terms of time series differ from other periods.

Cycle: Periodic changes in the economy not related to seasonal changes. For example, short-term expansion or contraction in the economy, independent of the general trend, describes the cyclical process.

Irregular component: Changes that are not definite like other elements and can be expressed with the term error.

Things to know to Understand the Nature of Time Series Models:

  1. Moving Average: The future value of a time series is the average of its k-number of previous values.
  2. Weighted Average: Similar to the moving average, it carries the main idea of giving more weight to recent observations.
  3. Smoothing Methods:

Single Exponential Smoothing (SES) : Used only in stationary series, no trend or seasonality. It predicts by exponential correction, weighing the effects of the past with the assumption that the future is more related to the recent past. Estimation is made by weighting the past true values and past predicted values exponentially. It is suitable for univariate time series without trend or seasonality.

Double exponential smoothing: Used in series with level and trend, there should be no seasonality. Makes an exponential correction taking into account the trend effect.
DES = Level (SES) + Trend
Basic approach is the same as SES but the trend is also considered in addition
It is suitable for trend and seasonal univariate time series.

Triple exponential smoothing: a.k.a. The Holt-Winters method is used in series with level, trend, and seasonality.
Level (SES) + Trend + Seasonality
Triple exponential smoothing is the most advanced smoothing method
This method dynamically estimates the effects of level, trend, and seasonality, and can be used in univariate series that include trend and/or seasonality.

After the time series are decomposed into all these constituent components, the time series y can be expressed as the Additively of the components, for a certain period of time by the Multiplicatively method.

0. Now with this information, let’s consider a simple data set:

In this project, I used the Global Land and Ocean-and-Land Temperatures (GlobalTemperatures.csv) dataset.

Our main dataset gives the average of monthly air temperatures according to states.

To get more detailed information about the data set, I looked at the general averages by country with a groupby operation.

y.rename(columns={"dt": "Date", "AverageTemperature": "Avg_Temp", "AverageTemperatureUncertainty": "confidence_interval_temp"}, inplace=True)y[['Country', "Avg_Temp"]].groupby(["Country"]).mean().sort_values("Avg_Temp")

Later, I obtained data from Florida in the data set. So I will focus on a smaller focus and do the operations in order. I wanted to start by looking at the graph for Florida first.

florida.head()
florida.tail(5)
florida["Date"] = pd.to_datetime(florida["Date"])
florida.set_index('Date', inplace = True)

plt.figure(figsize = (6,4))
sns.lineplot(x = 'Year', y = 'Avg_Temp', data = florida)
plt.show()

Later, I determined the part until the end of 1994 as educational data. I will keep the later months as test data. In this case, our test data has 225 months.

train = florida[:"1994-12-01"]
len(train)
test = florida["1995-01-01":]
len(test)

1. Prediction with Single Exponential Smoothing

It can be used in fixed series. First, I applied the Dickey-Fuller Test, as we know it is unavailable if there is trend and seasonality.

def is_stationary(y):
print('H0: Series Is Not Stationary')
print("H1: Series Is Stationary")
p_value = sm.tsa.stattools.adfuller(y)[1]
if p_value < 0.05:
print("Result is stationary",p_value)
else:
print("Series is not stationary", p_value)
is_stationary(florida)
ses_model = SimpleExpSmoothing(train).fit(smoothing_level = 0.5)
y_pred = ses_model.forecast(225)
train.plot(title="Single Exponential Smoothing")
test.plot()
y_pred.plot()
plt.show()
mean_absolute_error(test, y_pred)

The green line shown in the graph is the estimate of our model, while the orange line is the actual values. At this stage, we could not predict trend or seasonality.

These functions find parameters using the max log-likelihood method.

1.1 Optimizing Our SES Model

Now let’s create the grid and make it alpha less, optimize it with the boothforce method.

def optimize_ses(train,alphas, step=225):
for alpha in alphas:
ses_model = SimpleExpSmoothing(train).fit(smoothing_level=alpha)
y_pred = ses_model.forecast(step)
mae = mean_absolute_error(test, y_pred)
print("alpha", round(alpha,2), "mae:", round(mae,4))
alphas = np.arange(0.01, 1,0.01)
optimize_ses(train, alphas)
### Final Ses Model ###
ses_model = SimpleExpSmoothing(train).fit(smoothing_level=0.14)
y_pred = ses_model.forecast(225)
train["1985":].plot(title='Single Exponential Smoothing')
test.plot()
y_pred.plot()
plt.show()
mean_absolute_error(test, y_pred)

We cannot accept this model because we cannot catch the trend and seasonality. Although we reduced our MAE value, our model was not as successful as we wanted. So we move on to the next stage.

2. Forecasting with Double Exponential Smoothing

# DES = Level + Trend
des_model = ExponentialSmoothing(train, trend="add").fit(smoothing_level=0.5,
smoothing_slope=0.5)
y_pred = des_model.forecast(225)
train["1985":].plot(title="Double Exponential Smoothing")
test.plot()
y_pred.plot()
plt.show()

We caught the trend, but we could not predict how long the trend will last and the trend has always continued. That’s why our MAE value turned out to be quite high. As you can see in the graph, the green line continued by decreasing in all 225 steps.

2.1 Optimizing Our DES model

alphas = np.arange(0.01, 1, 0.05)
betas = np.arange(0.01, 1, 0.05)

optimize_des(train, alphas, betas)

def optimize_des(train, alphas, betas, step=225):
print("Optimizing parameters...")
results = []
for alpha in alphas:
for beta in betas:
des_model = ExponentialSmoothing(train, trend="add").fit(smoothing_level=alpha,
smoothing_slope=beta)
y_pred = des_model.forecast(step)
mae = mean_absolute_error(test, y_pred)
results.append([round(alpha, 2), round(beta, 2), round(mae, 6)])
results = pd.DataFrame(results, columns=["alpha", "beta", "mae"]).sort_values("mae")
print(results)

optimize_des(train, alphas, betas)

We add alpha(smoothing level) and beta (smoothing slope) values, which give the lowest MAE value in optimization, as parameters to our model.

final_des_model = ExponentialSmoothing(train, trend="add").fit(smoothing_level=0.06,
smoothing_slope=0.01)
y_pred = final_des_model.forecast(225)
train["1985":].plot(title="Double Exponential Smoothing")
test.plot()
y_pred.plot()
plt.show()

Even though we reduced our MAE value a lot, our model was still not as successful as we wanted. So we move on to the next step, the Holt-Winters method.

3. Forecasting with Triple Exponential Smoothing (HOLT WINTERS)

First of all, we set up our model by assigning all values as 0.5 as the base model.

tes_model = ExponentialSmoothing(train,
trend='add',
seasonal="add",
seasonal_periods=12).fit(smoothing_level=0.5,
smoothing_slope=0.5,
smoothing_seasonal=0.5)
y_pred = tes_model.forecast(225)
train["1985":].plot(title = "Triple Exponential Smoothing")
test.plot()
y_pred.plot()
plt.show()

As can be seen, our model was so unsuccessful that our MAE value was higher than ever. Now we will optimize this model to achieve a better result.

3.1 Optimizing out Holt-Winters Model

import itertools
alphas = betas = gammas = np.arange(0.01, 1, 0.05)
abg = list(itertools.product(alphas, betas, gammas))
abg[0][2]

def optimize_tes(train, abg, step=225):
print("Optimizing parameters...")
results = []
for comb in abg:
tes_model = ExponentialSmoothing(train, trend="add",
seasonal="add",
seasonal_periods=12).\
fit(smoothing_level=comb[0],
smoothing_slope=comb[1],
smoothing_seasonal=comb[2])

y_pred = tes_model.forecast(step)
mae = mean_absolute_error(test, y_pred)

print([round(comb[0], 2), round(comb[1], 2), round(comb[2], 2), round(mae, 2)])

results.append([round(comb[0], 2), round(comb[1], 2), round(comb[2], 2), round(mae, 2)])
results = pd.DataFrame(results, columns=["alpha", "beta", "gamma", "mae"]).sort_values("mae")
print(results)

alphas = betas = gammas = np.arange(0.01, 1, 0.05)
abg = list(itertools.product(alphas, betas, gammas))

optimize_tes(train, abg)

As a result of optimization, we enter our best alpha, beta, and gamma values as parameters in our model.

# Final TES Model
#################################
final_tes_model = ExponentialSmoothing(train, trend="add", seasonal="add", seasonal_periods=12).\
fit(smoothing_level=0.06, smoothing_slope=0.06, smoothing_seasonal=0.06)
y_pred = final_tes_model.forecast(225)
train["1985":].plot(title="Triple Exponential Smoothing")
test.plot()
y_pred.plot()
plt.show()

As can be seen, our MAE value has reached its lowest value yet.

Conclusion

If we look at our final model, it is very important to establish a TES (HOLT Winters) model in a variable but seasonal data such as weather. The seasonality is relevant to the past, the trend is relevant to the past, and the level is equally relevant to the past, indicating that the seasons and temperatures proceed in a similar pattern for us.

Next steps:

A few days after this article, I will discuss the AR model, MA (q), ARMA, ARIMA, SARIMA models over the same data set as Econometric and Statistical Models in Time Series, Part 2.

References

[1] https://www.veribilimiokulu.com

[2] https://www.itl.nist.gov/div898/handbook/pmc/section4/pmc4.htm

[3] https://www.statisticssolutions.com/time-series-analysis/

--

--

Ogulcan Ertunc
Analytics Vidhya

I’m an IT Consultant,graduated Data Analytics. I’m a Data Enthusiast 💻 😃 passionate about learning and working with new tech. https://github.com/ogulcanertunc