1

我正在尝试使用 实现卡尔曼滤波器的简单应用程序Pykalman,但我在Pykalman软件包附带的 EM 算法的估计步骤上遇到错误。

它是基于模拟数据的具有时变系数的简单线性回归。下面的代码模拟数据并启动卡尔曼滤波器,但是当我尝试根据观察估计参数时,使用kf.em(Data),它返回错误:ValueError: object arrays are not supported

我做错了pykalman什么吗?

型号和完整代码如下。错误发生在代码的最后一行。

模型(小图)

问题描述

模型的状态空间表示

完整代码

import pandas as pd
import scipy as sp
import numpy as np

import matplotlib.pyplot as plt
import pylab as pl
from pykalman import KalmanFilter

# generates the data
Data = pd.DataFrame(columns=['NoiseAR','NoiseReg', 'x', 'beta', 'y'], index=range(1000))
Data['NoiseAR'] = np.random.normal(loc=0.0, scale=1.0, size=1000)
Data['NoiseReg'] = np.random.normal(loc=0.0, scale=1.0, size=1000)

for i in range(1000):
    if i==0:
        Data.loc[i, 'x'] = Data.loc[i, 'NoiseAR']
    else:
        Data.loc[i, 'x'] = 0.95*Data.loc[i-1, 'x'] + Data.loc[i, 'NoiseAR']

for i in range(1000):
    Data.loc[i, 'beta'] = np.sin(np.radians(i))

Data['y'] = Data['x']*Data['beta'] + Data['NoiseReg']

# set up the kalman filter
F = [1.]
H = Data['x'].values.reshape(1000,1,1)
Q = [2.]
R = [2.]

init_state_mean = [0.]
init_state_cov = [2.]

kf = KalmanFilter(
    transition_matrices=F, 
    observation_matrices=H, 
    transition_covariance=Q, 
    observation_covariance=R, 
    initial_state_mean=init_state_mean, 
    initial_state_covariance=init_state_cov, 
    em_vars=['transition_covariance', 'observation_covariance', 'initial_state_mean', 'initial_state_covariance']
)

# estimate the parameters from em_vars using the EM algorithm
kf = kf.em(Data['y'].values)
4

1 回答 1

2

我想到了!Data['y'].values是一个 numpy 数组dtype=object。我所要做的就是将数组的类型更改为使用.astype(float). 这必须对进入 的卡尔曼滤波器对象的所有内容完成pykalman,因此我还必须更改H矩阵的类型。

希望这对将来的人有所帮助!

这是最终工作代码的样子:

import pandas as pd
import scipy as sp
import numpy as np
import matplotlib.pyplot as plt
import pylab as pl
from pykalman import KalmanFilter

Data = pd.DataFrame(columns=['NoiseAR','NoiseReg', 'x', 'beta', 'y'], index=range(1000))

Data['NoiseAR'] = np.random.normal(loc=0.0, scale=1.0, size=1000)
Data['NoiseReg'] = np.random.normal(loc=0.0, scale=1.0, size=1000)
plt.plot(Data[['NoiseAR','NoiseReg']])
plt.show()

for i in range(1000):
    if i == 0:
        Data.loc[i, 'x'] = Data.loc[i, 'NoiseAR']
    else:
        Data.loc[i, 'x'] = 0.95 * Data.loc[i - 1, 'x'] + Data.loc[i, 'NoiseAR']

plt.plot(Data['x'])
plt.show()

for i in range(1000):
    Data.loc[i, 'beta'] = np.sin(np.radians(i))

plt.plot(Data['beta'])
plt.show()

Data['y'] = Data['x']*Data['beta'] + Data['NoiseReg']

plt.plot(Data[['x', 'y']])
plt.show()

F = [1.]
H = Data['x'].values.reshape(1000,1,1).astype(float)
Q = [2.]
R = [2.]

init_state_mean = [0.]
init_state_cov = [2.]

kf = KalmanFilter(
    transition_matrices=F,
    observation_matrices=H,
    transition_covariance=Q,
    observation_covariance=R,
    initial_state_mean=init_state_mean,
    initial_state_covariance=init_state_cov,
    em_vars=['transition_covariance', 'observation_covariance', 'initial_state_mean', 'initial_state_covariance']
)

kf = kf.em(Data['y'].values.astype(float))

filtered_state_estimates = kf.filter(Data['y'].values.astype(float))[0]
smoothed_state_estimates = kf.smooth(Data['y'].values.astype(float))[0]

pl.figure(figsize=(10, 6))
lines_true = pl.plot(Data['beta'].values, linestyle='-', color='b')
lines_filt = pl.plot(filtered_state_estimates, linestyle='--', color='g')
lines_smooth = pl.plot(smoothed_state_estimates, linestyle='-.', color='r')
pl.legend(
    (lines_true[0], lines_filt[0], lines_smooth[0]),
    ('true', 'filtered', 'smoothed')
)
pl.xlabel('time')
pl.ylabel('state')

pl.show()
于 2017-09-14T11:36:50.490 回答