1. 状态空间模型
状态空间模型是动态时域模型,以隐含着的时间为自变量。状态空间模型在经济时间序列分析中的应用正在迅速增加。其中应用较为普遍的状态空间模型是由Akaike提出并由Mehra进一步发展而成的典型相关(canonical correlation)方法。
状态空间模型的假设条件是动态系统符合马尔科夫特性,即给定系统的现在状态,则系统的将来与其过去独立。
状态空间模型具有如下特点:
- 1、状态空间模型不仅能反映系统内部状态,而且能揭示系统内部状态与外部的输入和输出变量的联系。
- 2、状态空间模型将多个变量时间序列处理为向量时间序列,这种从变量到向量的转变更适合解决多输入输出变量情况下的建模问题。
- 3、状态空间模型能够用现在和过去的最小心信息形式描述系统的状态,因此,它不需要大量的历史数据资料,既省时又省力。
基于状态空间模型的时间序列预测的优点:
- 优点一:状态空间模型是一种结构模型,基于状态空间分解模型的时间序列预测,便于分析者利用存在的统计理论对模型进行统计检验。
- 优点二:状态空间模型求解算法的核心是Kalman滤波,Kalman滤波是在时刻t基于所有可得到的信息计算状态向量的最理想的递推过程。当扰动项和初始状态向量服从正态分布时,Kalman滤波能够通过预测误差分解计算似然函数,从而可以对模型中的所有未知参数进行估计,并且当新的观测值一旦得到,就可以利用Kalman滤波连续地修正状态向量的估计。
2. 粒子滤波
2.1 概念
学习文章链接:
(1)https://blog.csdn.net/setella/article/details/82912604
(2)https://blog.csdn.net/guo1988kui/article/details/82778293
粒子滤波技术在非线性、非高斯系统表现出来的优越性,决定了它的应用范围非常广泛。另外,粒子滤波器的多模态处理能力,也是它应用广泛的原因之一。国际上,粒子滤波已被应用于各个领域。在经济学领域,它被应用在经济数据预测;在军事领域已经被应用于雷达跟踪空中飞行物,空对空、空对地的被动式跟踪;在交通管制领域它被应用在对车或人视频监控;它还用于机器人的全局定位。
粒子滤波的缺点:
虽然粒子滤波算法可以作为解决SLAM问题的有效手段,但是该算法仍然存在着一些问题。其中最主要的问题是需要用大量的样本数量才能很好地近似系统的后验概率密度。机器人面临的环境越复杂,描述后验概率分布所需要的样本数量就越多,算法的复杂度就越高。因此,能够有效地减少样本数量的自适应采样策略是该算法的重点。另外,重采样阶段会造成样本有效性和多样性的损失,导致样本贫化现象。如何保持粒子的有效性和多样性,克服样本贫化,也是该算法研究重点。
2.2 粒子滤波算法原理
粒子滤波是采用蒙特卡洛方法求解贝叶斯估计中的最优估计,并利用重要性采样方法在状态空间上得到一组不断更新的随机样本(称为粒子),这一组粒子对应着一组权值。通过不停的按照权值大小来更新系统中的粒子并更新权值,来逼近需要估计的系统状态。算法步骤主要分为如下几步:
(1)粒子初始化:由于对系统状态未知,所以我们认为粒子在系统的状态空间中均匀分布,初始化生成粒子。然后将所有采样输入状态转移方程,得到预测粒子。
(2)粒子预测阶段:粒子滤波根据上一时刻确定的后验概率分布,通过随机采样的方法对每一个粒子的值进行更新,再将更新过的粒子输入状态转移方程,得到一组预测值,通过这组预测值的加权组合得到该时刻的预测结果。
(3)权值更新阶段:在获取一组粒子产生的预测值后,对比该时刻真实的观测值,通过观测方程对预测值进行评价。即第i个粒子输入观测方程后能得到真实观测值的概率,令这个概率为该粒子的权重,越可能获得真实观测值的粒子对应的权重就越高,也就代表该粒子越符合真实的概率分布。
(4)粒子重采样:为了避免粒子退化的现象,在算法迭代步骤中,需要去除权值较低的粒子,对权值较高的粒子进行复制,使得粒子的分布位置更逼近真实的解。在下一次的滤波过程中,使用重采样之后的粒子,使得每一轮滤波都让粒子更符合真实状态的概率分布,再将粒子带入状态转移方程中进行预测,从而使得预测的结果更准确。
如图4-3所示,如此反复迭代上述几个阶段,将得到状态转移方程的最优估计,即我们需要的预测值。
2.3 局限性
对于粒子滤波来说,预测过程的实现必须依赖于系统指定的状态转移方程和观测方程,但是现金流无法建立估计式模型。若随机初始化粒子,则无法实现预测,如下图所示:
因此,使用粒子滤波,必须提供估计式,或者与其他算法结合使用:
- xk与xk-1、xk与yk的关系,建立固定方程式;
- 与神经网络、SVM等算法结合,使用算法的预测结果作为粒子,不同参数的NN预测结果 = 不同的粒子。
与神经网络、SVM等算法结合本质:集成算法,基学习器是NN,通过粒子权值更新来求各个NN的权重
- 状态转移方程 = 神经网络预测过程
- 预测过程:神经网络预测,作为粒子预测
- 更新过程:使用观测值,调整各个NN的权重
3. 代码实现
import pandas as pd
import numpy as np
import math
import functools
import matplotlib.pyplot as plt
x = 0.1 # initial actual state
x_N = 1 # 系统过程噪声的协方差(由于是一维的,这里就是方差)
x_R = 1 # 测量的协方差
T = 75 # 共进行75次
N = 100 # 粒子数,越大效果越好,计算量也越大
# initilize our initial, prior particle distribution as a gaussian around the true initial value
V = 2 # 初始分布的方差
x_P = np.zeros(N) # 粒子
# 1.用一个高斯分布随机的产生初始的粒子
for i in range(N):
x_P[i] = x + np.sqrt(V) * np.random.randn()
z_out = [x ** 2 / 20 + np.sqrt(x_R) ** np.random.randn()] # 实际测量值
x_out = [x] # the actual output vector for measurement values.测量值的实际输出矢量
x_est = [x] # time by time output of the particle filters estimate 粒子滤波估计的逐时输出
x_est_out = [x] # the vector of particle filter estimates. 粒子滤波估计的向量
# 重采样
def hinstc(listname, n):
ran_w = np.random.rand(n)
dd = []
for i in ran_w:
j = 0
while i > listname[j]:
if i < listname[j + 1]:
break
else:
j += 1
dd.append(j + 1)
return dd
x_P_update = np.zeros(N)
z_update = np.zeros(N)
P_w = np.zeros(N)
for t in range(T):
x = 0.5 * x + 25 * x / (1 + x ** 2) + 8 * np.cos(1.2 * (t - 1)) + np.sqrt(x_N) * np.random.randn()
z = x ** 2 / 20 + np.sqrt(x_R) * np.random.randn()
# 2.权值计算
for i in range(N):
x_P_update[i] = 0.5 * x_P[i] + 25 * x_P[i] / (1 + x_P[i] ** 2) + 8 * np.cos(1.2 * (t - 1)) + np.sqrt(x_N) * np.random.randn()
# 计算采样粒子的值,为后面根据似然去计算权重做铺垫
z_update[i] = x_P_update[i]** 2 / 20
# 对每个粒子计算其权重,这里假设量测噪声是高斯分布。所以w = p(y | x) 对应下面的计算公式
P_w[i] = (1 / np.sqrt(2 * np.pi * x_R)) * np.exp(-(z - z_update[i]) ** 2 / (2 * x_R))
# 归一化.
P_w = P_w / sum(P_w)
# 3.重采样 Resampling
cum = np.random.rand(N)
for j in range(N):
# reduce 累加
cum[j] = functools.reduce(lambda x, y: x + y, P_w[:j + 1])
dd = hinstc(cum, N)
for j in range(N):
x_P[j] = x_P_update[dd[j]]
# 状态估计,重采样以后,每个粒子的权重都变成了1 / N
x_est = np.mean(x_P)
# Save data in arrays for later plotting
x_out.append(x) # 真实值
z_out.append(z)
x_est_out.append(x_est) # 预测值
plt.figure()
plt.plot(x_out, label='true')
plt.plot(x_est_out, label='pre')
plt.legend()
plt.show()
结果如下:
参考:https://blog.csdn.net/heyijia0327/article/details/41142679