EM-алгоритм с Pykalman

Я пытаюсь реализовать простое приложение фильтра Калмана с использованием Pykalman, но получаю сообщение об ошибке на шаге оценки алгоритма EM, который поставляется с пакетом Pykalman.

Это простая линейная регрессия с изменяющимся во времени коэффициентом, основанная на смоделированных данных. Код ниже имитирует данные и запускает фильтр Калмана, но когда я пытаюсь оценить параметры на основе наблюдений, используя 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)

person Gustavo Amarante    schedule 13.09.2017    source источник


Ответы (1)


Я понял! Data['y'].values - это пустой массив с dtype=object. Все, что мне нужно было сделать, это изменить тип массива на float с помощью .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()
person Gustavo Amarante    schedule 14.09.2017