我正在查看示例中显示的pykalman的KalmanFilter:
我想知道
observation_covariance=100,
vs
observation_covariance=1,
文档说明
observation_covariance R: e(t)^2 ~ Gaussian (0, R)
如何正确设置值?
此外,是否可以在上述模块中应用没有截距的卡尔曼滤波器?
答案 0 :(得分:1)
观察协方差显示您在输入数据中假设的误差。卡尔曼滤波器在正态分布数据上工作正常。在此假设下,您可以使用3-Sigma规则根据观察中的最大误差计算观察的协方差(在本例中为方差)。
您问题中的值可以解释如下:
示例1
observation_covariance = 100
sigma = sqrt(observation_covariance) = 10
max_error = 3*sigma = 30
示例2
observation_covariance = 1
sigma = sqrt(observation_covariance) = 1
max_error = 3*sigma = 3
因此您需要根据观察数据选择值。 观察越准确,观察协方差越小。
另一点:你可以通过操纵协方差来调整过滤器,但我认为这不是一个好主意。观察协方差值越高,新观察对过滤器状态的影响越小。
对不起,我不明白你问题的第二部分(关于没有拦截的卡尔曼滤波器)。你能解释一下你的意思吗? 您正在尝试使用回归模型,拦截和斜率都属于它。
<强> --------------------------- 强>
<强>更新强>
我准备了一些代码和情节来详细回答你的问题。我使用EWC和EWA历史数据来保持接近原始文章。
首先,这里是代码(与上面示例中的代码相同,但使用不同的符号)
from pykalman import KalmanFilter
import numpy as np
import matplotlib.pyplot as plt
# reading data (quick and dirty)
Datum=[]
EWA=[]
EWC=[]
for line in open('data/dataset.csv'):
f1, f2, f3 = line.split(';')
Datum.append(f1)
EWA.append(float(f2))
EWC.append(float(f3))
n = len(Datum)
# Filter Configuration
# both slope and intercept have to be estimated
# transition_matrix
F = np.eye(2) # identity matrix because x_(k+1) = x_(k) + noise
# observation_matrix
# H_k = [EWA_k 1]
H = np.vstack([np.matrix(EWA), np.ones((1, n))]).T[:, np.newaxis]
# transition_covariance
Q = [[1e-4, 0],
[ 0, 1e-4]]
# observation_covariance
R = 1 # max error = 3
# initial_state_mean
X0 = [0,
0]
# initial_state_covariance
P0 = [[ 1, 0],
[ 0, 1]]
# Kalman-Filter initialization
kf = KalmanFilter(n_dim_obs=1, n_dim_state=2,
transition_matrices = F,
observation_matrices = H,
transition_covariance = Q,
observation_covariance = R,
initial_state_mean = X0,
initial_state_covariance = P0)
# Filtering
state_means, state_covs = kf.filter(EWC)
# Restore EWC based on EWA and estimated parameters
EWC_restored = np.multiply(EWA, state_means[:, 0]) + state_means[:, 1]
# Plots
plt.figure(1)
ax1 = plt.subplot(211)
plt.plot(state_means[:, 0], label="Slope")
plt.grid()
plt.legend(loc="upper left")
ax2 = plt.subplot(212)
plt.plot(state_means[:, 1], label="Intercept")
plt.grid()
plt.legend(loc="upper left")
# check the result
plt.figure(2)
plt.plot(EWC, label="EWC original")
plt.plot(EWC_restored, label="EWC restored")
plt.grid()
plt.legend(loc="upper left")
plt.show()
我无法使用pandas检索数据,所以我下载了它们并从file读取。
在这里你可以看到估计的斜率和截距:
为了测试估计数据,我使用估计的参数从EWA恢复了EWC值:
关于观察协方差值
通过改变观察协方差值,您可以告诉过滤器输入数据的准确程度(通常您只是使用一些数据表或您对系统的了解来描述您对观察的信心)。
以下是使用不同观察协方差值的估计参数和恢复的EWC值:
您可以看到过滤器更好地遵循原始功能,具有更大的观察信心(较小的R)。如果置信度较低(R值较大),则滤波器会非常缓慢地保留初始估计值(斜率= 0,截距= 0),并且恢复的函数远离原始值。
关于冻结拦截
如果由于某种原因想要冻结截距,则需要更改整个模型和所有滤镜参数。
在正常情况下我们有:
x = [slope; intercept] #estimation state
H = [EWA 1] #observation matrix
z = [EWC] #observation
现在我们有:
x = [slope] #estimation state
H = [EWA] #observation matrix
z = [EWC-const_intercept] #observation
结果:
以下是代码:
from pykalman import KalmanFilter
import numpy as np
import matplotlib.pyplot as plt
# only slope has to be estimated (it will be manipulated by the constant intercept) - mathematically incorrect!
const_intercept = 10
# reading data (quick and dirty)
Datum=[]
EWA=[]
EWC=[]
for line in open('data/dataset.csv'):
f1, f2, f3 = line.split(';')
Datum.append(f1)
EWA.append(float(f2))
EWC.append(float(f3))
n = len(Datum)
# Filter Configuration
# transition_matrix
F = 1 # identity matrix because x_(k+1) = x_(k) + noise
# observation_matrix
# H_k = [EWA_k]
H = np.matrix(EWA).T[:, np.newaxis]
# transition_covariance
Q = 1e-4
# observation_covariance
R = 1 # max error = 3
# initial_state_mean
X0 = 0
# initial_state_covariance
P0 = 1
# Kalman-Filter initialization
kf = KalmanFilter(n_dim_obs=1, n_dim_state=1,
transition_matrices = F,
observation_matrices = H,
transition_covariance = Q,
observation_covariance = R,
initial_state_mean = X0,
initial_state_covariance = P0)
# Creating the observation based on EWC and the constant intercept
z = EWC[:] # copy the list (not just assign the reference!)
z[:] = [x - const_intercept for x in z]
# Filtering
state_means, state_covs = kf.filter(z) # the estimation for the EWC data minus constant intercept
# Restore EWC based on EWA and estimated parameters
EWC_restored = np.multiply(EWA, state_means[:, 0]) + const_intercept
# Plots
plt.figure(1)
ax1 = plt.subplot(211)
plt.plot(state_means[:, 0], label="Slope")
plt.grid()
plt.legend(loc="upper left")
ax2 = plt.subplot(212)
plt.plot(const_intercept*np.ones((n, 1)), label="Intercept")
plt.grid()
plt.legend(loc="upper left")
# check the result
plt.figure(2)
plt.plot(EWC, label="EWC original")
plt.plot(EWC_restored, label="EWC restored")
plt.grid()
plt.legend(loc="upper left")
plt.show()