The Kalman Filter (for time series)

We have a state-space model: a hidden state \alpha_t that evolves, seen only through noisy observations y_t. Now the central question: given the observations up to now, what is our best estimate of the hidden state — and how sure are we? And having answered it, how do we forecast the next observation, and how do we score how well the model fits so we can estimate its parameters?

Extraordinarily, all of this is delivered by a single, cheap, recursive procedure that never looks back over the whole history — it carries a running summary and updates it one observation at a time. That procedure is the Kalman filter. In a time-series course it is the workhorse behind three distinct jobs — filtering, smoothing and forecasting — and, crucially, it is the machine that computes the likelihood we maximise to fit ARMA and structural models. (For the same filter viewed as an optimal controller's state estimator, see the companion Kalman filter in control theory.)

A Gaussian belief, carried forward

Because the model is linear and every noise is Gaussian, the filter's belief about the state stays Gaussian for all time. So the entire belief is just two numbers (or in the vector case, a mean vector and a covariance matrix):

The filter marches through the data running a two-beat cycle at every time step: predict (project the belief forward through the dynamics) then update (pull it back toward the new observation). This is nothing more than Bayes' theorem applied over and over — recursive Bayesian updating for a linear-Gaussian model — where the prior at each step is last step's posterior pushed forward one tick.

The predict–update equations (scalar local level)

Let us write the recursion for the T = 1, Z = 1 local-level model — state variance Q = \sigma_\eta^2, measurement variance H = \sigma_\varepsilon^2. Write a_{t-1}, P_{t-1} for the filtered estimate after seeing y_{t-1}.

Predict — roll the state forward, and let uncertainty grow by the process noise:

a_{t\mid t-1} = a_{t-1}, \qquad P_{t\mid t-1} = P_{t-1} + \sigma_\eta^2.

Update — a new observation y_t arrives. Form the innovation (the one-step prediction error) and its variance:

v_t = y_t - a_{t\mid t-1}, \qquad F_t = P_{t\mid t-1} + \sigma_\varepsilon^2.

Then correct the estimate by a fraction of that surprise — the fraction being the Kalman gain K_t — and shrink the variance:

K_t = \frac{P_{t\mid t-1}}{F_t}, \qquad a_t = a_{t\mid t-1} + K_t\,v_t, \qquad P_t = (1 - K_t)\,P_{t\mid t-1}.

The gain K_t = P_{t\mid t-1}/(P_{t\mid t-1} + \sigma_\varepsilon^2) is a number between 0 and 1 that weighs confidence against confidence: a large state uncertainty or a small measurement noise pushes it toward 1 (trust the data, correct hard); a small state uncertainty or a noisy sensor pushes it toward 0 (trust the model, barely budge). The correction a_t = (1-K_t)\,a_{t\mid t-1} + K_t\, y_t is simply a weighted average of where the model thought it was and what the sensor just said.

Worked example: one predict–update cycle

Make it concrete. Local level with process variance \sigma_\eta^2 = 1 and measurement variance \sigma_\varepsilon^2 = 4. Suppose after yesterday we hold a_{t-1} = 10 with P_{t-1} = 3, and today's observation lands at y_t = 16.

Notice the estimate moved from 10 halfway toward the observation 16, landing at 13, and the uncertainty fell from a predicted 4 down to 2 — the observation taught us something. That is the whole filter in one breath, repeated for every time step.

Watching it lock on

Below, the true hidden state is the smooth line; we see it only through the scattered dots. The filtered estimate is the second line, and the shaded band is its \pm 2\sqrt{P_t} uncertainty. Watch the band at the left: the filter starts unsure (a wide band from a diffuse prior) and, observation by observation, the band narrows and the estimate settles onto the truth. After a few steps the gain and variance reach a steady state and the filter simply tracks.

This shrinking band is the visual signature of Bayesian learning: every observation removes a little uncertainty, until the incoming noise and the wandering state balance and the uncertainty holds steady.

The prize: the likelihood, for free

Here is why the filter is the beating heart of estimation. As it runs, it emits at every step an innovation v_t and its variance F_t. Under the model, these one-step prediction errors are independent and Gaussian, v_t \sim N(0, F_t). That independence is a gift: it lets us write the joint density of the whole series as a simple product, term by term — the prediction-error decomposition.

So the Kalman filter is not only an estimator of the hidden state — it is the engine that turns an intractable-looking joint density into a running sum you can hand to an optimiser. Every time you fit an ARIMA model, a filter like this is quietly running under the hood, decomposing the likelihood into these one-step surprises.

Filtering, smoothing, forecasting

The same recursion answers three different questions, distinguished only by which observations you condition on:

Three tasks — one algorithm, differing only in the direction you point it. This is the same trio of goals (forecasting among them) that motivated the whole subject, now delivered by a single recursion.

The recursion must be seeded: you have to supply an initial mean a_0 and variance P_0 before the first predict. For a stationary state you can start from the process's own stationary distribution. But for a non-stationary state — a random-walk level, a trend — there is no stationary distribution, and picking an arbitrary P_0 quietly biases the early estimates. The clean fix is a diffuse prior: let P_0 \to \infty to represent "we know nothing", handled by a special diffuse (exact-initial) Kalman filter in practice.

The second trap is the noise variances \sigma_\eta^2, \sigma_\varepsilon^2. The filter is only optimal if they are right. Feed it a measurement variance that is far too small and it will trust every noisy dot, jittering wildly; far too large and it will ignore real signal and lag badly. In practice you don't guess them — you estimate them by maximising the very prediction-error likelihood above. The filter and the fitting are two sides of one coin.

It feels like cheating: to condition on all past data you should surely need to keep it all. The magic is that for a Gaussian, linear model the pair (a_t, P_t) is a sufficient statistic — it packs everything the history has to say about the current state into two numbers. Tomorrow's belief depends on the past only through today's belief, a Markov property in the state. That is why the filter is recursive and runs in constant memory: yesterday's posterior is the summary of yesterday's world, and the new observation only ever meets that summary. This is the same structural fact that lets a spacecraft filter run forever on a tiny computer.