Lesson 25 · Python For Time Series
Understanding Exponential Smoothing and Holt-Winters Forecasting Models in Python
In this lesson, you will learn to forecast time series data using easy and powerful methods. What is exponential smoothing? How do you handle seasonality…
- CoursePython For Time Series
- Lesson25 of 30
- Video12 min
- FormatJupyter notebook · 19 code cells
What you'll learn
Data
No separate download needed — the notebook creates or downloads everything it uses.
📓 Full notebook
Download .ipynb
Welcome to Exponential Smoothing and Holt-Winters in Python!#
In this lesson, you will learn to forecast time series data using easy and powerful methods.
- What is exponential smoothing?
- How do you handle seasonality and trend?
- How to use real-world datasets for forecasting?
Let us get started step by step.
import warnings
warnings.filterwarnings("ignore") # Silence any warnings for a clean start
# First, let us import the libraries we will use
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
print("Ready to go!")
What is Exponential Smoothing?#
Exponential smoothing is a method for predicting the next value in a series. It gives more weight to recent data points, so your forecasts respond to changes quickly.
This is very useful in real-life data, like sales, temperature, or demand over time.
# Data setup: Load a real sales dataset
url = "https://raw.githubusercontent.com/jbrownlee/Datasets/master/shampoo.csv"
data = pd.read_csv(url)
print("Rows, columns:", data.shape)
data.head()
# Let us see all column names
print(data.columns.tolist())
# Plot the sales data to understand its pattern
plt.figure(figsize=(8, 4))
plt.plot(data['Sales'], marker='o')
plt.title('Monthly Shampoo Sales')
plt.xlabel('Month')
plt.ylabel('Sales')
plt.grid(True)
plt.show()
Why smooth data?#
Raw sales data jumps up and down. Smoothing helps find the real pattern. Exponential smoothing is like "forgetting" old noise.
You can use it to prepare for holidays or busy times in business.
# Simple exponential smoothing: apply to sales data
from statsmodels.tsa.holtwinters import SimpleExpSmoothing
sales = data['Sales'].astype(float)
model = SimpleExpSmoothing(sales)
fit = model.fit(smoothing_level=0.4, optimized=False)
pred = fit.fittedvalues
plt.figure(figsize=(8,4))
plt.plot(sales, label='Original')
plt.plot(pred, label='Smoothed', color='red')
plt.legend()
plt.title('Simple Exponential Smoothing')
plt.show()
How does smoothing work?#
You just saw a smoother line. Exponential smoothing uses a "smoothing level".
A value near 1 follows recent data closely. A value near 0 is smoother. You can adjust this to suit noisy or calm data.
# Try a different smoothing level
fit2 = model.fit(smoothing_level=0.9, optimized=False)
pred2 = fit2.fittedvalues
plt.figure(figsize=(8,4))
plt.plot(sales, label='Original')
plt.plot(pred2, color='green', label='Level 0.9')
plt.plot(pred, color='red', label='Level 0.4')
plt.legend()
plt.title('Compare Smoothing Levels')
plt.show()
What about trend and seasonality?#
Simple smoothing is not enough if data grows over time or has repeating seasons. You might see sales increase every year, or every holiday month.
That is where Holt and Holt-Winters methods come in.
# Holt: Handles trends in data
from statsmodels.tsa.holtwinters import ExponentialSmoothing
holt_model = ExponentialSmoothing(sales, trend='add', seasonal=None)
holt_fit = holt_model.fit(optimized=True)
holt_pred = holt_fit.fittedvalues
plt.figure(figsize=(8,4))
plt.plot(sales, label='Original')
plt.plot(holt_pred, color='purple', label='Holt Trend')
plt.legend()
plt.title('Holt Method for Trend')
plt.show()
# Holt-Winters: handles both trend and seasonality
hw_model = ExponentialSmoothing(sales, trend='add', seasonal='add', seasonal_periods=12)
hw_fit = hw_model.fit(optimized=True)
hw_pred = hw_fit.fittedvalues
plt.figure(figsize=(8,4))
plt.plot(sales, label='Original')
plt.plot(hw_pred, color='orange', label='Holt-Winters')
plt.legend()
plt.title('Holt-Winters (Trend + Seasonality)')
plt.show()
Quick recap: Three layers of smoothing#
- Simple: Just smooths, ignores trend and cycles.
- Holt: Adds line-up or line-down trends.
- Holt-Winters: Adds cycles, like holidays or seasons.
You pick based on what your data looks like.
# Make a forecast for future months
future = hw_fit.forecast(6)
print('Next 6 months sales forecast:')
print(future)
# Plot prediction vs. real data for the last points
plt.figure(figsize=(8,4))
plt.plot(sales, label='Actual Sales')
plt.plot(hw_fit.fittedvalues, label='Fitted', color='orange')
plt.plot(range(len(sales), len(sales)+6), future, 'go--', label='Forecast')
plt.legend()
plt.title('Real vs. Fitted vs. Forecasted Sales')
plt.show()
# Safe access: What if there is missing data?
print(data.isnull().sum())
# Fill missing values with the previous month
data_filled = data.fillna(method='ffill')
print(data_filled.isnull().sum())
# Quick mini-project: Predict sales after user input
user_months = int(input('How many months to predict? (1-12): '))
my_forecast = hw_fit.forecast(user_months)
print('Here is your forecast:')
print(my_forecast)
# Troubleshooting: What if fitting fails?
try:
broken_model = ExponentialSmoothing([], trend='add', seasonal='add', seasonal_periods=12)
broken_fit = broken_model.fit()
except Exception as e:
print('Error:', e)
# Extra tip: You can save your fitted model
import pickle
with open('hw_model.pkl', 'wb') as f:
pickle.dump(hw_fit, f)
print('Model saved!')
# Challenge: Try your own smoothing level
level = float(input('Pick a smoothing level between 0 and 1: '))
user_fit = model.fit(smoothing_level=level, optimized=False)
print('Your smoothed values:')
print(user_fit.fittedvalues.head())
Recap: What have you learned?#
- How to smooth out sales data
- How to spot trend and seasonality
- Using Holt-Winters for forecasting
- Handling missing data
- Making predictions for real business planning
Practice with other datasets to get better!
Want more? Subscribe for new lessons!#
Try using exponential smoothing on other datasets. Share your charts in the comments below. Subscribe and turn on notifications for more tutorials!
Found this useful?
All lessons, notebooks and datasets here are free. If they helped you, a coffee keeps new lessons coming.



