|
3 | 3 | # Example of particle Metropolis-Hastings |
4 | 4 | # in a linear Gaussian state space model |
5 | 5 | # |
6 | | -# Copyright (C) 2015 Johan Dahlin < johan.dahlin (at) liu.se > |
7 | | -# |
| 6 | +# Copyright (C) 2017 Johan Dahlin < liu (at) johandahlin.com > |
| 7 | +# |
8 | 8 | # This program is free software; you can redistribute it and/or modify |
9 | 9 | # it under the terms of the GNU General Public License as published by |
10 | 10 | # the Free Software Foundation; either version 2 of the License, or |
11 | 11 | # (at your option) any later version. |
12 | | -# |
| 12 | +# |
13 | 13 | # This program is distributed in the hope that it will be useful, |
14 | 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 | 16 | # GNU General Public License for more details. |
17 | | -# |
| 17 | +# |
18 | 18 | # You should have received a copy of the GNU General Public License along |
19 | 19 | # with this program; if not, write to the Free Software Foundation, Inc., |
20 | 20 | # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
21 | 21 | # |
22 | 22 | ############################################################################## |
23 | 23 |
|
24 | | -# Import some libraries |
25 | | -import matplotlib.pylab as plt |
26 | | -import numpy as np |
27 | | -import stateEstimationHelper as helpState |
28 | | -import parameterEstimationHelper as helpParam |
| 24 | +# Import libraries |
| 25 | +import matplotlib.pylab as plt |
| 26 | +import numpy as np |
| 27 | + |
| 28 | +# Import helpers |
| 29 | +from helpers.stateEstimation import generateData, particleFilter |
| 30 | +from helpers.parameterEstimation import particleMetropolisHastings |
29 | 31 |
|
30 | 32 | # Set the random seed |
31 | | -np.random.seed( 10 ); |
| 33 | +np.random.seed(10) |
| 34 | + |
32 | 35 |
|
33 | 36 | ############################################################################## |
34 | 37 | # Define the model |
|
41 | 44 | # |
42 | 45 | # where v[tt] ~ N(0,1) and e[tt] ~ N(0,1) |
43 | 46 |
|
44 | | -# Set the parameters of the model (par[0],par[1],par[2]) |
45 | | -par = np.zeros(3) |
46 | | -par[0] = 0.75 |
47 | | -par[1] = 1.00 |
48 | | -par[2] = 1.00 |
| 47 | +# Set the parameters of the model (phi, sigmav, sigmae) |
| 48 | +theta = np.zeros(3) |
| 49 | +theta[0] = 0.75 |
| 50 | +theta[1] = 1.00 |
| 51 | +theta[2] = 1.00 |
49 | 52 |
|
50 | 53 | # Set the number of time steps to simulate |
51 | | -T = 250; |
| 54 | +T = 250 |
52 | 55 |
|
53 | 56 | # Set the initial state |
54 | | -x0 = 0; |
| 57 | +initialState = 0 |
| 58 | + |
55 | 59 |
|
56 | 60 | ############################################################################## |
57 | 61 | # Generate data |
58 | 62 | ############################################################################## |
59 | 63 |
|
60 | | -(x, y) = helpState.generateData(par, T, x0) |
| 64 | +x, y = generateData(theta, T, initialState) |
| 65 | + |
61 | 66 |
|
62 | 67 | ############################################################################## |
63 | 68 | # Parameter estimation using PMH |
64 | 69 | ############################################################################## |
65 | 70 |
|
66 | 71 | # The inital guess of the parameter |
67 | | -initPar = 0.50; |
| 72 | +initialPhi = 0.50 |
68 | 73 |
|
69 | | -# No. particles in the particle filter ( choose nPart ~ T ) |
70 | | -nPart = 500; |
| 74 | +# No. particles in the particle filter ( choose noParticles ~ T ) |
| 75 | +noParticles = 500 |
71 | 76 |
|
72 | | -# The length of the burn-in and the no. iterations of PMH ( nBurnIn < nRuns ) |
73 | | -nBurnIn = 1000; |
74 | | -nRuns = 5000; |
| 77 | +# The length of the burn-in and the no. iterations of PMH |
| 78 | +# ( noBurnInIterations < noIterations ) |
| 79 | +noBurnInIterations = 1000 |
| 80 | +noIterations = 5000 |
75 | 81 |
|
76 | 82 | # The standard deviation in the random walk proposal |
77 | | -stepSize = 0.10; |
| 83 | +stepSize = 0.10 |
78 | 84 |
|
79 | 85 | # Run the PMH algorithm |
80 | | -res = helpParam.pmh(y,initPar,par,nPart,T,x0,helpState.pf,nRuns,stepSize) |
| 86 | +res = particleMetropolisHastings(y, initialPhi, theta, noParticles, initialState, |
| 87 | + particleFilter, noIterations, stepSize) |
81 | 88 |
|
82 | 89 |
|
83 | 90 | ############################################################################## |
|
86 | 93 |
|
87 | 94 | # Plot the parameter posterior estimate |
88 | 95 | # Solid black line indicate posterior mean |
89 | | -plt.subplot(2,1,1); |
90 | | -plt.hist(res[nBurnIn:nRuns], np.floor(np.sqrt(nRuns-nBurnIn)), normed=1, facecolor='#7570B3') |
91 | | -plt.xlabel("par[0]"); plt.ylabel("posterior density estimate") |
92 | | -plt.axvline( np.mean(res[nBurnIn:nRuns]), linewidth=2, color = 'k' ) |
| 96 | +plt.subplot(2, 1, 1) |
| 97 | +plt.hist(res[noBurnInIterations:noIterations], np.floor( |
| 98 | + np.sqrt(noIterations - noBurnInIterations)), normed=1, facecolor='#7570B3') |
| 99 | +plt.xlabel("par[0]") |
| 100 | +plt.ylabel("posterior density estimate") |
| 101 | +plt.axvline(np.mean(res[noBurnInIterations:noIterations]), |
| 102 | + linewidth=2, color='k') |
93 | 103 |
|
94 | 104 | # Plot the trace of the Markov chain after burn-in |
95 | 105 | # Solid black line indicate posterior mean |
96 | | -plt.subplot(2,1,2); |
97 | | -plt.plot(np.arange(nBurnIn,nRuns,1),res[nBurnIn:nRuns],color = '#E7298A') |
98 | | -plt.xlabel("iteration"); plt.ylabel("par[0]") |
99 | | -plt.axhline( np.mean(res[nBurnIn:nRuns]), linewidth=2, color = 'k' ) |
| 106 | +plt.subplot(2, 1, 2) |
| 107 | +plt.plot(np.arange(noBurnInIterations, noIterations, 1), |
| 108 | + res[noBurnInIterations:noIterations], color='#E7298A') |
| 109 | +plt.xlabel("iteration") |
| 110 | +plt.ylabel("par[0]") |
| 111 | +plt.axhline(np.mean(res[noBurnInIterations:noIterations]), |
| 112 | + linewidth=2, color='k') |
| 113 | + |
100 | 114 |
|
101 | 115 | ############################################################################## |
102 | 116 | # End of file |
|
0 commit comments