Notes

State Space Model

A lot of time series data has two layers: what’s really happening (often messy and partly hidden) and what you actually measure (noisy and imperfect). A State Space Model is a clean way to describe both layers at once.

What it is
A State Space Model represents a time series using an unobserved (latent) state that evolves over time, plus an observation process that turns that state into the data you see. It’s usually written as two equations:

  • State (transition) equation: how the hidden state changes from time t-1 to t (often with process noise).
  • Observation (measurement) equation: how the observed value at time t is generated from the state (often with measurement noise).

Intuition
Think of tracking a car in fog. The car’s true position and velocity are the state; your blurry GPS readings are the observations. The model separates “how the world moves” from “how your sensor lies,” which makes estimation much more stable.

Practical examples

  • House prices: state = underlying market trend; observations = monthly average prices distorted by sampling noise.
  • Medical monitoring: state = patient’s true physiological level; observations = noisy device readings.
  • Sales: state = baseline demand + seasonality; observations = daily sales with random shocks and reporting errors.

Why it matters in AI/ML
State space models power filtering (real-time estimation), smoothing (retrospective denoising), and forecasting. They’re central to the Kalman filter (linear-Gaussian case) and extend to non-linear/non-Gaussian settings via particle filters and related methods—useful in robotics, finance, and any ML pipeline where you need principled uncertainty over time.

State Space Model

A State Space Model represents a time series using latent (unobserved) states that evolve over time and generate noisy observations, typically via a transition equation and an observation equation. It is important in AI/ML for filtering, forecasting, and handling missing or irregular data within probabilistic sequential models. Example: tracking an object’s true position (state) from noisy sensor readings using a Kalman filter.

State Space Model

Imagine tracking a car on a foggy road. You can’t see the car perfectly, but you get noisy hints from a GPS. A state space model works like that: it assumes there’s a hidden “true situation” (the state, like the car’s real position and speed) that changes over time, and you only observe imperfect measurements (the observations, like the GPS readings). In time series and AI, this helps model systems that evolve step by step—such as weather, stock prices, or sensor data—by separating what’s happening underneath from what you can actually measure.

Python
import numpy as np  # numerical arrays and random number generation
import pandas as pd  # time-indexed data handling
import statsmodels.api as sm  # state space / Kalman filter implementations

# --- Create a realistic monthly demand series with trend + seasonality + noise ---
rng = np.random.default_rng(7)  # reproducible randomness
n = 120  # 10 years of monthly data
dates = pd.date_range("2015-01-01", periods=n, freq="MS")  # month-start timestamps
t = np.arange(n)  # time index for deterministic components

trend = 100 + 0.4 * t  # slowly increasing baseline demand
seasonal = 8 * np.sin(2 * np.pi * t / 12)  # yearly seasonality (monthly data)
y = trend + seasonal + rng.normal(0, 4, size=n)  # observed demand with observation noise
y = pd.Series(y, index=dates, name="demand")  # keep as a labeled time series

# --- Fit a state space model: local linear trend + seasonal component ---
# *** KEY LINE ***
mod = sm.tsa.UnobservedComponents(y, level="local linear trend", seasonal=12)  # state space specification
res = mod.fit(disp=False)  # estimate variances via maximum likelihood (Kalman filter under the hood)

# --- Extract latent states (smoothed) and generate forecasts ---
states = res.level.smoothed  # smoothed estimate of the latent level state
slope = res.trend.smoothed  # smoothed estimate of the latent slope state
fcst = res.get_forecast(steps=12)  # 12-month ahead forecast from the fitted state space model

# --- Package key outputs for inspection / downstream ML features ---
out = pd.DataFrame(
    {"y": y, "level_state": states, "slope_state": slope},
    index=y.index
)
print(out.tail(3))  # last few in-sample points with inferred states
print(fcst.summary_frame().head(3))  # forecast mean and intervals for first few future months
Code Notes
  • The core state space setup is done by statsmodels.tsa.UnobservedComponents; the fitted result provides latent (unobserved) states like level and slope that can be used as denoised features.
  • fit estimates noise variances; if the model is misspecified (e.g., wrong seasonal period), forecasts and inferred states can look plausible but be systematically biased.
  • get_forecast returns both point forecasts and uncertainty intervals; in ML workflows, the state estimates often feed into feature engineering (e.g., “current level” / “current slope”).
R
library(stats)      # time-series basics and Kalman infrastructure
library(forecast)   # practical state space models (ETS) and forecasting

# --- Create a realistic monthly demand series with trend + seasonality + noise ---
set.seed(7)  # reproducible randomness
n <- 120  # 10 years of monthly data
t <- 0:(n - 1)  # time index for deterministic components

trend <- 100 + 0.4 * t  # slowly increasing baseline demand
seasonal <- 8 * sin(2 * pi * t / 12)  # yearly seasonality (monthly data)
y <- trend + seasonal + rnorm(n, mean = 0, sd = 4)  # observed demand with observation noise
y_ts <- ts(y, start = c(2015, 1), frequency = 12)  # encode monthly time series structure

# --- Fit a state space model via exponential smoothing (ETS is a state space formulation) ---
# *** KEY LINE ***
fit <- ets(y_ts, model = "AAA")  # additive error, additive trend, additive seasonality (state space)

# --- Extract fitted values and states, then forecast ahead ---
fitted_y <- fitted(fit)  # one-step-ahead fitted values (in-sample)
states <- fit$states  # filtered state estimates (level, trend, seasonal)
fc <- forecast(fit, h = 12)  # 12-month ahead forecast with prediction intervals

# --- Inspect key outputs for downstream use (features / monitoring) ---
print(tail(cbind(y = y_ts, fitted = fitted_y), 3))  # compare observed vs fitted at the end
print(head(states, 3))  # first few rows of state estimates
print(head(fc$mean, 3))  # first few forecasted means
Code Notes
  • The state space model is fit with forecast::ets; model = "AAA" enforces additive error/trend/seasonality, which is appropriate when seasonal amplitude is roughly constant.
  • fit$states contains the inferred components (level/trend/seasonal); these are commonly exported as features for supervised models (e.g., demand forecasting with external regressors).
  • A common mistake is using an additive seasonal model when seasonality scales with the level; in that case, consider multiplicative seasonality (e.g., ETS with “M” components).