Time Series • Time Series Regression Model
Time Series / P5.04 Simple Multivariate Forecast

P5.04 Simple Multivariate Forecast

Practical 5 Time Series Regression Model

Fit a small VAR(1) to two related stationary teaching series, forecast both variables a few steps, and plot history against forecasts.

Practical / Solution

P5.04 Simple Multivariate Forecast

Problem Statement

Fit a small VAR(1) to two related stationary teaching series, forecast both variables a few steps, and plot history against forecasts.

Learning Outcomes

  • Fit a beginner VAR on aligned columns.
  • Forecast more than one series from the same model.
  • Evaluate with MAE on a hold-out window.

Theory

A vector autoregression (VAR) lets each variable depend on lags of itself and of the others. VAR(1) is a teaching starting point: one lag, two series. The series should be roughly stationary. VAR is one multivariate forecasting tool; it is not the only one, and large lag orders overfit short samples.

Dataset / Data Source

Constructed 90 observations of two related stationary series (demand-like and temperature-like). Teaching data.

Kaggle-style Workflow

  • Inspect bivariate series
  • Check they are not strongly wandering
  • Train/test split by time
  • Fit VAR(1)
  • Forecast both variables
  • MAE per variable
  • Plot

Analysis / Program

import numpy as np import pandas as pd import matplotlib.pyplot as plt from statsmodels.tsa.api import VAR rng = np.random.default_rng(4) n = 90 e1, e2 = rng.normal(size=n), rng.normal(size=n) x = np.zeros(n) y = np.zeros(n) for t in range(1, n): x[t] = 0.5 * x[t-1] + 0.2 * y[t-1] + e1[t] y[t] = 0.4 * y[t-1] + 0.1 * x[t-1] + e2[t] df = pd.DataFrame({"x": x, "y": y}) train, test = df.iloc[:-6], df.iloc[-6:] model = VAR(train).fit(maxlags=1, ic=None) print(model.summary()) fc = model.forecast(train.values[-1:], steps=6) fc = pd.DataFrame(fc, index=test.index, columns=["x", "y"]) print("Forecast:\n", fc.round(3)) print("MAE x:", round(np.mean(np.abs(test["x"] - fc["x"])), 3)) print("MAE y:", round(np.mean(np.abs(test["y"] - fc["y"])), 3)) fig, axes = plt.subplots(2, 1, figsize=(8, 6), sharex=True) for ax, col in zip(axes, ["x", "y"]): train[col].plot(ax=ax, label="train") test[col].plot(ax=ax, label="test") fc[col].plot(ax=ax, style="--", label="VAR forecast") ax.legend() ax.set_title(col) plt.tight_layout() plt.show()

Expected Output

A VAR summary, a 6-row forecast table for x and y, MAE for each column, and two panels of history vs forecast. Exact MAE depends on the random construction.

Result / Interpretation

Each forecast uses information from both series. If one variable helps the other, multivariate MAE can beat separate univariate naive forecasts, but students should compare rather than assume. Hold-out dates must remain later than the training dates.

Note

A small VAR is a joint forecast of several stationary series. Large lag orders need more data.