想象一艘在浓雾中航行的船。它的 GPS 含有噪声,洋流未知,且无法直接测量其精确位置,只能通过传感器读数近似推断。状态空间模型正是为这种问题而生:您关心的量是隐藏的,而您能获得的只是它的不完美测量。
本文将介绍状态空间模型的结构,如何通过滤波与平滑估计隐藏状态,卡尔曼滤波在其中的位置,以及如何在 Python 和 R 中实现这些模型。
什么是状态空间模型?
状态空间模型是一个数学框架,用于描述随时间变化且无法直接观测的系统。核心有两个量: 状态 ,即在任一时刻真实刻画系统的底层信息;以及 观测 ,即您实际获得的带噪声、间接的测量。
模型规定两件事:隐藏状态如何从一个时间步演化到下一个,以及隐藏状态如何生成您看到的观测。这种分离使该框架具备通用性。它广泛出现于信号处理、计量经济学、控制系统与机器学习中,往往人们没有意识到自己都在同一形式结构内工作。
状态空间模型如何工作
核心逻辑在每个时间步遵循一个简单序列:
前一状态 → 当前状态 → 观测
系统从之前的隐藏状态转移到新的状态。该转移可能包含随机性,因为真实系统并非完全可预测。随后,新状态会生成一个可观测的测量,该测量自带噪声。您从未直接看到状态,只能看到它不完美地产生的结果。
您能 做的是利用每一个新观测来更新对隐藏状态的最佳估计。这就是推断问题,也是围绕状态空间模型的大多数算法机制要解决的事情。
隐藏状态随时间生成带噪声的观测。图片由作者提供。
状态方程与观测方程
模型的结构归结为两个方程:一个描述状态如何运动,一个描述您能测到什么。
状态方程
状态方程描述隐藏状态如何演化。标量形式为:
这里, z ₜ 是当前隐藏状态, a 表示转移动力学(前一状态延续的强度),而 wₜ 是过程噪声——系统运动中的随机性。在多变量系统的矩阵形式下, a 变为转移矩阵,但思想完全相同。
观测方程
观测方程将隐藏状态与您测得的量相连:
yₜ 是观测到的测量值, c 定义观测关系, vₜ 是测量噪声。在考虑一般的矩阵形式之前,先从这样的标量版本入手。矩阵带来的是通用性,而非新思想。
一个简单的状态空间模型示例
想一辆在道路上行驶的汽车。其真实位置与速度是隐藏状态,您无法直接观测。您拥有的是带噪声的 GPS 读数。状态方程刻画位置与速度在时间步之间如何变化(汽车大致以相同速度前进)。观测方程将真实位置与可能有数米误差的 GPS 读数关联起来。
一个好的可视化会显示三条线:真实位置(平滑)、GPS 读数(围绕真值分散)以及模型的估计位置(接近真值,较原始 GPS 更平滑)。获得第三条线正是模型的全部工作。
如何估计状态
定义模型只是问题的一半,您还需要从现有观测中推断隐藏状态。三项任务覆盖了这一空间:
滤波 仅使用截至当前的观测来估计当前状态——实时推断,适用于跟踪与控制。 平滑 利用给定时点前后全部观测来回溯修正估计——通常更准确,但需要完整序列。 预测 在观测到来之前向前外推估计未来状态。
大多数应用使用滤波。平滑适用于回顾性分析,当准确性比速度更重要时会用到。
卡尔曼滤波与状态空间模型
卡尔曼滤波是线性高斯状态空间模型中的滤波算法。需要精确区分:状态空间模型是模型本身;卡尔曼滤波是适用于其中某一类模型的推断方法。
该滤波以两个交替步骤运行。在 预测步骤 中,它使用状态方程将当前估计向前投射,同时给出该估计的不确定度量。在 更新步骤 中,新观测到来并修正估计。修正幅度取决于预测与测量各自的不确定性:若模型预测更可靠,观测的影响更小;若 GPS 信号干净而模型不确定,观测将占主导。这种按不确定性加权的融合让卡尔曼滤波在实践中奏效。
对于非线性或非高斯情形存在扩展:扩展卡尔曼滤波对动力学做线性化,无迹卡尔曼滤波采用更聪明的近似,而粒子滤波通过采样处理完全通用的情形。这些属于另一个话题。
状态空间模型的类型
根据您对动力学与噪声所愿意作出的假设不同,该框架涵盖多种设置。
线性高斯状态空间模型 是经典设置:线性的转移与观测方程,高斯噪声。可直接应用卡尔曼滤波,且精确推断可行。
非线性状态空间模型 在状态转移或观测关系不线性时出现——如单摆,或价格效应逐渐减弱的模型。此时不再存在精确推断。
非高斯状态空间模型 放弃噪声服从正态分布的假设。计数数据、二元结果与重尾过程皆属此类。
状态空间模型与相关时间序列模型的对比
有必要明确比较几点,因为它们之间的边界比初看时更模糊。
状态空间模型 vs. ARIMA
ARIMA 直接对观测值及其过去误差建模,不引入任何隐藏状态。状态空间模型则显式引入潜在状态。话虽如此,ARIMA 可以改写为状态空间形式——因此两者并非如初看那般泾渭分明,软件在拟合 ARIMA 时往往也会在内部使用状态空间表示。
状态空间模型 vs. 隐马尔可夫模型
二者都包含隐藏状态。经典 HMM 使用离散潜在状态(系统处于 k 种模式之一),而大多数状态空间模型采用连续状态。用于语音识别时,离散模式更合理;用于跟踪物体运动时,连续状态更自然。
状态空间模型 vs. 结构性时间序列模型
结构性时间序列模型(将序列分解为趋势、季节性与不规则成分)通常是 以 状态空间模型来表述的,而不是与其竞争。它们是该框架的特定用例。
Python 与 R 中的状态空间模型
两种语言的流程类似——定义模型、拟合模型,并提取隐藏状态的估计。
Python 中的状态空间模型
statsmodels 库为拟合状态空间模型提供了简洁接口。以下是在一些时间序列数据上拟合局部水平模型(最简单的结构性模型,状态为随机游走,观测含噪声):
import statsmodels. api as sm
model = sm. tsa. UnobservedComponents( time_series, level= 'local level' )
result = model. fit( disp= False )
print ( result. filtered_state[ 0 ] )
forecast = result. forecast( 10 ) 技术支持
滤波后的状态为您提供模型在各时点对隐藏水平的最佳估计。这才是您最关心的输出,而非参数本身。
R 中的状态空间模型
在 R 中,KFAS 包可处理高斯状态空间模型,如果您经常在这一领域工作,值得掌握。流程与 Python 相仿:定义模型对象、拟合,并提取平滑或滤波后的状态。解读隐藏状态估计,而不仅仅是拟合统计量。
library( KFAS)
model <- SSModel( time_series ~ SSMtrend( 1 , Q = NA ) , H = NA )
fit <- fitSSM( model, inits = c( log( 1 ) , log( 1 ) ) )
out <- KFS( fit$ model)
out$ att
predict( fit$ model, n.ahead = 10 ) 技术支持
状态空间模型的优势与局限
与大多数建模框架相似,其优劣同源:您必须事先承诺一种结构。
优势: 它们不是掩盖隐藏过程,而是将其显式表示;它们天然处理随时间变化的系统;测量不确定性内生于模型,而非事后考虑;同一框架无需改变模型结构即可支持滤波、平滑与预测。
局限: 指定模型可能很难。您需要决定隐藏状态意味着什么以及如何演化,这需要真正的领域判断。对于非线性或非高斯系统,推断成本会很高。而且如果您对动力学或噪声的假设有误,估计结果也会以不总是显而易见的方式出错。
结语
状态空间模型描述两件事:不可观测的状态如何随时间演化,以及该状态如何生成您可测得的观测。这分别是状态方程与观测方程。其他内容(卡尔曼滤波、平滑、预测)都是关于如何根据数据推断隐藏状态。
我认为该框架的价值在于,它迫使您明确自己不知道的部分。与直接对观测建模(如 ARIMA)不同,您必须承诺一个关于底层过程的故事。这是一种约束,也是一种澄清。一旦写下您认为的隐藏状态及其运动方式,推断问题就变成了机械过程。最难的部分早已在建模时完成。
如果您来自经典时间序列方法领域,值得把状态空间模型作为独立方法来理解,而非仅视作已知方法的推广。我们的 Python 时间序列课程 涵盖更广泛的工具包;若您的下一站是隐马尔可夫模型或卡尔曼滤波,这里的概念基础可直接迁移。
想象一艘在浓雾中航行的船。它的 GPS 含有噪声,洋流未知,且无法直接测量其精确位置,只能通过传感器读数近似推断。状态空间模型正是为这种问题而生:您关心的量是隐藏的,而您能获得的只是它的不完美测量。
本文将介绍状态空间模型的结构,如何通过滤波与平滑估计隐藏状态,卡尔曼滤波在其中的位置,以及如何在 Python 和 R 中实现这些模型。
什么是状态空间模型?
状态空间模型是一个数学框架,用于描述随时间变化且无法直接观测的系统。核心有两个量:状态,即在任一时刻真实刻画系统的底层信息;以及观测,即您实际获得的带噪声、间接的测量。
模型规定两件事:隐藏状态如何从一个时间步演化到下一个,以及隐藏状态如何生成您看到的观测。这种分离使该框架具备通用性。它广泛出现于信号处理、计量经济学、控制系统与机器学习中,往往人们没有意识到自己都在同一形式结构内工作。
状态空间模型如何工作
核心逻辑在每个时间步遵循一个简单序列:
前一状态 → 当前状态 → 观测
系统从之前的隐藏状态转移到新的状态。该转移可能包含随机性,因为真实系统并非完全可预测。随后,新状态会生成一个可观测的测量,该测量自带噪声。您从未直接看到状态,只能看到它不完美地产生的结果。
您能做的是利用每一个新观测来更新对隐藏状态的最佳估计。这就是推断问题,也是围绕状态空间模型的大多数算法机制要解决的事情。
隐藏状态随时间生成带噪声的观测。图片由作者提供。
状态方程与观测方程
模型的结构归结为两个方程:一个描述状态如何运动,一个描述您能测到什么。
状态方程
状态方程描述隐藏状态如何演化。标量形式为:
这里,zₜ 是当前隐藏状态,a 表示转移动力学(前一状态延续的强度),而 wₜ 是过程噪声——系统运动中的随机性。在多变量系统的矩阵形式下,a 变为转移矩阵,但思想完全相同。
观测方程
观测方程将隐藏状态与您测得的量相连:
yₜ 是观测到的测量值,c 定义观测关系,vₜ 是测量噪声。在考虑一般的矩阵形式之前,先从这样的标量版本入手。矩阵带来的是通用性,而非新思想。
一个简单的状态空间模型示例
想一辆在道路上行驶的汽车。其真实位置与速度是隐藏状态,您无法直接观测。您拥有的是带噪声的 GPS 读数。状态方程刻画位置与速度在时间步之间如何变化(汽车大致以相同速度前进)。观测方程将真实位置与可能有数米误差的 GPS 读数关联起来。
一个好的可视化会显示三条线:真实位置(平滑)、GPS 读数(围绕真值分散)以及模型的估计位置(接近真值,较原始 GPS 更平滑)。获得第三条线正是模型的全部工作。
如何估计状态
定义模型只是问题的一半,您还需要从现有观测中推断隐藏状态。三项任务覆盖了这一空间:
滤波仅使用截至当前的观测来估计当前状态——实时推断,适用于跟踪与控制。平滑利用给定时点前后全部观测来回溯修正估计——通常更准确,但需要完整序列。预测在观测到来之前向前外推估计未来状态。
大多数应用使用滤波。平滑适用于回顾性分析,当准确性比速度更重要时会用到。
卡尔曼滤波与状态空间模型
卡尔曼滤波是线性高斯状态空间模型中的滤波算法。需要精确区分:状态空间模型是模型本身;卡尔曼滤波是适用于其中某一类模型的推断方法。
该滤波以两个交替步骤运行。在预测步骤中,它使用状态方程将当前估计向前投射,同时给出该估计的不确定度量。在更新步骤中,新观测到来并修正估计。修正幅度取决于预测与测量各自的不确定性:若模型预测更可靠,观测的影响更小;若 GPS 信号干净而模型不确定,观测将占主导。这种按不确定性加权的融合让卡尔曼滤波在实践中奏效。
对于非线性或非高斯情形存在扩展:扩展卡尔曼滤波对动力学做线性化,无迹卡尔曼滤波采用更聪明的近似,而粒子滤波通过采样处理完全通用的情形。这些属于另一个话题。
状态空间模型的类型
根据您对动力学与噪声所愿意作出的假设不同,该框架涵盖多种设置。
线性高斯状态空间模型是经典设置:线性的转移与观测方程,高斯噪声。可直接应用卡尔曼滤波,且精确推断可行。
非线性状态空间模型在状态转移或观测关系不线性时出现——如单摆,或价格效应逐渐减弱的模型。此时不再存在精确推断。
非高斯状态空间模型放弃噪声服从正态分布的假设。计数数据、二元结果与重尾过程皆属此类。
状态空间模型与相关时间序列模型的对比
有必要明确比较几点,因为它们之间的边界比初看时更模糊。
状态空间模型 vs. ARIMA
ARIMA 直接对观测值及其过去误差建模,不引入任何隐藏状态。状态空间模型则显式引入潜在状态。话虽如此,ARIMA 可以改写为状态空间形式——因此两者并非如初看那般泾渭分明,软件在拟合 ARIMA 时往往也会在内部使用状态空间表示。
状态空间模型 vs. 隐马尔可夫模型
二者都包含隐藏状态。经典 HMM 使用离散潜在状态(系统处于k种模式之一),而大多数状态空间模型采用连续状态。用于语音识别时,离散模式更合理;用于跟踪物体运动时,连续状态更自然。
状态空间模型 vs. 结构性时间序列模型
结构性时间序列模型(将序列分解为趋势、季节性与不规则成分)通常是以状态空间模型来表述的,而不是与其竞争。它们是该框架的特定用例。
Python 与 R 中的状态空间模型
两种语言的流程类似——定义模型、拟合模型,并提取隐藏状态的估计。
Python 中的状态空间模型
statsmodels库为拟合状态空间模型提供了简洁接口。以下是在一些时间序列数据上拟合局部水平模型(最简单的结构性模型,状态为随机游走,观测含噪声):滤波后的状态为您提供模型在各时点对隐藏水平的最佳估计。这才是您最关心的输出,而非参数本身。
R 中的状态空间模型
在 R 中,
KFAS包可处理高斯状态空间模型,如果您经常在这一领域工作,值得掌握。流程与 Python 相仿:定义模型对象、拟合,并提取平滑或滤波后的状态。解读隐藏状态估计,而不仅仅是拟合统计量。状态空间模型的优势与局限
与大多数建模框架相似,其优劣同源:您必须事先承诺一种结构。
优势: 它们不是掩盖隐藏过程,而是将其显式表示;它们天然处理随时间变化的系统;测量不确定性内生于模型,而非事后考虑;同一框架无需改变模型结构即可支持滤波、平滑与预测。
局限: 指定模型可能很难。您需要决定隐藏状态意味着什么以及如何演化,这需要真正的领域判断。对于非线性或非高斯系统,推断成本会很高。而且如果您对动力学或噪声的假设有误,估计结果也会以不总是显而易见的方式出错。
结语
状态空间模型描述两件事:不可观测的状态如何随时间演化,以及该状态如何生成您可测得的观测。这分别是状态方程与观测方程。其他内容(卡尔曼滤波、平滑、预测)都是关于如何根据数据推断隐藏状态。
我认为该框架的价值在于,它迫使您明确自己不知道的部分。与直接对观测建模(如 ARIMA)不同,您必须承诺一个关于底层过程的故事。这是一种约束,也是一种澄清。一旦写下您认为的隐藏状态及其运动方式,推断问题就变成了机械过程。最难的部分早已在建模时完成。
如果您来自经典时间序列方法领域,值得把状态空间模型作为独立方法来理解,而非仅视作已知方法的推广。我们的Python 时间序列课程涵盖更广泛的工具包;若您的下一站是隐马尔可夫模型或卡尔曼滤波,这里的概念基础可直接迁移。