In [1]:
# import function to simulate multivariate poisson process data
import simulatePLDS as plds
import numpy as np
import scipy as sp
In [2]:
# define process model parameters
A = np.diag([.8, .3])
print A
Sigma = .5*np.asarray([[1, .5], [.5, 1]])
# define measurement model parameters
B = np.diag([2, 2])
print B
# set time length and initial parameters
T = 50
x_0 = np.random.randn(1,2)[0]
In [3]:
# plot 2d observed (Y) and hidden (X) signal
import matplotlib.pyplot as plt
%matplotlib inline
[hidden, obs] = plds.simulateStateSpace(A,B,Sigma,T,x_0)
plt.subplots_adjust(right=1.85, hspace=.85)
In [4]:
B
Out[4]:
In [5]:
# import auxiliary particle filter code
from apf12 import *
n_particles = 500
In [6]:
# run particle filter
[w, x, k] = apf(obs, T, n_particles, A, B, Sigma, x_0)
In [7]:
# visualize parameters
import matplotlib.pyplot as plt
%matplotlib inline
#parts = np.array([np.array(xi) for xi in w])
plt.subplot(141)
plt.imshow(w)
plt.xlabel('time')
plt.ylabel('particle weights')
plt.title('weight matrix')
plt.subplot(142)
plt.imshow(x[:,:,0])
plt.xlabel('time')
plt.ylabel('particles')
plt.title('path matrix')
plt.subplot(143)
plt.imshow(x[:,:,1])
plt.xlabel('time')
plt.ylabel('particles')
plt.title('path matrix')
plt.subplot(144)
plt.imshow(k)
plt.xlabel('time')
plt.ylabel('p(y_n | x_{n-1})')
plt.title('posterior')
plt.subplots_adjust(right=2.5, hspace=.75)
In [8]:
# examine particle trajectories over time
plt.subplot(141)
plt.plot(np.transpose(x[:,:,0]), alpha=.01, linewidth=1.5)
plt.xlabel('time')
plt.ylabel('displacement')
plt.title('particle path trajectories over time (dim 1)')
plt.subplot(142)
plt.plot(np.transpose(x[:,:,1]), alpha=.01, linewidth=1.5)
plt.xlabel('time')
plt.ylabel('displacement')
plt.title('particle path trajectories over time (dim 2)')
plt.subplot(143)
plt.plot(x[:,:,0])
plt.xlabel('particle')
plt.ylabel('time')
plt.title('particle variance (dim 1)')
plt.subplot(144)
plt.plot(x[:,:,1])
plt.xlabel('particle')
plt.ylabel('time')
plt.title('particle variance (dim 2)')
plt.subplots_adjust(right=2.5, hspace=.85)
In [9]:
# average over particle trajectories to obtain predicted state means for APF output
predsignal1 = np.mean(x[:,:,0], axis=0)
predsignal2 = np.mean(x[:,:,1], axis=0)
In [10]:
hidden[:,0]
Out[10]:
In [11]:
# check true values against standard kalman filter output
time = np.arange(T)
#plt.subplot(121)
#lo = plt.plot(time, hidden, 'r', time, filtered_state_means, 'b')
#plt.xlabel('time')
#plt.ylabel('signal')
#plt.title('kalman filter')
#plt.legend(lo, ('true value','prediction'))
plt.subplot(121)
plt.title('apf')
lo = plt.plot(time, hidden[:,0], 'r', time, predsignal1, 'b')
plt.xlabel('time')
plt.ylabel('signal')
plt.legend(lo, ('true value','prediction'))
plt.subplot(122)
plt.title('apf')
lo = plt.plot(time, hidden[:,1], 'r', time, predsignal2, 'b')
plt.xlabel('time')
plt.ylabel('signal')
plt.legend(lo, ('true value','prediction'))
plt.subplots_adjust(right=1.5, hspace=.75)
In [12]:
# examine particle trajectories over time
plt.subplot(141)
plt.plot(np.transpose(x[:,:,0]), alpha=.01, linewidth=1.5)
plt.xlabel('time')
plt.ylabel('displacement')
plt.title('particle path trajectories over time (dim 1)')
plt.subplot(142)
plt.plot(np.transpose(x[:,:,1]), alpha=.01, linewidth=1.5)
plt.xlabel('time')
plt.ylabel('displacement')
plt.title('particle path trajectories over time (dim 2)')
plt.subplot(143)
plt.title('apf (dimension 1)')
lo = plt.plot(time, hidden[:,0], 'r', time, predsignal1, 'b')
plt.xlabel('time')
plt.ylabel('signal')
plt.legend(lo, ('true value','prediction'))
plt.subplot(144)
plt.title('apf (dimension 2)')
lo = plt.plot(time, hidden[:,1], 'r', time, predsignal2, 'b')
plt.xlabel('time')
plt.ylabel('signal')
plt.legend(lo, ('true value','prediction'))
plt.subplots_adjust(right=2.5, hspace=.95)
In [13]:
from pykalman import KalmanFilter
# run kalman filter and check parameters
#print A, B
kf = KalmanFilter(transition_matrices = A, observation_matrices = B)
kf = kf.em(obs, n_iter=50)
(filtered_state_means, filtered_state_covariances) = kf.filter(obs)
(smoothed_state_means, smoothed_state_covariances) = kf.smooth(obs)
In [14]:
# check true values against standard kalman filter output
plt.subplot(221)
lo = plt.plot(time, hidden[:,0], 'r', time, filtered_state_means[:,0], 'b')
plt.xlabel('time')
plt.ylabel('signal')
plt.title('kalman filter (dim 1)')
plt.legend(lo, ('true value','prediction'), loc='lower left')
#plt.plot(filtered_state_means[:,0])
plt.subplot(223)
plt.title('apf (dim 1)')
lo = plt.plot(time, hidden[:,0], 'r', time, predsignal1, 'b')
plt.xlabel('time')
plt.ylabel('signal')
plt.legend(lo, ('true value','prediction'), loc='lower left')
plt.subplots_adjust(right=1.5, hspace=.75)
plt.subplot(222)
lo = plt.plot(time, hidden[:,1], 'r', time, filtered_state_means[:,1], 'b')
plt.xlabel('time')
plt.ylabel('signal')
plt.title('kalman filter (dim 2)')
plt.legend(lo, ('true value','prediction'), loc='lower left')
#plt.plot(filtered_state_means[:,0])
plt.subplot(224)
plt.title('apf (dim 2)')
lo = plt.plot(time, hidden[:,1], 'r', time, predsignal2, 'b')
plt.xlabel('time')
plt.ylabel('signal')
plt.legend(lo, ('true value','prediction'), loc='lower left')
plt.subplots_adjust(right=1.75, hspace=.85)