Time Series Forecasting with Prophet, NeuralProphet, and LSTM
Table of Contents
Introduction
Time series forecasting is one of the most impactful applications of data science in industry. From predicting stock prices and energy consumption to forecasting product demand and server load, the ability to anticipate future values from historical patterns is invaluable.
This tutorial covers three powerful approaches to time series forecasting: Facebook Prophet for robust additive decomposition, NeuralProphet for neural network-enhanced forecasting with autoregression, and LSTM (Long Short-Term Memory) networks built in PyTorch for capturing complex sequential dependencies.
By the end of this tutorial, you will be able to build, evaluate, and compare production-grade forecasting models using all three frameworks.
Prerequisites
- Python 3.9+
- Basic understanding of statistics (mean, variance, correlation)
- Familiarity with pandas and matplotlib
Install the required packages:
pip install prophet neuralprophet torch pandas numpy matplotlib scikit-learn
Time Series Fundamentals
A time series is a sequence of data points indexed in time order. Before building any model, you must understand the key components that make up a time series signal.
Components of a Time Series
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
Generate a synthetic time series with known components
np.random.seed(42)
dates = pd.daterange(start="2020-01-01", periods=730, freq="D")
trend = np.linspace(50, 150, 730)
seasonality = 20 np.sin(2 np.pi np.arange(730) / 365.25)
noise = np.random.normal(0, 5, 730)
y = trend + seasonality + noise
df = pd.DataFrame({"ds": dates, "y": y})
fig, axes = plt.subplots(4, 1, figsize=(14, 10), sharex=True)
axes[0].plot(dates, y, color="steelblue")
axes[0].settitle("Observed Time Series")
axes[1].plot(dates, trend, color="darkorange")
axes[1].settitle("Trend Component")
axes[2].plot(dates, seasonality, color="green")
axes[2].settitle("Seasonal Component")
axes[3].plot(dates, noise, color="red", alpha=0.6)
axes[3].settitle("Noise / Residual")
plt.tightlayout()
plt.savefig("timeseriesdecomposition.png", dpi=150)
plt.show()
Stationarity
A stationary time series has constant statistical properties over time. Many forecasting methods assume or benefit from stationarity. Use the Augmented Dickey-Fuller (ADF) test to check:
from statsmodels.tsa.stattools import adfuller
result = adfuller(df["y"].values)
print(f"ADF Statistic: {result[0]:.4f}")
print(f"p-value: {result[1]:.4f}")
if result[1] < 0.05:
print("The series is stationary (reject null hypothesis).")
else:
print("The series is non-stationary. Consider differencing.")
Train-Test Split for Time Series
Never use random splitting for time series. Always split chronologically:
splitdate = "2021-07-01"
train = df[df["ds"] < split
date].copy()
test = df[df["ds"] >= splitdate].copy()
print(f"Training samples: {len(train)}")
print(f"Testing samples: {len(test)}")
Forecasting with Prophet
Facebook Prophet is designed for business forecasting. It decomposes a time series into trend, seasonality, and holidays using an additive (or multiplicative) model: y(t) = g(t) + s(t) + h(t) + e(t).