System Identification › Parametric Identification
World Models HandbookAll chapters System Identification › Parametric IdentificationOne section · Sections in this chapter4 / 11 ↓
Reading tools Definitions & inline links
Choose your expertise level to adjust how many terms are explained. Beginners see more tooltips, experts see fewer to maintain reading flow. Hover over underlined terms for instant definitions.
Article links
Make inline references clickable
Parametric methods commit to a function class with finitely many parameters and optimize those parameters against data. The commitment is a bargain: you accept misspecification risk in exchange for statistical efficiency, interpretability, and computational tractability. When the class contains (or nearly contains) the truth, parametric methods extract an extraordinary amount from modest data; when it does not, they converge efficiently to the wrong answer. This section builds the two workhorse approaches: regression for linear systems and the prediction-error method as the general template.
Linear Systems by Least Squares
Start with the friendliest case, friendly enough that we can see the entire estimation logic laid bare before complications arrive. Suppose we have full-state data and posit the linear model class:
where:
- : the unknown state-transition matrix, propagating today's state forward under the system's internal dynamics
- : the unknown input matrix, converting commanded actions into state change
- : the process-noise residual at time , the part of the deterministic part cannot account for
The crucial observation is that for a linear model class, each row of the unknown matrices appears in one state equation independently, so what looks like a dynamical-systems problem decomposes into ordinary multiple regression, one row at a time. Stack the unknowns row-wise into a matrix of shape , and define the regressor . Every transition is a linear equation:
Arranging all transitions into matrices (regressors as columns) and (successor states as columns), ordinary least squares solves
which is exactly ordinary linear regressions sharing one regressor matrix, one per state dimension, each using the same transition observations. Read the middle expression physically: is the empirical second moment of the stacked state-input regressors used in this fit. Positive definiteness of this finite-record matrix is exactly the condition for a unique least-squares estimate. Without full rank, the displayed inverse does not exist and some parameter directions remain unidentified, although a pseudoinverse still returns one of many minimizing solutions. Persistent excitation is the related asymptotic richness condition on the input sequence: it is designed to keep the relevant empirical information matrices nonsingular as data accumulates, but it is stronger than full rank in one finite record and is not literally identical to the joint state-input rank condition here.
Under i.i.d. Gaussian innovations, least squares coincides with maximum likelihood and is asymptotically efficient under the usual regularity and excitation conditions. With lagged stochastic states as regressors, finite-sample estimates can retain an dynamic-regression bias even though current innovations are uncorrelated with current regressors. Under non-Gaussian white noise with the same exogeneity conditions, least squares remains consistent and asymptotically unbiased but generally loses Gaussian efficiency. The clean distinction for this chapter is therefore consistency versus persistent misspecification bias, not exact finite-sample unbiasedness.
When only inputs and outputs are available, we posit an autoregressive model, the classical ARX form ("auto-regressive with exogenous input"). For a second-order system with scalar output,
where:
- : coefficients on the lagged outputs; together they form the characteristic polynomial , whose roots are the poles we will shortly compare against the true system eigenvalues
- : coefficients on the lagged inputs
- : the one-step-ahead prediction error. Plain least squares is consistent only when this composite error is orthogonal to the lagged-output and lagged-input regressors; process noise or measurement noise entering those lagged outputs can violate that condition. Whiteness is an additional condition used by standard uncertainty and efficiency calculations.
and again least squares applies with regressor . The philosophical move here is elegant: instead of estimating a hidden state and then the dynamics on it, we promote the lagged output history itself to be the state. The model implicitly treats its own past predictions as state, so ARX is a one-step predictor even when the physical system was written in state-space form. For minimal observable systems these two descriptions contain identical input-output information; they differ only in coordinates and in what happens to noise, which is exactly the caveat coming next. Fitting the ARX denominator coefficients and comparing their roots to the true system eigenvalues reveals something important: the recovery happens in input-output coordinates, a different (but equivalent, for minimal systems) description than the internal state.
Notice what changed, because it quietly invalidates the clean theory. With full-state data, the regression noise is the current process disturbance and the current regressor is built from variables available before that disturbance. With output data, eliminating the hidden state produces a composite equation error containing earlier process disturbances; sensor noise can also enter the lagged outputs. Either source can therefore appear in both today's regressor and today's equation error, biasing plain ARX least squares. In the drone example below, process noise alone is enough: the eliminated equation contains , while contains . Such correlation can persist with more data, so the estimator may converge to a shifted value. Correcting that bias leads to the general template.
The Prediction-Error Method
The prediction-error method (PEM) generalizes linear regression into a principle for essentially any model class. Rather than regressing outputs on raw lagged quantities and hoping the implicit noise bookkeeping works out, PEM asks each candidate model to do its own optimal prediction, noise structure included. Define a one-step-ahead predictor associated with candidate model : , the conditional expectation of the next output given everything observed through time , assuming the world behaves like . The definition matters: this conditional expectation uses only data available through time , so when past measurements are noisy, the optimal predictor weighs recent observations less than it would trust clean states. For a linear state-space model with Gaussian noises, computing this predictor is exactly the Kalman filter recursion from our previous chapter, run with 's matrices. Here the two chapters meet operationally: the filter, previously the consumer of a known model, becomes an internal subroutine of the estimator searching for the model. PEM then optimizes:
typically with quadratic loss , whereupon PEM reduces to negative log-likelihood maximization for Gaussian output noise. Three properties justify why PEM became the classical centerpiece:
- Statistical grounding. With structural containment, identifiability, informative data, and standard stability and regularity assumptions, a correctly specified maximum-likelihood PEM is consistent and asymptotically efficient. Under misspecification it instead converges to the best approximation selected by its loss, which need not be the physical system.
- Noise-model honesty. Unlike bare ARX regression, PEM lets you declare whether disturbances corrupt the state dynamics (equation error), only the sensor (output error), or something in between. A wrong disturbance model can shift the pseudo-true parameters and forfeits the clean maximum-likelihood efficiency guarantee, even when some parameter estimates remain consistent under weaker conditions. When a network minimizes squared one-step error against noisy observations, it adopts a Gaussian one-step-prediction scoring rule on noisy targets; that loss alone does not specify a classical output-error model structure.
- Model-quality framing. PEM scores exactly the quantity a filter consumes: predictive likelihood of new data. Models good for filtering are judged on their own terms. This alignment between the training objective and the downstream consumer is rarer than it sounds; later we will see planning consumes models quite differently, and the mismatch will matter.
Its costs: PEM optimization is nonlinear in (each loss evaluation runs a filter pass), initialization-sensitive, and locally convergent at best. Each gradient or search step requires filtering the entire record, and the loss surface over multi-dimensional parameter spaces can harbor local minima corresponding to qualitatively wrong dynamics that nonetheless predict the data mediocre-but-decently. Multi-start strategies, careful initialization from cheaper methods, and structure-exploiting implementations mitigate but do not eliminate this friction. This computational friction motivated the family we visit next.
Worked Example: Recovering a Drone's Lateral Dynamics
Consider a crude lateral dynamics model of a quadrotor hovering, linearized about hover and discretized at 50 Hz:
where is the lateral velocity proxy, is its rate, is the differential motor command, and records that only the first component of the state reaches the sensor. The complex-conjugate eigenvalues of this have modulus about , describing a moderately damped side-to-side oscillation: errors rotate as they decay rather than disappearing in one step. We simulate it under a spectrally rich shaped-noise input, then fit (a) the full-state linear regression and (b) a second-order ARX model on the scalar output, checking that both recover the dynamics, one up to nothing (states observed, exact coordinates) and one up to input-output equivalence. We then evaluate the fitted full-state model recursively on overlapping starts from the held-out tail, under the recorded exogenous action sequence. Comparing its horizon-30 error with the true-model floor isolates the excess caused by estimation imperfection; the code reports that gap explicitly rather than asking you to infer it from the plot.
Let's code this. Everything numerical in this chapter uses NumPy first, PyTorch only in the neural section.
import numpy as np
rng = np.random.default_rng(11)
## Ground-truth second-order linear system (quadrotor lateral toy model)
A_true = np.array([[0.90, 0.35], [-0.15, 0.75]])
B_true = np.array([[0.0], [0.6]])
C_true = np.array([[1.0, 0.0]])
T = 400
X = np.zeros((T + 1, 2))
U = np.zeros(T)
## Richly excited input: sum of slowly varying random components
white = rng.normal(size=T)
U[0] = white[0]
for t in range(1, T):
U[t] = 0.8 * U[t - 1] + 0.6 * white[t]
## Roll out the system with small process noise
proc_std = 0.01
w = rng.normal(scale=proc_std, size=(T, 2))
for t in range(T):
X[t + 1] = A_true @ X[t] + B_true @ np.array([U[t]]) + w[t]
assert X.shape == (T + 1, 2)
assert U.shape == (T,)Trajectory length: 401, input std: 0.897 True eigenvalues of A: [0.825+0.2165j 0.825-0.2165j]
The clearly nonzero input standard deviation is an amplitude sanity check, not by itself proof of excitation. Richness comes from the shaped AR(1) generator's nonzero spectrum together with the full-rank regressor checks below. The complex-conjugate eigenvalues announce the moderately damped oscillatory lateral mode that every estimator in this section must recover. Passing white noise through a low-pass shaping filter produces a smoothly varying command signal while retaining broadband variation, an example of the "filtered random noise" entry from the excitation list made concrete. With the trajectory in hand, the full-state regression is four lines of linear algebra. We compare recovered eigenvalues against the truth to verify that the estimator did its job before trusting anything downstream.
## Full-state least squares: x_{t+1} = Theta @ [x_t, u_t]
T_fit = 320 # fit on the first 80% of transitions, hold out the rest
Phi = np.column_stack([X[:T_fit], U[:T_fit]]) # shape (T_fit, n+m)
Target = X[1 : T_fit + 1] # shape (T_fit, n)
Theta_hat, *_ = np.linalg.lstsq(Phi, Target, rcond=None)
Theta_hat = Theta_hat.T # lstsq returns (n+m, n); restore n x (n+m) layout
A_hat, B_hat = Theta_hat[:, :2], Theta_hat[:, 2:]
eig_est = np.sort_complex(np.linalg.eigvals(A_hat))
eig_true = np.sort_complex(np.linalg.eigvals(A_true))Estimated A: [[ 0.8996 0.3503] [-0.1501 0.7498]] Estimated B: [2.81603088e-04 6.00300265e-01] Eigenvalues estimated: [0.8247-0.2168j 0.8247+0.2168j] Eigenvalues true: [0.825-0.2165j 0.825+0.2165j] B error: 0.0004
Both estimated eigenvalues land close to the true pair, and the input gain comes out near . With 320 transitions informing six parameters, current process noise is orthogonal to the current regressors, so ordinary least squares is consistent and asymptotically unbiased under the stated excitation assumptions. This finite dynamic regression can still carry the bias described above, in addition to ordinary sampling variation. Now the honest-but-blind variant: hide the state, keep only the scalar first coordinate, and fit a second-order ARX model.
Y = X[:, 0] # we only get to see the first state component
## ARX(2): y_{t+1} = a1*y_t + a2*y_{t-1} + b1*u_t + b2*u_{t-1}
## Use only transitions in the same training prefix as the full-state fit.
arx_phi = np.column_stack(
[Y[1:T_fit], Y[: T_fit - 1], U[1:T_fit], U[: T_fit - 1]]
)
arx_target = Y[2 : T_fit + 1]
coef_arx, *_ = np.linalg.lstsq(arx_phi, arx_target, rcond=None)
a1, a2, b1, b2 = coef_arx
roots_arx = np.roots([1.0, -a1, -a2])
arx_r2 = 1 - np.var(arx_target - arx_phi @ coef_arx) / np.var(arx_target)ARX coefficients a1=1.6490, a2=-0.7268, b1=-0.0009, b2=0.2111 ARX-implied poles: [0.8245-0.2167j 0.8245+0.2167j] True poles: [0.825-0.2165j 0.825+0.2165j] ARX one-step R^2 on training data: 0.99996
Read the pole comparison carefully. In the noise-free minimal case, observability means the scalar input-output map contains the system poles up to input-output equivalence. Plain least squares on noisy ARX regressors does not generally attain that identifiability result asymptotically, because lagged noisy outputs can correlate with the equation error. On this seeded finite record, the ARX roots nevertheless happen to land close to the true pair. Treat that closeness as a run-specific empirical outcome, not as a guarantee of plain ARX regression. Had the system been unobservable from , some modes would have vanished from the input-output description entirely, an absence no goodness-of-fit statistic would flag; under correlated output noise, prediction-error methods are the principled remedy.
The agreement between the two estimators is easiest to judge in the complex plane. Here the oscillatory pair lies at radius about , safely inside the unit circle rather than especially close to it.
pole_true = np.linalg.eigvals(A_true)
pole_full = np.linalg.eigvals(A_hat)
pole_arx = roots_arx
Next we quantify the difference between one-step grading and recursive state prediction under the recorded action sequence. The rollout is closed-loop in predicted state but open-loop in actions: each predicted state feeds the next model step, while the controls remain the held-out controls from the dataset.
def linear_step(a_mat, b_mat, x, u):
return a_mat @ x + b_mat @ np.array([u])
horizons = np.arange(1, 31)
onestep_err = np.zeros(len(horizons))
rollout_err = np.zeros(len(horizons))
true_rollout_err = np.zeros(len(horizons))
max_horizon = int(horizons[-1])
## The exclusive stop guarantees both X[s + h] and U[s + h - 1] are in bounds
## for every h <= max_horizon.
val_starts = range(T_fit, len(X) - max_horizon)
for hi, h in enumerate(horizons):
se_one, se_roll, se_true = [], [], []
for s in val_starts:
# One-step: always restart from the true state
pred1 = linear_step(A_hat, B_hat, X[s], U[s])
se_one.append(np.sum((pred1 - X[s + 1]) ** 2))
# Recursive rollout: model output feeds back as model input
xr = X[s].copy()
for k in range(h):
xr = linear_step(A_hat, B_hat, xr, U[s + k])
se_roll.append(np.sum((xr - X[s + h]) ** 2))
# Reference: same recursion with the TRUE model (irreducible process noise)
xt = X[s].copy()
for k in range(h):
xt = linear_step(A_true, B_true, xt, U[s + k])
se_true.append(np.sum((xt - X[s + h]) ** 2))
onestep_err[hi] = np.mean(se_one)
rollout_err[hi] = np.mean(se_roll)
true_rollout_err[hi] = np.mean(se_true)
print(
f"Horizon 1: one-step={onestep_err[0]:.6f}, "
f"fitted rollout={rollout_err[0]:.6f}, "
f"true-model floor={true_rollout_err[0]:.6f}"
)
print(
f"Horizon {horizons[-1]}: one-step={onestep_err[-1]:.6f}, "
f"fitted rollout={rollout_err[-1]:.6f}, "
f"true-model floor={true_rollout_err[-1]:.6f}"
)
rollout_gap_30 = rollout_err[-1] - true_rollout_err[-1]
print(
f"Horizon {horizons[-1]} excess over true-model floor={rollout_gap_30:.6f}"
)
print(f"Held-out rollout starts: {len(val_starts)} overlapping starts")
assert np.isclose(onestep_err[0], rollout_err[0])Horizon 1: one-step=0.000177, fitted rollout=0.000177, true-model floor=0.000173
Horizon 30: one-step=0.000177, fitted rollout=0.001249, true-model floor=0.001047 Horizon 30 excess over true-model floor=0.000202 Held-out rollout starts: 51 overlapping starts
Nothing here is plotted yet; the next cell renders precomputed curves only.

The one-step curve is nearly flat with horizon because it is really the same measurement repeated: each evaluation restarts from truth, discards the model's previous guess entirely, and asks a fresh single question. Its flatness across "horizons" is therefore an artifact of the protocol, not a property of the model. In this seeded run the recursive curve climbs steadily: at horizon ten the model has consumed nine of its own guesses, each contributing error that the light damping preserves. The dashed true-model reference is nonzero because deterministic mean rollout cannot reproduce the realized process disturbances. The printed horizon-30 difference separates the fitted model's error from that run-specific reference; its positive value is an empirical observation for this seed, not a build invariant or a theorem about every finite record. The printed count also makes clear that the curve averages overlapping starts from the held-out tail. This experiment evaluates recursive use of the fitted full-state model under recorded controls, not an ARX rollout or a planner-generated action sequence. Part XI returns to these evaluation distinctions systematically.