Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Lesson 10 — Time Series for Business/Economics

(trend, forecasting baselines, and honest evaluation)


Time series mindset: time is not just another variable

Examples of time series data:

Unit of observation

Always ask:

What does one row represent?

Examples:

The unit of observation affects what kind of patterns we can analyze.


Describing time series: trend, seasonality, and noise

A useful conceptual decomposition is:

yt=trendt+seasonalityt+noisety_t = trend_t + seasonality_t + noise_t

Trend

Trend is the long-run movement of the series.

Examples:

Seasonality

Seasonality is a regular pattern that repeats over time.

Examples:

Noise

Noise is irregular movement.

Examples:


Forecasting as a benchmark game

Today we focus on two simple forecasting methods:

  1. Naïve forecast

  2. Moving average forecast


Baseline 1: naïve forecast

The naïve forecast says:

The forecast for the next period equals the actual value from the previous period.

In notation:

x^t=xt1\hat{x}_{t} = x_{t-1}

For example, if sales in Week 4 were 45, then the naïve forecast for Week 5 is 45.


Baseline 2: moving average forecast

A moving average forecast uses the average of recent observations.

For a 3-period moving average:

x^t=xt1+xt2+xt33\hat{x}_{t} = \dfrac{x_{t-1} + x_{t-2} + x_{t-3}}{3}

For example, the forecast for Week 5 uses the average of Weeks 2, 3, and 4.

A moving average may work well when the series fluctuates around a relatively stable level.

It may work less well when there is a strong trend or sudden structural break.


In-class Excel exercise: sales forecasting

We start with a small weekly sales dataset.

WeekSales
139
244
340
445
538
643
739

We will forecast sales for Weeks 5, 6, and 7 using:

  1. Naïve forecast

  2. MA(3), a 3-week moving average forecast


Forecasting Weeks 5–7 manually

Naïve forecast

The naïve forecast uses the previous week’s actual sales.

WeekActual SalesNaïve Forecast
53845
64338
73943

MA(3) forecast

The MA(3) forecast uses the average of the previous three actual values.

For Week 5:

x^5=(44+40+45)/3=43\hat{x}_5 = (44 + 40 + 45)/3 = 43

For Week 6:

x^6=(40+45+38)/3=41\hat{x}_6 = (40 + 45 + 38)/3 = 41

For Week 7:

x^7=(45+38+43)/3=42\hat{x}_7 = (45 + 38 + 43)/3 = 42

WeekActual SalesNaïve ForecastMA(3) Forecast
5384543
6433841
7394342

Forecast errors

Forecast error is:

errort=actualtforecastterror_t = actual_t - forecast_t

A positive error means the forecast was too low.

A negative error means the forecast was too high.

WeekActualNaïveNaïve ErrorMA(3)MA(3) Error
53845-743-5
643385412
73943-442-3

Forecast evaluation metrics

Mean Absolute Error

MAE is the average absolute forecast error.

MAE=average(actualforecast)MAE = average(|actual - forecast|)

It is easy to explain:

On average, the forecast misses by about ___ units.

Root Mean Squared Error

RMSE is the square root of the average squared forecast error.

RMSE=average((actualforecast)2)RMSE = \sqrt{average((actual - forecast)^2)}

RMSE penalizes large errors more heavily than MAE.


Excel task

In Excel, create columns:

  1. Week

  2. Sales

  3. Naive

  4. MA_3

  5. Naive_Error

  6. MA3_Error

  7. Naive_Abs_Error

  8. MA3_Abs_Error

  9. Naive_Squared_Error

  10. MA3_Squared_Error

Then calculate:


How to evaluate forecasts

Forecast evaluation should be done on observations that were not used to construct the forecast.

For this small exercise:

For larger datasets:


Visual communication for time series

Useful plots include:

  1. Line plot of actual values

  2. Actual vs forecast plot

  3. Forecast error plot

  4. Rolling average plot, if the series is longer

For today’s small dataset, the most useful chart is:

actual sales vs naïve forecast vs MA(3) forecast.


Mini-lab: Google Colab


Python workflow

Step 1 — Create the data

import pandas as pd
import matplotlib.pyplot as plt
import numpy as np

df = pd.DataFrame({
    "Week": [1, 2, 3, 4, 5, 6, 7],
    "Sales": [39, 44, 40, 45, 38, 43, 39]
})

df

Step 2 — Create forecasts

# Naive forecast: this week's forecast = last week's actual sales
df["Naive"] = df["Sales"].shift(1)

# MA(3): average of previous 3 actual sales
df["MA_3"] = df["Sales"].rolling(window=3).mean().shift(1)

df

Step 3 — Focus on Weeks 5–7

forecast_df = df[df["Week"].isin([5, 6, 7])].copy()

forecast_df

Expected result:

WeekSalesNaiveMA_3
53845.043.0
64338.041.0
73943.042.0

Plot actual sales and forecasts

plt.figure(figsize=(8, 5))

plt.plot(df["Week"], df["Sales"], marker="o", label="Actual Sales")
plt.plot(df["Week"], df["Naive"], marker="o", linestyle="--", label="Naive Forecast")
plt.plot(df["Week"], df["MA_3"], marker="o", linestyle="--", label="MA(3) Forecast")

plt.title("Actual Sales and Forecasts")
plt.xlabel("Week")
plt.ylabel("Sales")
plt.xticks(df["Week"])
plt.legend()
plt.show()

Calculate forecast errors

forecast_df["Naive_Error"] = forecast_df["Sales"] - forecast_df["Naive"]
forecast_df["MA3_Error"] = forecast_df["Sales"] - forecast_df["MA_3"]

forecast_df["Naive_Abs_Error"] = forecast_df["Naive_Error"].abs()
forecast_df["MA3_Abs_Error"] = forecast_df["MA3_Error"].abs()

forecast_df["Naive_Squared_Error"] = forecast_df["Naive_Error"] ** 2
forecast_df["MA3_Squared_Error"] = forecast_df["MA3_Error"] ** 2

forecast_df

Calculate MAE

naive_mae = forecast_df["Naive_Abs_Error"].mean()
ma3_mae = forecast_df["MA3_Abs_Error"].mean()

print("Naive MAE:", round(naive_mae, 3))
print("MA(3) MAE:", round(ma3_mae, 3))

Calculate RMSE

naive_rmse = np.sqrt(forecast_df["Naive_Squared_Error"].mean())
ma3_rmse = np.sqrt(forecast_df["MA3_Squared_Error"].mean())

print("Naive RMSE:", round(naive_rmse, 3))
print("MA(3) RMSE:", round(ma3_rmse, 3))

Create a metric comparison table

metrics = pd.DataFrame({
    "Method": ["Naive", "MA(3)"],
    "MAE": [naive_mae, ma3_mae],
    "RMSE": [naive_rmse, ma3_rmse]
})

metrics.round(3)

Interpreting the results

For this small example:

Therefore, MA(3) performs better for forecasting Weeks 5–7 in this toy dataset.


Forecast memo template

Write a short memo using this structure:

  1. Headline Which forecast performed better?

  2. Evidence Compare MAE and/or RMSE.

  3. Interpretation Why might this method work better for this series?

  4. Caveat What could make the forecast fail?

Example:

For Weeks 5–7, the MA(3) forecast performed better than the naïve forecast. Its MAE was lower, meaning that on average it missed actual sales by fewer units. This suggests that averaging recent weeks helped smooth short-run fluctuations. However, the dataset is very small, and the result may not hold if there is a sudden change in demand, promotion, holiday effect, or structural break.


AI check: responsible use for time series

Good prompt examples:

Write Python code to compute a naive forecast and MA(3) forecast for weekly sales.
Explain MAE and RMSE in plain language for a business audience.
Help me write a cautious forecast memo comparing two baseline methods.

Bad prompt example:

Guarantee which forecasting model will be best next month.

In-class checkpoints

  1. Enter the weekly sales data in Excel.

  2. Compute the naïve forecast for Weeks 5–7.

  3. Compute the MA(3) forecast for Weeks 5–7.

  4. Compute forecast errors.

  5. Compute MAE and RMSE.

  6. Reproduce the same calculation in Python.

  7. Plot actual sales and forecasts.

  8. Compare the two methods.

  9. Write a short forecast memo.


Submission after class

Submit either:

Your submission should include:

  1. The actual vs forecast plot.

  2. A metric comparison table with MAE and RMSE.

  3. A short forecast memo:

    • headline,

    • evidence,

    • caveat.

  4. A short AI-use note if AI tools were used.


Review questions

  1. Why does time ordering matter in forecasting?

  2. What is a naïve forecast?

  3. What is a moving average forecast?

  4. Why should forecast evaluation use data from the future relative to the training period?

  5. What is the difference between MAE and RMSE?

  6. Why might a simple baseline be useful even when advanced models are available?

  7. What is one event or change that could cause a forecast to fail?