Lesson 28 · Python For Time Series
Encoding Seasonality in Time Series Data Using Fourier Terms for Accurate Modeling
Welcome! In this lesson, we will learn how to use Fourier terms for handling seasonality in time series data. By the end, you will be able to create new…
- CoursePython For Time Series
- Lesson28 of 30
- Video12 min
- FormatJupyter notebook · 17 code cells
What you'll learn
Data
No separate download needed — the notebook creates or downloads everything it uses.
📓 Full notebook
Download .ipynb
Encoding Seasonality with Fourier Terms#
Welcome! In this lesson, we will learn how to use Fourier terms for handling seasonality in time series data.
By the end, you will be able to create new features based on sine and cosine waves to help models recognize repeating patterns.
Let us begin our journey into this useful skill for time series work.
What is Seasonality?#
Seasonality means a pattern that repeats at regular intervals, like higher ice cream sales in summer months, or holiday shopping surges.
Many time series, such as weather or sales, show seasonality.
We can help models understand these cycles by creating special input features.
import warnings; warnings.filterwarnings("ignore")
# Let us import the basics we will need
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# Data setup
url = "https://raw.githubusercontent.com/jbrownlee/Datasets/master/airline-passengers.csv"
df = pd.read_csv(url)
print(df.shape)
df.head()
# Convert 'Month' to datetime
df['Month'] = pd.to_datetime(df['Month'])
df = df.set_index('Month')
df.head()
# Plot the data
plt.figure(figsize=(10,4))
plt.plot(df.index, df['Passengers'])
plt.title("Monthly Airline Passengers")
plt.ylabel("Passengers")
plt.xlabel("Date")
plt.show()
Why Use Fourier Terms?#
Fourier terms turn repeating time patterns into smooth waves using sine and cosine functions.
Many models cannot use the date itself, but they understand numbers like sine and cosine.
With these, patterns like yearly or weekly cycles become easier for a computer to learn.
# Create time-step numbers for each row
df['t'] = np.arange(len(df))
df.head()
# Basic Fourier (one cycle per year)
period = 12 # 12 months in a year
df['sin1'] = np.sin(2 * np.pi * df['t'] / period)
df['cos1'] = np.cos(2 * np.pi * df['t'] / period)
df[['sin1','cos1']].head()
# Plot sine and cosine waves
plt.figure(figsize=(10,4))
plt.plot(df.index, df['sin1'], label='sin1')
plt.plot(df.index, df['cos1'], label='cos1')
plt.legend()
plt.title("First Order Fourier Terms")
plt.show()
# Higher-order Fourier terms: add more waves
order = 2
for k in range(2, order*2+1):
df[f'sin{k}'] = np.sin(2 * np.pi * k * df['t'] / period)
df[f'cos{k}'] = np.cos(2 * np.pi * k * df['t'] / period)
df[[f'sin{k}' for k in range(2, order*2+1)] + [f'cos{k}' for k in range(2, order*2+1)]].head()
# Combine and plot all Fourier terms up to chosen order
plt.figure(figsize=(10,6))
for k in range(1, order*2+1):
plt.plot(df.index, df[f'sin{k}'], label=f'sin{k}')
plt.plot(df.index, df[f'cos{k}'], label=f'cos{k}')
plt.legend(ncol=2)
plt.title("All Fourier Term Waves (Order 2)")
plt.show()
# Add Fourier terms to a model
from sklearn.linear_model import LinearRegression
X = df[[f'sin{k}' for k in range(1, order*2+1)] + [f'cos{k}' for k in range(1, order*2+1)]]
y = df['Passengers']
model = LinearRegression()
model.fit(X, y)
preds = model.predict(X)
plt.figure(figsize=(10,4))
plt.plot(df.index, y, label='Actual')
plt.plot(df.index, preds, label='Model', linestyle='--')
plt.legend()
plt.title("Passengers: Actual vs Fourier Model")
plt.show()
Real-World Example: Why Fourier?#
Sine and cosine can describe any repeating pattern, whether it is sales at Christmas or more flights in summer.
They help even simple models find and match cycles that would be hard with just a date.
These features are used in business forecasting, weather prediction, and more.
# What happens if you use only t (time) as input?
model2 = LinearRegression()
model2.fit(df[['t']], y)
preds2 = model2.predict(df[['t']])
plt.figure(figsize=(10,4))
plt.plot(df.index, y, label='Actual')
plt.plot(df.index, preds2, label='Time-only Model', linestyle='--')
plt.legend()
plt.title("Passengers: Actual vs Time-only Model")
plt.show()
# Practice! How would you add weekly patterns?
print("How many months are there in a year?")
months = input()
print("The period for yearly seasonality would be:", months)
# Challenge! Make your own fourier feature
feature = np.sin(2 * np.pi * df['t'] / 6)
plt.plot(df.index, feature)
plt.title("Custom Sine Wave: 6 Month Seasonality")
plt.show()
# Best practice: Test different orders and period values
for trial_period in [3, 6, 12]:
feature = np.sin(2 * np.pi * df['t'] / trial_period)
plt.plot(df.index, feature, label=f'period={trial_period}')
plt.legend()
plt.title("Comparing Different Fourier Periods")
plt.show()
# Tip: Use sklearn's FunctionTransformer for pipelines
from sklearn.preprocessing import FunctionTransformer
def make_fourier(X, period=12, order=2):
t = np.arange(len(X)).reshape(-1, 1)
feats = []
for k in range(1, order*2+1):
feats.append(np.sin(2 * np.pi * k * t / period))
feats.append(np.cos(2 * np.pi * k * t / period))
return np.concatenate(feats, axis=1)
# Example use with pipeline:
trans = FunctionTransformer(make_fourier, kw_args={'period':12, 'order':2})
fourier_feats = trans.fit_transform(df[['Passengers']])
fourier_feats.shape
# Troubleshooting: Watch for overfitting with high orders
order = 10
X_big = df[[f'sin{k}' for k in range(1, order*2+1)] + [f'cos{k}' for k in range(1, order*2+1)]]
model_big = LinearRegression()
model_big.fit(X_big, y)
preds_big = model_big.predict(X_big)
plt.figure(figsize=(10, 4))
plt.plot(df.index, y, label='Actual')
plt.plot(df.index, preds_big, label='High-order Fourier Model', linestyle='--')
plt.legend()
plt.title("Model with Many Fourier Features")
plt.show()
Recap: Fourier for Seasonality#
- Seasonality means repeating cycles like sales or temperature.
- Fourier terms give us wavy features using sine and cosine.
- Models use these waves to match peaks and valleys in real data.
You can use as many orders as your cycles need, but watch out for overfitting.
This skill works in forecasts for business, science, and beyond!
Now Practice & Subscribe!#
- Try adding Fourier features to your own time series dataset.
- Change period or order and see what cycles your data contains.
If this was helpful, subscribe to the channel and let us know what you built!
Thanks for learning with us!
Found this useful?
All lessons, notebooks and datasets here are free. If they helped you, a coffee keeps new lessons coming.



