1- ##############################################################################
2- #
3- # Example of particle Metropolis-Hastings in a LGSS model.
4- #
5- # Copyright (C) 2017 Johan Dahlin < liu (at) johandahlin.com.nospam >
6- #
7- # This program is free software; you can redistribute it and/or modify
8- # it under the terms of the GNU General Public License as published by
9- # the Free Software Foundation; either version 2 of the License, or
10- # (at your option) any later version.
11- #
12- # This program is distributed in the hope that it will be useful,
13- # but WITHOUT ANY WARRANTY; without even the implied warranty of
14- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15- # GNU General Public License for more details.
16- #
17- # You should have received a copy of the GNU General Public License along
18- # with this program; if not, write to the Free Software Foundation, Inc.,
19- # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20- #
21- ##############################################################################
1+ # Parameter estimation using particle Metropolis-Hastings in a LGSS model.
222
233from __future__ import print_function , division
24-
25- # Import libraries
264import matplotlib .pylab as plt
275import numpy as np
286
29- # Import helpers
307from helpers .dataGeneration import generateData
318from helpers .stateEstimation import particleFilter , kalmanFilter
329from helpers .parameterEstimation import particleMetropolisHastings
3310
34- # Set the random seed
11+ # Set the random seed to replicate results in tutorial
3512np .random .seed (10 )
3613
37-
38- #=============================================================================
3914# Define the model
40- #=============================================================================
41-
42- # Here, we use the following model
43- #
44- # x[t + 1] = phi * x[t] + sigmav * v[t]
45- # y[t] = x[t] + sigmae * e[t]
46- #
47- # where v[t] ~ N(0, 1) and e[t] ~ N(0, 1)
48-
49- # Set the parameters of the model (phi, sigmav, sigmae)
50- theta = np .zeros (3 )
51- theta [0 ] = 0.75
52- theta [1 ] = 1.00
53- theta [2 ] = 0.10
54-
55- # Set the number of time steps to simulate
56- T = 250
57-
58- # Set the initial state
15+ # x[t + 1] = phi * x[t] + sigmav * v[t], v[t] ~ N(0, 1)
16+ # y[t] = x[t] + sigmae * e[t], e[t] ~ N(0, 1)
17+
18+ # Set the parameters of the model theta = (phi, sigmav, sigmae), T, x_0
19+ parameters = np .zeros (3 )
20+ parameters [0 ] = 0.75
21+ parameters [1 ] = 1.00
22+ parameters [2 ] = 0.10
23+ noObservations = 250
5924initialState = 0
6025
61-
62- #=============================================================================
63- # Generate data
64- #=============================================================================
65-
66- x , y = generateData (theta , T , initialState )
67-
68-
69- #=============================================================================
70- # Parameter estimation using PMH
71- #=============================================================================
72-
73- # The inital guess of the parameter
26+ # Settings for PMH
7427initialPhi = 0.50
75-
76- # No. particles in the particle filter ( choose noParticles ~ T )
77- noParticles = 500
78-
79- # The length of the burn-in and the no. iterations of PMH
80- # ( noBurnInIterations < noIterations )
28+ noParticles = 500 # Use noParticles ~ noObservations
8129noBurnInIterations = 1000
8230noIterations = 5000
83-
84- # The standard deviation in the random walk proposal
8531stepSize = 0.10
8632
87- # Run the PMH algorithm
88- res = particleMetropolisHastings (y , initialPhi , theta , noParticles , initialState ,
89- particleFilter , noIterations , stepSize )
33+ # Generate data
34+ state , observations = generateData (parameters , noObservations , initialState )
9035
36+ # Run the PMH algorithm
37+ phiTrace = particleMetropolisHastings (
38+ observations , initialPhi , parameters , noParticles ,
39+ initialState , particleFilter , noIterations , stepSize )
9140
92- #=============================================================================
9341# Plot the results
94- #=============================================================================
95-
9642noBins = int (np .floor (np .sqrt (noIterations - noBurnInIterations )))
9743grid = np .arange (noBurnInIterations , noIterations , 1 )
98- resPhi = res [noBurnInIterations :noIterations ]
44+ phiTrace = phiTrace [noBurnInIterations :noIterations ]
9945
100- # Plot the parameter posterior estimate
101- # Solid black line indicate posterior mean
46+ # Plot the parameter posterior estimate (solid black line = posterior mean)
10247plt .subplot (3 , 1 , 1 )
103- plt .hist (resPhi , noBins , normed = 1 , facecolor = '#7570B3' )
48+ plt .hist (phiTrace , noBins , normed = 1 , facecolor = '#7570B3' )
10449plt .xlabel ("phi" )
10550plt .ylabel ("posterior density estimate" )
106- plt .axvline (np .mean (resPhi ), color = 'k' )
51+ plt .axvline (np .mean (phiTrace ), color = 'k' )
10752
108- # Plot the trace of the Markov chain after burn-in
109- # Solid black line indicate posterior mean
53+ # Plot the trace of the Markov chain after burn-in (solid black line = posterior mean)
11054plt .subplot (3 , 1 , 2 )
111- plt .plot (grid , resPhi , color = '#7570B3' )
55+ plt .plot (grid , phiTrace , color = '#7570B3' )
11256plt .xlabel ("iteration" )
11357plt .ylabel ("phi" )
114- plt .axhline (np .mean (resPhi ), color = 'k' )
58+ plt .axhline (np .mean (phiTrace ), color = 'k' )
11559
11660# Plot the autocorrelation function
11761plt .subplot (3 , 1 , 3 )
118- macf = np .correlate (resPhi - np .mean (resPhi ), resPhi - np .mean (resPhi ), mode = 'full' )
119- macf = macf [macf .size / 2 :]
62+ macf = np .correlate (phiTrace - np .mean (phiTrace ), phiTrace - np .mean (phiTrace ), mode = 'full' )
63+ idx = int (macf .size / 2 )
64+ macf = macf [idx :]
12065macf = macf [0 :100 ]
12166macf /= macf [0 ]
12267grid = range (len (macf ))
12368plt .plot (grid , macf , color = '#7570B3' )
12469plt .xlabel ("lag" )
12570plt .ylabel ("ACF of phi" )
12671
127-
128- ##############################################################################
129- # End of file
130- ##############################################################################
72+ plt .show ()
0 commit comments