Time-Series Forecasting (ARIMA & Prophet)
Reviewed & published by Brayan K
Predict the future from the past. Learn to spot trend and seasonality, make a series stationary, and use ARIMA, SARIMA, and Prophet — without ever shuffling your data.
Part of the free AI & Machine Learning course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
What You'll Learn in This Lesson
- Trend, seasonality, and what makes time data special
- What stationarity is and how differencing helps
- Reading ARIMA(p, d, q) and when to add seasonality
- What Prophet brings to business forecasting
- Splitting time data without shuffling
- Evaluating with MAE, RMSE, and MAPE
🎯 Real-World Analogy: Reading the Tide
A sailor reading the sea separates three things: the slow rise of the tide (the trend), the regular daily ebb and flow (the seasonality), and the random splash of individual waves (the noise). Predicting the water level means modelling each part.
Time-series forecasting does exactly this: pull apart trend, seasonality, and noise, model the predictable parts, and project them forward. And just like the sea, you can only learn from the past to predict the future — never the other way around.
1 Trend, Seasonality & Stationarity
Every time series mixes a few components. Trend is the long-term direction. Seasonality is a pattern that repeats over a fixed period (weekly, yearly). Noise is the random leftover.
Classic models assume the series is stationary — its mean and variance stay roughly constant over time. Most real series aren't, so we apply differencing (subtract the previous value) to strip out the trend and bring the series closer to stationary.
- Plot the series; identify trend and seasonality.
- Difference (and/or transform) to reach stationarity.
- Fit a model (ARIMA / SARIMA / Prophet).
- Evaluate on a held-out recent period — no shuffling.
2 Decomposing a Series
Let's pull a tiny series apart. A moving average smooths the seasonal wiggle to reveal the trend, and differencing strips the trend out so the seasonal pattern stands clear. Run it and watch.
# Decompose a tiny series into TREND + SEASONALITY by hand (plain Python).
# A moving average smooths out the seasonal wiggle to reveal the trend.
series = [10, 14, 12, 16, 14, 18, 16, 20] # rising trend + up/down season
# 1) TREND: a centered 2-point moving average smooths the noise.
def moving_average(data, window):
out = []
for i in range(len(data) - window + 1):
chunk = data[i:i + window]
out.append(round(sum(chunk) / window, 1))
return out
trend = moving_average(series, 2)
print("trend:", trend) # smoothed, steadily rising
# 2) DIFFERENCING removes the trend (subtract the previous value).
# A differenced series is closer to STATIONARY (stable mean).
diffs = [series[i] - series[i - 1] for i in range(1, len(series))]
print("differences:", diffs) # alternates +4 / -2 -> the season shows up
# Expected output:
# trend: [12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0]
# differences: [4, -2, 4, -2, 4, -2, 4]3 ARIMA, SARIMA & Prophet
ARIMA(p, d, q) is the classic statistical model. p is the autoregressive order (how many past values), d is the differencing order (how many times you difference to reach stationarity), and q is the moving-average order (how many past errors).
- SARIMA: ARIMA plus explicit seasonal terms — use it when the data repeats over a fixed period.
- Prophet (Meta): a robust, low-effort model that decomposes trend, multiple seasonalities, and holiday effects automatically and tolerates missing data — popular for business forecasting.
🌍 Worked Example: The Real Tools (statsmodels & Prophet)
Here's ARIMA via statsmodels and a Prophet forecast. Study it (it isn't runnable in the in-browser sandbox) and notice the train/test split is done by time order, never shuffled.
# WORKED EXAMPLE — what the real tools look like (statsmodels & Prophet).
# You don't run this here; study it so the library code feels familiar.
# ----- ARIMA with statsmodels -----
from statsmodels.tsa.arima.model import ARIMA
# IMPORTANT: split by TIME, never shuffle.
train, test = series[:-12], series[-12:] # last 12 points are the test set
model = ARIMA(train, order=(1, 1, 1)) # ARIMA(p=1, d=1, q=1)
fit = model.fit()
forecast = fit.forecast(steps=12) # predict the next 12 steps
# ----- Prophet (handles trend + seasonality + holidays) -----
from prophet import Prophet
# Prophet expects a dataframe with columns ds (date) and y (value).
m = Prophet(yearly_seasonality=True)
m.fit(df_train) # df_train has columns ds, y
future = m.make_future_dataframe(periods=12, freq="M")
prophet_forecast = m.predict(future)
# Evaluate with error metrics (MAE / RMSE / MAPE) on the TEST period.
# No output here — this is a structural reference.Prophet wants two columns named ds (date) and y (value); ARIMA takes the raw series and an order=(p, d, q) tuple.
4 Splitting & Evaluating Forecasts
The cardinal rule of time series: train on the past, test on the future. Never shuffle. Hold out the most recent slice and evaluate the forecast on it, mimicking real deployment.
Three metrics tell you how good a forecast is:
- MAE — average absolute error, in the original units.
- RMSE — like MAE but punishes large misses more.
- MAPE — error as a percentage of the actual value, easy to compare across scales.
🎯 Your Turn 1: First-Order Differencing
Fill in the blank so difference() subtracts the previous value at each step. The expected output is in the comments.
# 🎯 YOUR TURN — finish first-order differencing.
# Differencing removes trend: new[i] = series[i] - series[i-1].
series = [5, 8, 12, 17, 23]
def difference(data):
return [data[i] - data[___] for i in range(1, len(data))] # 👉 previous index is i-1
print(difference(series))
# ✅ Expected output:
# [3, 4, 5, 6]🎯 Your Turn 2: Compute MAE
Finish the MAE function by dividing the total error by the number of points. The expected output is in the comments.
# 🎯 YOUR TURN — compute MAE (mean absolute error) of a forecast.
# MAE = average of |actual - predicted| over all points.
actual = [10, 12, 14, 16]
predicted = [11, 11, 15, 16]
def mae(actual, predicted):
errors = [abs(a - p) for a, p in zip(actual, predicted)]
return sum(errors) / ___ # 👉 divide by the number of points (len(actual))
print(mae(actual, predicted))
# ✅ Expected output:
# 0.75🎯 Mini-Challenge: Time-Aware Split + RMSE
Split a series by time (no shuffling) and compute RMSE on the held-out period. Only a comment outline is provided.
# 🎯 MINI-CHALLENGE: time-aware train/test split + RMSE
# NEVER shuffle a time series. Train on the past, test on the most recent.
#
# 1. series = [10, 12, 14, 16, 18, 20]
# 2. Split: train = first 4 points, test = LAST 2 points (keep order!)
# 3. Pretend forecast for the test period is [17, 21]
# 4. Compute RMSE = sqrt(mean((actual - pred) ** 2)) over the test points
# 5. print() the train, test, and the RMSE rounded to 2
#
# ✅ Expected: train=[10,12,14,16], test=[18,20], RMSE = 1.0
# your code here5 Common Errors (And How to Fix Them)
These are the mistakes that quietly ruin time-series projects. Watch for them.
❌ Shuffling the data before splitting
A random split puts future points in the training set — the future leaks into the past.
train_test_split(series, shuffle=True) # ❌ leaks the future✅ Fix: split by time order:
train, test = series[:-12], series[-12:] # past -> future❌ Fitting ARIMA on a non-stationary series
Trend or changing variance breaks ARIMA's assumptions and the forecast drifts.
ARIMA(series, order=(1, 0, 1)) # ❌ d=0 but the series has a trend✅ Fix: difference (raise d) to reach stationarity:
ARIMA(series, order=(1, 1, 1)) # d=1 removes the trendA monthly series with a yearly cycle needs seasonal terms, or it forecasts a flat line through the peaks.
ARIMA(monthly, order=(1, 1, 1)) # ❌ misses the yearly season✅ Fix: use SARIMA (or Prophet) with a seasonal period:
SARIMAX(monthly, order=(1,1,1), seasonal_order=(1,1,1,12))📋 Quick Reference
| Concept | What It Is | Key Point |
|---|---|---|
| Trend | Long-term direction | Removed by differencing |
| Seasonality | Repeating cycle | Fixed period (e.g. yearly) |
| Stationarity | Stable mean and variance | ARIMA assumes it |
| ARIMA(p, d, q) | AR + differencing + MA | d = differencing order |
| SARIMA | Seasonal ARIMA | Adds seasonal terms |
| Prophet | Trend + seasonality + holidays | Robust, low-tuning |
| Train/test split | Past trains, future tests | Never shuffle |
| MAE / RMSE / MAPE | Error metrics | MAPE is a percentage |
🎉 Lesson Complete!
You can now separate trend and seasonality, make a series stationary with differencing, read ARIMA(p, d, q), reach for SARIMA or Prophet when needed, and evaluate forecasts with MAE, RMSE, and MAPE — without ever shuffling.
Practice quiz
What makes time-series data different from ordinary tabular data?
- It has no features
- The order of observations in time matters
- It cannot be forecast
- It is always categorical
Answer: The order of observations in time matters. Time-series observations are ordered in time, so each value depends on the past — order carries information you must respect.
What is the 'trend' component of a time series?
- The long-term upward or downward movement
- A repeating pattern
- Random noise
- A single outlier
Answer: The long-term upward or downward movement. Trend is the slow, long-term direction (rising or falling) once short-term fluctuations are smoothed out.
What is 'seasonality'?
- A long-term trend
- A pattern that repeats over a fixed period (e.g. yearly, weekly)
- Random walk
- Missing data
Answer: A pattern that repeats over a fixed period (e.g. yearly, weekly). Seasonality is a regular, repeating cycle at a fixed period — like higher retail sales every December.
A stationary time series is one whose statistical properties:
- Change wildly over time
- Are always zero
- Stay roughly constant over time (stable mean and variance)
- Depend on the season only
Answer: Stay roughly constant over time (stable mean and variance). Stationarity means the mean, variance, and autocorrelation don't change over time — a key assumption for ARIMA.
In ARIMA(p, d, q), what does the 'd' term represent?
- The number of seasons
- The number of differencing steps to make the series stationary
- The forecast horizon
- The learning rate
Answer: The number of differencing steps to make the series stationary. d is how many times you difference the series (subtract the previous value) to remove trend and reach stationarity.
What do the 'p' and 'q' terms in ARIMA stand for?
- Periods and quarters
- Autoregressive (past values) and moving-average (past errors) orders
- Predictions and queries
- Precision and quality
Answer: Autoregressive (past values) and moving-average (past errors) orders. p is the autoregressive order (how many past values), q is the moving-average order (how many past forecast errors).
What does SARIMA add over plain ARIMA?
- Nothing
- Explicit seasonal terms for repeating cycles
- Faster training only
- Support for images
Answer: Explicit seasonal terms for repeating cycles. SARIMA (Seasonal ARIMA) adds seasonal autoregressive, differencing, and moving-average terms to model periodic patterns.
What is a notable strength of Facebook's Prophet?
- It needs no data
- It handles trend, multiple seasonalities, and holidays with little tuning
- It only works on stationary data
- It ignores trend
Answer: It handles trend, multiple seasonalities, and holidays with little tuning. Prophet is designed to be easy: it decomposes trend, seasonality, and holiday effects and is robust to missing data.
How should you split time-series data into train and test sets?
- Shuffle randomly like normal data
- Keep time order: train on the past, test on the most recent period
- Use only the test set
- Split by feature value
Answer: Keep time order: train on the past, test on the most recent period. Never shuffle a time series — train on earlier data and test on later data, or you leak the future into training.
Which metric expresses forecast error as a percentage of the actual values?
- MAE
- RMSE
- R-squared
- MAPE
Answer: MAPE. MAPE (Mean Absolute Percentage Error) reports error as a percentage, making it easy to interpret across different scales.
Continue this course
- Previous: Gradient Boosting (XGBoost & LightGBM)
- Next: Anomaly Detection — Isolation Forest, One-Class SVM, LOF and statistical methods
- Quick reference: AI & Machine Learning cheat sheet
Frequently asked questions
What is time-series forecasting?
Time-series forecasting predicts future values of a sequence that is ordered in time — like daily sales, hourly temperature, or monthly traffic. The key difference from ordinary machine learning is that order matters: each value depends on what came before, so you cannot shuffle the data.
What are trend, seasonality, and stationarity?
Trend is the long-term direction (a series slowly rising or falling). Seasonality is a pattern that repeats over a fixed period, like higher ice-cream sales every summer. Stationarity means the series' statistical properties — its mean and variance — stay roughly constant over time. Classic models like ARIMA assume stationarity, which is why you often difference the data first.
What do the three numbers in ARIMA(p, d, q) mean?
ARIMA combines three ideas. p is the autoregressive order: how many past values feed the prediction. d is the differencing order: how many times you subtract the previous value to remove trend and make the series stationary. q is the moving-average order: how many past forecast errors are used. You tune these three integers to fit your series.
When should I use SARIMA or Prophet instead of ARIMA?
Use SARIMA when your data has clear seasonality — it adds seasonal versions of the p, d, and q terms. Use Prophet (from Facebook/Meta) when you want a robust, low-effort model that automatically handles trend, multiple seasonalities, and holiday effects, and copes well with missing data. ARIMA is the classic statistical baseline; Prophet is friendlier for business forecasting.
How do I split time-series data for training and testing?
Never shuffle it. Train on the earlier part of the series and test on the most recent part — exactly how you'd forecast in real life. Random shuffling would let future information leak into training and give you wildly optimistic, meaningless scores.
Which metrics should I use to evaluate a forecast?
MAE (mean absolute error) is the average size of the errors in the original units. RMSE (root mean squared error) is similar but punishes large errors more. MAPE (mean absolute percentage error) expresses the error as a percentage of the actual values, which makes it easy to compare across series of different scales.