State-space models and the Kalman filter
Before this lesson: simple exponential smoothing (lesson 04), AR models and the backshift notation (lesson 05), forecast intervals and ARIMA(0,1,1) (lesson 06). From the probability-and-statistics track: the multivariate Gaussian and its conditional distribution, maximum likelihood, and Bayes' rule with a prior and a posterior. Covariance matrices are positive semidefinite (linear-algebra lesson 07). Time: about 110 minutes, plus the notebook.
Why this matters #
- One framework for many models. Local level, trend, seasonal, ARMA and regression models with
changing coefficients are all state-space models. One algorithm filters, forecasts and computes the
likelihood for all of them. statsmodels computes the exact likelihood of ARIMA and SARIMA models
with a Kalman filter (its
SARIMAXclass is a state-space model). - Missing data and irregular times need no special code: the filter skips the update when there is no observation.
- Tracking and navigation. The Kalman filter (Kalman, 1960) fuses GPS, inertial sensors and odometry in aircraft, phones and robots. It is the base of SLAM and of data assimilation in weather forecasting (ensemble Kalman filter, see the ml-for-science track).
- Deep learning. The layers of S4 and Mamba are linear state-space recurrences (deep-learning lesson 16). They use the state equation of this lesson without noise and learn and by gradient descent.
1. Predict first #
2. The picture #
A hidden state seen through noise #
A state-space model has a state that we do not observe and an observation that we do observe. The state carries everything about the past that matters for the future. The state moves by a linear rule plus noise; the observation is a linear function of the state plus noise:
The arrows are the only dependencies: depends on the past only through (a Markov chain), and depends only on . This is the same graph as a hidden Markov model; here the state is a continuous vector and everything is linear and Gaussian.
The example of the figure. A target moves along a line. Its state is . In each time step the position grows by the velocity, and a small random acceleration changes both. A sensor measures the position only, with noise of standard deviation 3. The velocity is never measured.
Press Step several times. Each press does one half of the cycle. After predict, the orange point and bar show the one-step prediction and its range: the range is wider than before. After update, the aqua point moves toward the new blue observation and the range shrinks. The yellow line is the current step; the dashed blue line is the true position. Then choose missing at t = 40 to 60 and press Run: the band grows in the grey gap and collapses at . Watch the lower chart: the velocity is never observed, but the filter estimates it. Use the Try buttons to give the filter a wrong or and compare the RMSE readouts. View: whole series shows all 100 steps.
The filter repeats two steps.
- Predict. Move the last estimate forward with the motion rule: new position = old position + velocity. The uncertainty grows, because the random acceleration adds the variance .
- Update. A new observation arrives. The difference between it and the predicted position is the innovation (the "surprise"). Move the estimate by a fraction of the innovation. The uncertainty shrinks, because we have one more measurement.
The fraction is the Kalman gain . It is not a tuning knob: the filter computes it from the two variances. With the true and , the filtered position has an RMSE well below the RMSE of the raw observations: the filter averages the noise away and still follows the turns of the target.
One update is Bayes' rule for two Gaussians #
Look at one update in one dimension. Before arrives, the prediction says : this is the prior. The sensor says with : as a function of , this is the likelihood. Bayes' rule multiplies the two. The product of two Gaussian densities in is again a Gaussian: the posterior.
Move the three sliders. The orange curve is the prior (the prediction, mean ), the dashed blue curve is the likelihood of the observation , and the aqua curve is the posterior. Make small: the posterior jumps to and . Make large: the posterior stays at the prior and . Notice that the posterior is always narrower than both other curves.
The posterior mean is a weighted average of the prediction and the observation. Each one gets a weight proportional to its precision (one over its variance). So the more precise source wins, and the combined estimate is more precise than either source.
In the scalar filter, the observation noise variance grows to infinity while the prediction variance stays finite. What does the update step do?
as . A sensor with infinite noise carries no information, so and . The gain goes to 1 in the opposite case, .
The prediction is . You observe with noise variance . What is the posterior?
, so the mean is and the variance is . The variance goes down, not up: two equally good sources halve the variance. The mean is in the middle because both sources have the same variance.
3. Definitions and main results #
3.1 The linear Gaussian state-space model #
Definition. A linear Gaussian state-space model for a series (each a vector of size ) has a hidden state (a vector of size ) and two equations:
The first line is the state equation (or transition equation); the second is the observation equation (or measurement equation).
- () is the transition matrix; () is the observation matrix.
- is the process noise (state noise) covariance; is the observation noise covariance. Both are positive semidefinite.
- Assumptions: the noises and are independent of each other, independent over time, and independent of the initial state .
, , and may depend on (then we write , and so on); every result below still holds. A known input can be added, ; this only shifts the predicted mean.
Examples. Each model below is one choice of the four matrices.
| Model | State | ||||
|---|---|---|---|---|---|
| local level (random walk plus noise) | level | ||||
| local linear trend | level and slope | ||||
| constant velocity (tracking) | (position, velocity) | ||||
| seasonal, period | |||||
| AR(2), companion form |
How to read the rows:
- Local level. is a random walk; adds measurement noise. This is the model behind SES (section 3.4).
- Local linear trend. and : the slope also moves slowly. This is the stochastic version of Holt's linear method (lesson 04).
- Constant velocity. The same . The random acceleration adds to the position and to the velocity, so and .
- Seasonal. The first row says : four consecutive seasonal values sum to zero, up to noise. To get "level + season", stack the level and the seasonal state into one vector, put in block-diagonal form and use .
- AR(2). The first row of is ; the second row copies down. The eigenvalues of are the inverses of the roots of (lesson 05), so the model is stationary exactly when they lie inside the unit circle. Every ARMA() model has such a form, with a state of size (Durbin and Koopman, ch. 3).
Switch between the models. Each model is only a different set of matrices , , , , and the same Kalman filter works for all of them. The chart shows one simulated sample: the blue observations, the aqua hidden level, and, for the seasonal model, the violet hidden seasonal part. Press New sample to see another path from the same model.
3.2 The scalar update, step by step #
Start with the local level model. All quantities are numbers. We write for the mean of given and for its variance.
Predict. Suppose . Then with independent , so
Update. Write and . Then:
- Prior times likelihood, as a function of : .
- The exponent is . Expand and keep the terms with : .
- A Gaussian has exponent . Compare the coefficients (this is "completing the square"):
- So the posterior variance is and the posterior mean is .
- Write . Then , and step 4 becomes
The first form says: a weighted average of prediction and observation. The second form says: the prediction plus the gain times the innovation . Step 3 says that precisions add: . So is smaller than both and .
3.3 The Kalman filter #
For the vector model the same two steps hold with matrices.
Which covariance is which. is the uncertainty of the state before we see (the prediction). is the uncertainty after we see it (the filtered estimate). is the uncertainty of the observation before we see it: state uncertainty mapped by , plus sensor noise. With and the box is exactly section 3.2.
Theorem (the Kalman filter is exact). Under the assumptions of section 3.1, and for every , and .
Proof by Gaussian conditioning
We use one fact about jointly Gaussian vectors : the conditional distribution of given is Gaussian with mean and covariance (the multivariate Gaussian lesson of the probability-and-statistics track). The proof is by induction over .
- Start. by assumption.
- Predict. Assume . The noise is independent of and of . A linear map of a Gaussian plus an independent Gaussian is Gaussian, with mean and covariance .
- Joint of state and observation. Given , the pair with is jointly Gaussian ( is independent of everything else), with
The lower-right block is . This already proves the claim about . 4. Condition on . With and , the fact above gives the mean and the covariance . This is the update step, and the induction continues.
Two remarks. First, the covariances , , and the gain do not depend on the data : they can be computed before the data arrive. Second, without the Gaussian assumption (noises only uncorrelated, with the same means and covariances), the same recursion still gives the best linear estimate of in mean squared error.
Why the velocity changes when only the position is observed. In the constant-velocity model, , so is the first column of divided by . The second entry of that column is the covariance of position and velocity. The predict step makes it nonzero (a fast target moves far), so a surprise in the position also corrects the velocity. The worked example in section 4 shows this with numbers.
Numerical form and cost
The form can lose symmetry and positive semidefiniteness in floating point. The Joseph form is a sum of two positive semidefinite matrices, so it stays positive semidefinite, and it is correct for any gain , not only the optimal one. Square-root filters propagate a Cholesky factor of instead (linear-algebra lesson 07). Solve with (Cholesky) instead of forming . One step costs operations; this is why a state of size (a weather model) needs the ensemble methods of the ml-for-science track.
3.4 Steady state: the local level filter is exponential smoothing #
For the local level model the covariance recursion does not involve the data. Combine predict and update into one map for :
Theorem (steady-state gain). Let , and (the signal-to-noise ratio). For every start , converges to , and the gain converges to
Proof.
- Fixed point. means , that is . The only positive root is .
- Gain. Divide by : solves , so . The claim is equivalent to , which is . So .
- Convergence. and for every , so every , and the fixed point is too. The derivative is , so on it is at most . By the mean value theorem,
so the error shrinks geometrically.
The link to SES. With a constant gain , the update is
This is the SES recursion of lesson 04 with . The forecasts agree too: both are flat, . So SES is the steady-state Kalman filter of the local level model, and is decided by the signal-to-noise ratio :
| 0.01 | 0.1 | 0.5 | 1 | 10 | |
|---|---|---|---|---|---|
| 0.095 | 0.270 | 0.500 | 0.618 | 0.916 |
Small (the level moves little, the noise is large) gives a small : average over a long past. Large gives near 1: trust the last observation. As , ; as , .
Move and the start variance . The upper chart shows the gain (aqua): it starts near 1 when is large and settles at (dashed line) after a few steps. The lower chart runs the Kalman filter (aqua) and SES with (orange, dashed) on the same blue data, both started at 0. Notice that the two lines differ only at the start; the readout shows the gap going to 0. With small the start-up takes longer.
In a local level model the state noise and the observation noise have the same variance, . Which SES parameter gives the steady-state Kalman filter?
, so . The answer is not 0.5: the gain compares with the prediction variance , which is larger than because it also contains the uncertainty of the last estimate. is the weight on the old level.
SES intervals and ARIMA(0,1,1)
In steady state the innovations have constant variance and are white noise. From and we get : an ARIMA(0,1,1) with , as in lesson 06. The -step forecast variance of the state-space model is . It equals the ARIMA formula : both are for , and each extra step adds in one form and in the other. These are equal, because the fixed-point equation says .
3.5 Forecasting and missing data #
Forecasting. To forecast from origin , run the predict step times without updates:
so . The forecast of the observation is with covariance . Under the model, a 95 % prediction interval for a scalar is . For the local level model, : the variance grows linearly in , and the fan widens like . These intervals assume that are known; using estimated values makes them a little too narrow (lesson 10 checks the coverage of intervals).
Missing data. If is missing, skip the update: and . This is exact, because "no observation" means "condition on nothing new". For the local level model the variance grows by in each missing step. At the first observation after the gap, is large, so the gain is near 1 and the estimate jumps to the data. The likelihood (next section) simply has no term for a missing time. If only some entries of a vector are missing, keep the rows of and that belong to the observed entries.
Irregular time steps. If the time between observations is , use and for that step. For the local level model, a random walk observed after units has .
A local level model has and . The observations at times 31 to 35 are missing, and . What is ?
Without observations only the predict step runs, and for it adds : . belongs to the sensor; it enters only in an update. The uncertainty about the hidden level grows because the level keeps moving while nobody looks.
3.6 The likelihood: the prediction-error decomposition #
To estimate unknown parameters (for example and , or the of an AR model), we need the likelihood . The observations are dependent, so it is not a product of marginal densities. The chain rule of probability gives
and the theorem of section 3.3 says . So
This is the prediction-error decomposition: the filter turns dependent observations into innovations that are independent with known covariances . One pass of the filter gives the exact Gaussian log-likelihood in steps. Maximise it with a numerical optimiser; write variances as , so that they stay positive.
Checking the model. If the model is correct, the standardised innovations are independent . Check them like residuals: plot them, look at their ACF and run the Ljung–Box test (lesson 02).
The Nile example (Durbin and Koopman, ch. 2). The annual flow of the Nile at Aswan, 1871–1970, in , fitted with a local level model. Maximising the likelihood gives and , so and : the level moves slowly compared with the year-to-year noise. The maximum log-likelihood is (with the diffuse start of section 3.7).
Move , then press Go to the maximum. For each , the figure sets to its best value and shows the aqua level with its band over the blue data, and a 10-year orange forecast fan after the yellow origin (1970). The lower chart is the log-likelihood as a function of ; its maximum is at . Notice the drop of the level around 1899 (the first Aswan dam was built from 1898 to 1902). Switch to smoother: the band becomes narrower. Data: Durbin and Koopman (2012), via statsmodels.
3.7 Initialisation #
The filter needs and . Often we know nothing about the start. A diffuse prior uses a very large . For the local level model, is then huge, , and so and : the first estimate is the first observation, with the uncertainty of one observation. The first innovation has an almost infinite variance and carries no information, so the diffuse log-likelihood leaves out the first term.
In practice: (1) the exact diffuse start for the local level model is ,
, and the likelihood starts at (this lesson and Durbin and Koopman use it); or
(2) set to a very large number, for example for the Nile data, and leave out the first likelihood term (an approximate diffuse start). Different
starts change the estimates a little. For the Nile data, statsmodels 0.15 UnobservedComponents gives
, . The first filtered values have wide bands for the same reason:
early on, there is little data. For a stationary state (such as an AR part) use instead its
stationary distribution as the start.
3.8 Smoothing: using the whole series #
The filter estimates from . After the whole series is observed, we can estimate each from all of : this is smoothing. The Rauch–Tung–Striebel (RTS) smoother runs backward after the filter, for :
It starts at , where smoother and filter agree. In words: the smoother corrects the filtered estimate by what the future revealed about the prediction error at .
Smoothed variances are smaller. (in the order of positive semidefinite matrices): conditioning a Gaussian on more data never increases its covariance. On the Nile data, the smoothed variance in the middle of the series is about 2 330, against 4 030 for the filter.
Filter or smoother? The smoother uses future data. Use it to describe the past: decomposition into trend and season, filling gaps, finding the date of a level shift, or anomaly analysis (lesson 11). Never use it to make or evaluate forecasts: in a backtest (lesson 03), a smoothed state at the forecast origin has seen the test period. That is leakage.
You backtest a local level model with a rolling origin. At each origin you need the state estimate to start the forecast. Which estimate do you use?
uses , which are in the test period, so the backtest would leak the future. The filter and the smoother agree only at the last time of the series that was smoothed, not at an origin inside it. Smaller variance is not an advantage if it comes from data you would not have.
Beyond linear and Gaussian
- Extended Kalman filter (EKF). For , , linearise and around the current estimate (Jacobians) and run the Kalman steps. Works when the nonlinearity is mild over the size of the uncertainty.
- Unscented Kalman filter (UKF). Push chosen "sigma points" through and and match the mean and covariance. No Jacobians; often more accurate than the EKF.
- Particle filter. Represent the distribution by many weighted samples; predict by simulating the model, update by weighting with the likelihood, and resample. Works for any model, but needs many particles when the state has many dimensions.
- Ensemble Kalman filter and 4D-Var. For states with millions of entries (weather), estimate from an ensemble of model runs, or solve a variational problem over a time window. See the ml-for-science track.
- Deep state-space layers. S4 and Mamba use , (deep-learning lesson 16): is our , is our , is a known input. There is no noise and no update step; the matrices are learned by gradient descent.
Answers to section 1. (1) About 2.1 m. Precisions add: , so the variance is and the standard deviation is m, which is . (2) During the gap only the predict step runs, so the variance grows by (local level) or faster (models with a velocity) at every step. At the first observation after the gap the gain is large, so the estimate jumps toward the data and the variance drops at once. (3) Yes: the local level model (random walk plus noise). SES with is its steady-state Kalman filter, and is decided by the signal-to-noise ratio .
4. Worked example #
(a) Three steps of the local level filter. , , start , , observations , , .
Step .
- Predict: , .
- Innovation: , with variance .
- Gain: .
- Update: , .
Step .
- Predict: , .
- Innovation: , .
- Gain: .
- Update: , .
Step .
- Predict: , .
- Innovation: , .
- Gain: .
- Update: , .
Steady state. The gains approach . Here , so
with . The filter becomes SES with .
Forecast from . for every . The variance of is : , , for . The 95 % interval for is .
Log-likelihood. Each term is : , , , so .
Missing . Skip the update at : , . Then , (larger than before) and .
(b) One step of constant-velocity tracking. , , , , start (position 0, velocity 1), . We observe .
- Predict the mean: .
- Predict the covariance: , and adding gives . The off-diagonal 1 is new: position and velocity are now correlated.
- Innovation: ; .
- Gain: , that is .
- Update: .
- Covariance:
The target is further ahead than predicted, so the filter raises the velocity from 1 to 1.5, although the velocity was not measured. The position variance fell from 2 to ; the velocity variance fell only from 2 to .
5. In code #
One function covers every model of this lesson. It treats a row of NaN as a missing observation.
import numpy as np
from scipy.optimize import minimize
def kalman_filter(y, F, H, Q, R, x0, P0):
"""Filtered means/covariances and log-likelihood. y: (n, k) array; NaN rows are missing."""
x, P = np.asarray(x0, float), np.asarray(P0, float)
xs, Ps, loglik = [], [], 0.0
for yt in y:
x, P = F @ x, F @ P @ F.T + Q # predict
if not np.any(np.isnan(yt)): # update (skip if missing)
nu = yt - H @ x # innovation
S = H @ P @ H.T + R # its covariance
K = P @ H.T @ np.linalg.inv(S) # Kalman gain
x, P = x + K @ nu, (np.eye(len(x)) - K @ H) @ P
loglik -= 0.5 * (np.log(np.linalg.det(2 * np.pi * S)) + nu @ np.linalg.solve(S, nu))
xs.append(x); Ps.append(P)
return np.array(xs), np.array(Ps), loglik
# worked example (a): local level, Q = 1, R = 2, prior N(10, 3)
I = np.eye(1)
y = np.array([[13.], [11.], [14.]])
xs, Ps, ll = kalman_filter(y, I, I, 1 * I, 2 * I, [10.], 3 * I)
print(xs.ravel().round(4), Ps.ravel().round(4), round(ll, 4))
# [12. 11.4615 12.7547] [1.3333 1.0769 1.0189] -6.7442
y_miss = np.array([[13.], [np.nan], [14.]])
print(kalman_filter(y_miss, I, I, I, 2 * I, [10.], 3 * I)[0].ravel().round(4))
# [12. 12. 13.25]
# worked example (b): one step of constant-velocity tracking
F = np.array([[1., 1.], [0., 1.]]); H = np.array([[1., 0.]])
xs, Ps, _ = kalman_filter(np.array([[2.5]]), F, H, np.diag([0., 1.]), np.eye(1), [0., 1.], np.eye(2))
print(xs[0], Ps[0].round(4).tolist())
# [2. 1.5] [[0.6667, 0.3333], [0.3333, 1.6667]]
# Nile: maximum likelihood for (Q, R); NILE holds the 100 values (they are in the notebook)
def neg_loglik(theta):
Q, R = np.exp(theta) # log scale keeps the variances positive
# exact diffuse start: x_{1|1} = y_1, P_{1|1} = R; the likelihood starts at t = 2
return -kalman_filter(NILE[1:, None], I, I, Q * I, R * I, [NILE[0]], R * I)[2]
res = minimize(neg_loglik, x0=np.log([1000., 10000.]), method="Nelder-Mead")
Q_hat, R_hat = np.exp(res.x)
q = Q_hat / R_hat
print(round(Q_hat), round(R_hat), round(-res.fun, 2)) # 1469 15099 -632.55
print(round(q, 4), round((np.sqrt(q**2 + 4*q) - q) / 2, 3)) # 0.0973 0.267
For real work, statsmodels has the same model as sm.tsa.UnobservedComponents(y, "local level")
and general models with sm.tsa.statespace.MLEModel. The notebook compares the results in an optional cell.
6. Where it shows up #
- Classical forecasting software. statsmodels fits ARIMA, SARIMAX, unobserved-components and
dynamic factor models through the Kalman filter; this is how it handles missing values and
computes the exact likelihood. The R package
KFASand the structural models of Harvey (1989) work the same way. - Structural time-series models. Write a series as level + trend + season + regression, each a block of the state, and read the smoothed components. Time-varying regression coefficients ( with a random walk) are a state-space model with ; economists use them for changing relations and nowcasting.
- Navigation and robotics. GPS + inertial sensor fusion, target tracking with radar, and the EKF in SLAM.
- Weather and climate. Data assimilation combines a physical model forecast with millions of observations; the ensemble Kalman filter and 4D-Var are the large-scale versions of the update step (see the ml-for-science track).
- Machine learning. Probabilistic state-space models with a neural network inside (deep Kalman filters, DeepState) use the same predict–update structure. S4 and Mamba layers use the linear state equation without noise (deep-learning lesson 16). A Gaussian process with a Matérn kernel in time can be written as a state-space model, so a Kalman filter computes it in instead of (Hartikainen and Särkkä, 2010).
7. Common mistakes #
- Mixing up the state and the observation. is hidden; is measured. The filtered level is not the data, and the interval for must add to the state variance.
- Mixing up the covariances. (before ), (after ) and (of the observation) are three different things. The gain uses , not .
- Thinking the gain is a free parameter. follows from and . To get a smoother or a more reactive filter, change or (or better, estimate them).
- Too small a . With near 0 the filter "trusts the model" and becomes slow; it can lag behind a real change for a long time. The innovations then have long runs of one sign: check them.
- Using the smoother for forecasts or in a backtest. It uses future data. Only the filter is allowed at a forecast origin.
- Forgetting the start. A small with a wrong makes the first estimates wrong for a long time, and the first likelihood terms can dominate the fit. Use a diffuse start when you know nothing.
8. Check yourself #
- Write the model , (an AR(1) measured with noise)
in state-space form.
Answer
State , , , , . With a natural start is the stationary distribution: , (lesson 02). - In the local level model set and use a diffuse start. What does the filter compute?
Answer
The running mean. With the level is a constant . After the diffuse start, and . By induction, if , then and , the update of the mean of , with . The gain goes to 0, which matches for . - In worked example (b), why did the velocity estimate change although measures only the position?
Answer
The predict step made position and velocity correlated: has off-diagonal entry 1. The gain is , the first column of over , so its second entry is . A position surprise of therefore raises the velocity by . - Why does the likelihood use the innovations and not the observations themselves?
Answer
The are dependent, so their joint density is not a product of marginals. The chain rule writes it as a product of one-step conditional densities , and each one is the Gaussian density of the innovation with covariance . Under the model the innovations are independent, so the log-likelihood is a simple sum. - For the Nile data the filter at 1970 gives and , with and . Give the 95 % prediction interval for the flow in 1971.
Answer
The variance is , so the standard deviation is . The interval is , about . Most of the width comes from , the year-to-year noise, not from the uncertainty about the level. - At which time do the filter and the smoother give the same estimate, and why?
Answer
At the last time . There, both condition on the same data , so is both the filtered and the smoothed estimate. The RTS recursion starts from it and goes backward.
Write the two equations of a linear Gaussian state-space model.
State: , . Observation: , .
What does the predict step of the Kalman filter compute?
and .
Give the Kalman gain in the vector case.
with .
What does the update step compute?
with , and .
Prior , observation with . What is the posterior?
, so .
What is the steady-state gain of the local level model?
with ; for example when .
How are SES and the Kalman filter related?
SES with is the steady-state Kalman filter of the local level model (random walk plus noise).
How does the Kalman filter handle a missing observation?
It skips the update step: , . The variance grows during the gap.
State the prediction-error decomposition of the log-likelihood.
: a sum over the innovations.
Why may only the filter, not the smoother, be used at a forecast origin?
The smoother estimate uses data after ; in a backtest that is leakage from the test period.
9. Interview angle #
- "Explain the Kalman filter in one minute." — A hidden state follows a linear model with noise and is measured with noise. Predict: push the estimate and its covariance through the model. Update: correct with the innovation times the gain, which weighs prediction uncertainty against sensor noise. For linear Gaussian models it is the exact posterior.
- "What is the intuition for the Kalman gain?" — It is the relative trust in the measurement: in one dimension. Precisions add. Large → small gain; large prediction uncertainty → gain near 1.
- "How do you choose and ?" — Estimate them by maximum likelihood with the prediction-error decomposition, then check that the standardised innovations look like white noise with variance 1. Hand tuning is a last resort.
- "What is the link between SES and the Kalman filter?" — SES is the steady-state filter of the local level model, with fixed by . ARIMA(0,1,1) with gives the same forecasts.
- "Filter vs smoother vs forecast?" — , and . Only the filter and the forecast are allowed in real-time use and in backtests.
- "What do you do for a nonlinear model?" — EKF (linearise), UKF (sigma points) or a particle filter (samples); for very large states the ensemble Kalman filter.
10. Practice #
The notebook for this lesson runs in Colab. It has five exercises, each with a check cell and a folded solution:
- Write
kalman_filter(y, F, H, Q, R, x0, P0)that returns filtered means, covariances and the log-likelihood and treatsnp.nanas missing; check it on worked example (a) and against Bayes' rule computed on a grid. - Track a constant-velocity target from position-only observations and compare the RMSE of the filtered position with the RMSE of the raw observations.
- Compute the steady-state gain of the local level model and show that SES with gives the same values as the filter after the start-up.
- Fit the local level model to the Nile data: maximise the log-likelihood over with
scipy.optimize.minimizeand compare with , . - Write
rts_smootherand check that the smoothed variances are never larger than the filtered ones.
11. Watch and read #
- Durbin and Koopman, Time Series Analysis by State Space Methods, 2nd ed., Oxford University Press, 2012 (publisher page): ch. 2 is the local level model with the Nile data; ch. 3 puts ARIMA and structural models in state-space form.
- Simo Särkkä, Bayesian Filtering and Smoothing, Cambridge University Press 2013, free PDF from the author: ch. 4 (Kalman filter as Bayesian filtering) and ch. 8 (RTS smoother).
- Hyndman and Athanasopoulos, Forecasting: Principles and Practice (3rd ed.), §8.5 Innovations state space models for exponential smoothing.
- Greg Welch and Gary Bishop, An Introduction to the Kalman Filter, UNC technical report TR 95-041: a short, practical introduction with the discrete filter equations.
- Shumway and Stoffer, Time Series Analysis and Its Applications, 4th ed., Springer 2017, ch. 6 (state-space models), with R code on the authors' GitHub page.
- statsmodels documentation:
UnobservedComponentsand state-space methods.
Runs in your browser with nothing to install. The notebook repeats the key demos and has exercises with checks; solutions are inside, folded.
No Google account needed: Python runs inside your browser. The first start downloads about 40 MB; your changes are saved in this browser only.