smoothing¶
This module implements:
- particle history classes, which store the full or partial history of a SMC algorithm.
- off-line smoothing algorithms as methods of these classes.
For on-line smoothing, see instead the collectors module.
History classes¶
A SMC
object has a hist
attribute, which is used to record at certain
times t:
- the N current particles \(X_t^n\);
- their weights;
- (optionally, see below), the ancestor variables \(A_t^n\).
The frequency at which history is recorded depends on option store_history
of class SMC
. Possible options are:
True
: records full history (at every time t);False
: no history (attributehist
set toNone
);- callable
f
: history is recorded at time t iff(t)
returns True - int k: records a rolling window history of length k (may be used to perform fixed-lag smoothing)
This module implements different classes that correspond to the different cases:
- particles.smoothing.ParticleHistory: full history (based on lists)
PartialParticleHistory
: partial history (based on dictionaries)RollingParticleHistory
: rolling window history (based on deques)
All these classes provide a similar interface. If smc
is a SMC
object,
then:
smc.hist.X[t]
returns the N particles at time tsmc.hist.wgts[t]
returns the N weights at time t (seeresampling.weights
)smc.hist.A[t]
returns the N ancestor variables at time t
Partial History¶
Here are some examples on one may record history only at certain times:
# store every other 10 iterations
smc = SMC(fk=fk, N=100, store_history=lambda t: (t % 10) == 0)
# store at certain times given by a list
times = [10, 30, 84]
smc = SMC(fk=fk, N=100, store_history=lambda t: t in times)
Once the algorithm is run, smc.hist.X
and smc.hist.wgts
are
dictionaries, the keys of which are the times where history was recorded. The
ancestor variables are not recorded in that case:
smc.run()
smc.hist.X[10] # the N particles at time 10
smc.hist.A[10] # raises an error
Full history, off-line smoothing algorithms¶
For a given state-space model, off-line smoothing amounts to approximate the distribution of the complete trajectory \(X_{0:T}\), given data \(y_{0:T}\), at some fixed time horizon T. The corresponding algorithms take as an input the complete history of a particle filter, run until time T (forward pass). Say:
# forward pass
fk = ssm.Bootstrap(ssm=my_ssm, data=y)
pf = particles.SMC(fk=fk, N=100, store_history=True)
pf.run()
Then, pf.hist
is an instance of class particles.smoothing.ParticleHistory. It implements two
types of approaches:
- two-filter smoothing: uses two particle filters (one forward, one backward) to estimate marginal expectations; see
two_filter_smoothing
.- FFBS (forward filtering backward sampling): uses one particle filter, then generates trajectories from its history, using different methods (exact, rejection, MCMC, QMC). See
backward_sampling_mcmc
,backward_sampling_ON2
,backward_sampling_reject
, andbackward_sampling_qmc
. Recommended method isbackward_sampling_mcmc
, see discussion in Dang & Chopin (2022).
For more details, see the documentation of particles.smoothing.ParticleHistory, the ipython notebook on smoothing, Chapter 12 of the book, and Dang & Chopin (2022).
Warning
the complete history of a particle filter may take a lot of memory.
Rolling history, Fixed-lag smoothing¶
To obtain a rolling window (fixed-length) history:
smc = SMC(fk=fk, N=100, store_history=10)
smc.run()
In that case, fields smc.hist.X
, smc.hist.wgts
and smc.hist.A
are
deques of max length 10. Using negative indices:
smc.hist.X[-1] # the particles at final time T
smc.hist.X[-2] # the particles at time T - 1
# ...
smc.hist.X[-10] # the N particles at time T - 9
smc.hist.X[-11] # raises an error
Note that this type of history makes it possible to perform fixed-lag smoothing as follows:
B = smc.hist.compute_trajectories()
# B[t, n] is index of ancestor of X_T^n at time t
phi = lambda x: x # any test function
est = np.average(phi(smc.hist.X[-10][B[-10, :]]), weights=smc.W)
# est is an estimate of E[ phi(X_{T-9}) | Y_{0:T}]
Note
recall that it is possible to run SMC
algorithms step by step,
since they are iterators. Hence it is possible to do fixed-lag smoothing
step-by-step as well.
Module summary¶
ParticleHistory (fk, qmc) |
Particle history. |
PartialParticleHistory (func) |
Partial history. |
RollingParticleHistory (length) |
Rolling window history. |
smoothing_worker ([method, N, fk, fk_info, …]) |
Generic worker for off-line smoothing algorithms. |