I'm experimenting with the
pykalman Python library to learn about Kalman Filters. In the code below, I'm generating a random walk where each step is the last step multiplied by 1 plus some noise:
1 + std_dev. In the first block, the covariance matrix of the KF (using a 1D signal/state, so it's really just one variance) appears to converge to about
0.62. Even if I set
grow_std_dev=True, causing the noise to grow significantly over time, the covariance matrix still converges to this value.
import numpy as np import matplotlib.pyplot as plt from pykalman import KalmanFilter def generate_random_walk(seed=1, n_steps=100, grow_std_dev=False): np.random.seed(seed) rand_walk =  std_devs =  for n in range(n_steps): if grow_std_dev: std_dev = np.random.normal(0,0.01 * (1 + n)) else: std_dev = np.random.normal(0,0.01) val = rand_walk[-1] * (1 + std_dev) std_devs.append(std_dev) rand_walk.append(val) return np.array(rand_walk), np.array(std_devs) kf = KalmanFilter(transition_matrices = , observation_matrices = , initial_state_mean = 1, initial_state_covariance = 1, observation_covariance=1, transition_covariance=1) rand_walk, std_devs = generate_random_walk(0) state_means, state_cov = kf.filter(rand_walk) plt.plot(std_devs) plt.show() plt.plot(rand_walk_1) plt.show() plt.plot(state_cov.flatten())
The plots produced by the above code:
I read elsewhere that KFs can be used to perform recursive linear regression (I believe this is the correct term) between two variables by passing one variable for the
observation_matrices argument and the other as the value to filter. So in the block below, I'm generating a second random walk with a different seed and passing that for
observation_matrices rather than the fixed matrix of
 as in the first block. Unlike the first example, this results in a covariance matrix that does not converge.
rand_walk_2, _ = generate_random_walk(1) kf = KalmanFilter(transition_matrices = , observation_matrices = rand_walk_2[:,None,None], initial_state_mean = 1, initial_state_covariance = 1, observation_covariance=1, transition_covariance=1) state_means, state_cov = kf.filter(rand_walk_1) plt.plot(rand_walk_2) plt.show() plt.plot(state_cov.flatten())
I'm really not as concerned with the second example other than to show that it's possible for the covariance matrix to not converge. In learning about Kalman Filters, my understanding was that part of the value is that the uncertainty of the estimate is quantified at each time step, i.e., that the covariance matrix is evolving with the state estimate. Again, by setting
grow_std_dev=True, I would expect that the covariance matrix would need to change for the filter to make optimal predictions.
With that said, I'm wondering if I'm missing something about how KFs are supposed to work, missing an argument, or otherwise.
Any help is appreciated.