我正在尝试使用pykalman
Python 库来了解卡尔曼滤波器。在下面的代码中,我正在生成一个随机游走,其中每一步都是最后一步乘以 1 加上一些噪声:1 + std_dev
。在第一个块中,KF 的协方差矩阵(使用一维信号/状态,所以它实际上只是一个方差)似乎收敛到大约0.62
. 即使我设置grow_std_dev=True
,导致噪声随时间显着增长,协方差矩阵仍会收敛到该值。
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 = [1]
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 = [1],
observation_matrices = [1],
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())
上述代码产生的图:
我在其他地方读到,KF 可用于在两个变量之间执行递归线性回归(我相信这是正确的术语),方法是传递一个变量作为observation_matrices
参数,另一个作为过滤值。因此,在下面的块中,我使用不同的种子生成第二个随机游走,并将其传递给observation_matrices
而不是[1]
第一个块中的固定矩阵。与第一个示例不同,这会导致协方差矩阵不收敛。
rand_walk_2, _ = generate_random_walk(1)
kf = KalmanFilter(transition_matrices = [1],
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())
除了表明协方差矩阵可能不收敛之外,我真的不关心第二个示例。在学习卡尔曼滤波器时,我的理解是,部分价值在于估计的不确定性在每个时间步被量化,即协方差矩阵随着状态估计而发展。同样,通过设置grow_std_dev=True
,我希望协方差矩阵需要更改才能使滤波器做出最佳预测。
话虽如此,我想知道我是否遗漏了一些关于 KF 应该如何工作的内容,遗漏了一个论点,或者其他。
任何帮助表示赞赏。