particles.state_space_models¶
Statespace models as Python objects.
Overview¶
This module defines:
the
StateSpaceModel
class, which lets you define a statespace model as a Python object;
FeynmanKac
classes that automatically define the Bootstrap, guided or auxiliary FeynmanKac models associated to a given statespace model;several standard statespace models (stochastic volatility, bearingsonly tracking, and so on).
The recommended import is:
from particles import state_space_models as ssms
For more details on statespace models and their properties, see Chapters 2 and 4 of the book.
Defining a statespace model¶
Consider the following (simplified) stochastic volatility model:
To define this particular model, we subclass StateSpaceModel
as follows:
import numpy as np
from particles import distributions as dists
class SimplifiedStochVol(ssms.StateSpaceModel):
default_params = {'sigma': 1., 'rho': 0.8} # optional
def PY(self, t, xp, x): # dist of Y_t at time t, given X_t and X_{t1}
return dists.Normal(scale=np.exp(x))
def PX(self, t, xp): # dist of X_t at time t, given X_{t1}
return dists.Normal(loc=self.mu + self.rho * (xp  self.mu),
scale=self.sigma)
def PX0(self): # dist of X_0
return dists.Normal(scale=self.sigma / np.sqrt(1.  self.rho**2))
Then we define a particular object (model) by instantiating this class:
my_stoch_vol_model = SimplifiedStochVol(sigma=0.3, rho=0.9)
Hopefully, the code above is fairly transparent, but here are some noteworthy details:
probability distributions are defined through
ProbDist
objects, which are defined in moduledistributions
. Most basic probability distributions are defined there; see moduledistributions
for more details.The class above actually defines a parametric class of models; in particular,
self.sigma
andself.rho
are attributes of this class that are set when we define objectmy_stoch_vol_model
. Default values for these parameters may be defined in a dictionary calleddefault_params
. When this dictionary is defined, any undefined parameter will be replaced by its default value:default_stoch_vol_model = SimplifiedStochVol() # sigma=1., rho=0.8There is no need to define a
__init__()
method, as it is already defined by the parent class. (This parent__init__()
simply takes care of the default parameters, and may be overridden if needed.)
Now that our statespace model is properly defined, what can we do with it? First, we may simulate states and data from it:
x, y = my_stoch_vol_model.simulate(20)
This generates two lists of length 20: a list of states, X_0, …, X_{19} and a list of observations (datapoints), Y_0, …, Y_{19}.
Associated FeynmanKac models¶
Now that our statespace model is defined, we obtain the associated Bootstrap FeynmanKac model as follows:
my_fk_model = ssms.Bootstrap(ssm=my_stoch_vol_model, data=y)
That’s it! You are now able to run a bootstrap filter for this model:
my_alg = particles.SMC(fk=my_fk_model, N=200)
my_alg.run()
In case you are not clear about what are FeynmanKac models, and how one may associate a FeynmanKac model to a given statespace model, see Chapter 5 of the book.
To generate a guided FeynmanKac model, we must provide proposal kernels (that is, Markov kernels that define how we simulate particles X_t at time t, given an ancestor X_{t1}):
class StochVol_with_prop(StochVol):
def proposal0(self, data):
return dists.Normal(scale = self.sigma)
def proposal(t, xp, data): # a silly proposal
return dists.Normal(loc=rho * xp + data[t], scale=self.sigma)
my_second_ssm = StochVol_with_prop(sigma=0.3)
my_better_fk_model = ssms.GuidedPF(ssm=my_second_ssm, data=y)
# then run a SMC as above
Voilà! You have now implemented a guided filter.
Of course, the proposal distribution above does not make much sense; we use it
to illustrate how proposals may be defined. Note in particular that it depends
on data
, an object that represents the complete dataset. Hence the proposal
kernel at time t
may depend on y_t but also y_{t1}, or any other
datapoint.
For auxiliary particle filters (APF), one must in addition specify auxiliary functions, that is the (log of) functions \(\eta_t\) that modify the resampling probabilities (see Section 10.3.3 in the book):
class StochVol_with_prop_and_aux_func(StochVol_with_prop):
def logeta(self, t, x, data):
"Log of auxiliary function eta_t at time t"
return (xdata[t])**2
my_third_ssm = StochVol_with_prop_and_aux_func()
apf_fk_model = ssms.AuxiliaryPF(ssm=my_third_ssm, data=y)
Again, this particular choice does not make much sense, and is just given to show how to define an auxiliary function.
Already implemented statespace models¶
This module implements a few basic statespace models that are often used as numerical examples:
Class 
Comments 


Basic, univariate stochastic volatility model 

Univariate stochastic volatility model with leverage 

Multivariate stochastic volatility model 

Bearingsonly tracking 

Popular toy model often used as a benchmark 

A discrete Cox model (Y_tX_t is Poisson) 

Thetalogistic model from Population Ecology 
Classes



Base class for auxiliary bootstrap particle filters 

Auxiliary particle filter for a given statespace model. 

Bearingsonly tracking SSM. 

Bootstrap FeynmanKac formalism of a given statespace model. 

A discrete Cox model. 

Popular toy example that appeared initially in Gordon et al (1993). 

Guided filter for a given statespace model. 

Multivariate stochastic volatility model. 

Base class for statespace models. 

Univariate stochastic volatility model. 

Univariate stochastic volatility model with leverage effect. 

ThetaLogistic statespace model (used in Ecology). 