使用 Pykalman 的 EM 算法
EM-Algorithm with Pykalman
我正在尝试使用 Pykalman
实现卡尔曼滤波器的简单应用程序,但我在 Pykalman
包附带的 EM 算法的估计步骤中遇到错误。
它是一种基于模拟数据的具有时变系数的简单线性回归。下面的代码模拟数据并启动卡尔曼滤波器,但是当我尝试根据观察结果估计参数时,使用 kf.em(Data)
,它 returns 错误:ValueError: object arrays are not supported
.
我在 pykalman
上做错了吗?
模型和完整代码如下。错误发生在代码的最后一行。
模型(小图片)
Description of the problem
State-Space representation of the model
完整代码
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)
我想通了! Data['y'].values
是一个带有 dtype=object
的 numpy 数组。我所要做的就是使用 .astype(float)
将数组类型更改为 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()
我正在尝试使用 Pykalman
实现卡尔曼滤波器的简单应用程序,但我在 Pykalman
包附带的 EM 算法的估计步骤中遇到错误。
它是一种基于模拟数据的具有时变系数的简单线性回归。下面的代码模拟数据并启动卡尔曼滤波器,但是当我尝试根据观察结果估计参数时,使用 kf.em(Data)
,它 returns 错误:ValueError: object arrays are not supported
.
我在 pykalman
上做错了吗?
模型和完整代码如下。错误发生在代码的最后一行。
模型(小图片)
Description of the problem
State-Space representation of the model
完整代码
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)
我想通了! Data['y'].values
是一个带有 dtype=object
的 numpy 数组。我所要做的就是使用 .astype(float)
将数组类型更改为 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()