尧图精选

AR-HMM自回归隐马尔可夫模型:原理推导与Python实战

🕒 发布时间:2026/9/15 12:19:37 📁 来源:尧图网络
AR-HMM模型 自回归隐马尔可夫模型两年前我在处理一组工业升降机的振动信号时第一次真切体会到“时序数据里藏着状态”这句话有多折磨人。升降机在空载、满载、门机联动这三个阶段里振动波形完全不同但又不是简单的一刀切就能切开的——阶段切换点往往藏在几百毫秒的过渡区里。当时我先用普通AR模型去拟合结果预测误差忽大忽小残差里明显带着结构又试了传统HMM把每个观测当作独立发射结果状态切换倒是切出来了可状态内部的噪声大得离谱因为HMM根本没有利用“上一时刻的观测对下一时刻有直接影响”这一层关系。折腾到最后我才把目光落到AR-HMM模型上。自回归隐马尔可夫模型Autoregressive Hidden Markov Model本质上是一个“带记忆的HMM”隐状态负责刻画数据背后不可直接观测的模式切换每个状态内部用一条AR回归来建模观测值随时间的自相关性。做时序的人应该都明白这玩意儿几乎是给“分段平稳、段内相关”这类数据量身定做的。接下来的内容我会从模型动机、数学推导、代码实现到实战踩坑一层层拆开讲希望能帮你少走我当时走过的弯路。1. AR-HMM到底解决什么问题先看一组会变“脾气”的时序数据1.1 从两个失败案例说起AR模型和HMM各自的盲区先看一个最简单的场景某段传感器信号在0到600个采样点内是一条均值为5、方差为1的AR(1)序列600到1200个采样点突然变成均值为-2、方差明显增大的另一个AR(1)序列。如果我们用单一AR模型去拟合整段数据估计出的系数是两个状态下系数的“平均”预测在状态切换点附近会出现系统性偏差。如果改用普通HMM把每个时间点的观测看成由某个离散状态发射的独立样本虽然能识别出两种状态但模型完全没有利用相邻观测之间的相关关系导致每个状态内部的残差仍然表现出很强的自相关违背了HMM观测独立的假设。这两个失败案例分别戳中了两种模型的盲区AR模型擅长描述平稳时间序列内的线性动态但不具备状态切换能力HMM擅长描述离散状态之间的马尔可夫跳转却假设观测在给定状态下条件独立。现实中大量信号恰恰是“状态切换状态内自相关”并存比如语音发音的帧序列、人体动作的关节角度、设备运行的模式切换、脑电信号的不同节律甚至金融资产的波动聚集。AR-HMM把这两者揉在一起恰好堵住了各自的缺口。1.2 AR-HMM的直观图像状态切换 状态内回归我把AR-HMM理解成一个“带记忆的开关系统”。想象我们有一台机器机器内部有几个固定的工作模式外部观测到的数据由当前模式对应的回归方程产生。机器按照马尔可夫链在模式之间切换而每个模式内部的观测值不是孤立的而是依赖前几个时刻的观测值。用一句话概括每个时刻的观测既受当前隐藏状态控制又受该状态内自回归路径的控制。这张图我建议所有刚上手的人都画一遍顶部是一条离散隐藏状态链随时间变化底部是一条连续观测序列。隐藏状态链的状态数记为(K)每一步按状态转移矩阵(A)转移观测序列在时刻(t)的取值(x_t)其生成方式取决于当前状态(z_t)对应的AR系数(a_{z_t,1}, \dots, a_{z_t,p})和噪声方差(\sigma^2_{z_t})。这样我们既能在时间轴上看到分段的语义标签又能在每个标签内部看到连续的动态模式。后面所有公式和代码都围绕这张图展开。2. 模型骨架拆解状态序列、观测方程与三条依赖假设2.1 观测方程状态内自回归阶数p的决定方式AR-HMM的观测方程写作[ x_t \sum_{i1}^{p} a_{z_t,i} , x_{t-i} \epsilon_t, \quad \epsilon_t \sim \mathcal{N}(0, \sigma_{z_t}^2) ]其中(z_t \in {1,2,\dots,K})是时刻(t)的隐藏状态(a_{z_t,i})是当前状态下第(i)阶自回归系数(\epsilon_t)是均值为0、方差由当前状态决定的高斯噪声。一句话理解每个状态都对应一个独立的线性回归模型用来预测当前观测。这里有一个关键点AR阶数(p)是该状态的“记忆长度”。(p0)时模型退化成普通HMM(p \geq 1)时观测之间通过自回归项产生状态内部的相关性。阶数越大模型能刻画的状态内动态越复杂但参数也越多。我在实际项目中一般不会一上来就拍脑袋定(p)而是先用纯时间序列方法对每个候选状态分别做PACF偏自相关函数分析看截尾位置。对于振动信号通常(p2)到(4)就够了对于语音这种高频采样的信号可能要去到10以上。2.2 完整概率图结构中的三组依赖关系AR-HMM的联合概率分布可以写成[ P(\mathbf{x}{1:T}, \mathbf{z}{1:T} \mid \theta) \pi_{z_1} \prod_{t2}^{T} A_{z_{t-1}, z_t} \prod_{t1}^{T} \mathcal{N}\left(x_t ,\middle|, \sum_{i1}^{p} a_{z_t,i} x_{t-i}, \sigma_{z_t}^2\right) ]其中(\pi)是初始状态分布(A)是(K\times K)的状态转移矩阵(\theta)包含了所有转移概率、AR系数和噪声方差。从概率图的角度看模型里有三组关键依赖关系状态链的马尔可夫依赖(z_{t})只依赖(z_{t-1})不依赖更早的状态。这保证了状态切换过程的简洁性也让前向后向算法能够高效计算。观测对状态的依赖(x_t)的发射分布完全由当前状态(z_t)决定。没有这个假设我们就无法把不同状态下的动态模式区分开。观测对历史观测的依赖(x_t)直接依赖(x_{t-1}, \dots, x_{t-p})。这正是AR-HMM和普通HMM最大的区别也是它在处理连续时序数据时能大幅减少“伪状态切换”的原因。值得提醒的是这里有个容易被忽略的前提初始时刻(t1)时我们通常假设(x_0, x_{-1}, \dots, x_{1-p})是已知的或者把(t1)时刻的观测值设为全局观测均值。更严谨的做法是将前(p)个时刻视为预热期不参与发射概率计算或者给它们单独建模。我习惯的方法是把训练序列整体前移给模型传入一个足够长的“上下文向量”让自回归项在每一时刻都有合法的滞后值。2.3 一个具体的生成示例两状态AR(2)的模拟过程纸上谈兵不如直接跑一段生成代码。假设我们有一个两状态AR(2)模型状态1(a_1 [0.5, 0.2])噪声方差(\sigma_1^20.5)状态2(a_2 [-0.3, 0.9])噪声方差(\sigma_2^22.0)状态转移矩阵(A \begin{bmatrix} 0.95 0.05 \ 0.1 0.9 \end{bmatrix})初始状态分布(\pi [0.5, 0.5])用NumPy模拟1000个点代码长这样import numpy as np np.random.seed(42) T 1000 p 2 K 2 # 状态转移矩阵行表示 t-1 时刻状态 A np.array([[0.95, 0.05], [0.10, 0.90]]) pi np.array([0.5, 0.5]) # 各状态 AR 系数和噪声标准差 ar_coef np.array([[0.5, 0.2], [-0.3, 0.9]]) sigma np.array([0.7, 1.4]) # 标准差 # 生成状态链 z np.zeros(T, dtypeint) z[0] np.random.choice(K, ppi) for t in range(1, T): z[t] np.random.choice(K, pA[z[t - 1]]) # 生成观测序列 x np.zeros(T) for t in range(T): context 0.0 for i in range(1, p 1): if t - i 0: context ar_coef[z[t], i - 1] * x[t - i] x[t] context np.random.normal(0, sigma[z[t]])把这段数据画出来你能很直观地看到状态切换时均值、振动幅度和波峰形态同时变化。这种生成器我建议保留下来后面无论是验证模型实现还是测试识别算法都能用同一份基准数据说话。3. 参数怎么估计EM算法推导细节与贝叶斯扩展3.1 EM算法中的E步前向后向算法与状态后验平滑AR-HMM的参数估计不像前面模拟生成那么简单因为隐藏状态链是未知的。最经典的估计方式是最大似然估计而EM算法是解决“含隐变量模型”的标准武器。EM的思路是反复迭代在E步计算隐变量的后验期望在M步更新参数直到对数似然不再明显上升。E步的核心是计算两个后验量[ \gamma_t(i) P(z_t i \mid \mathbf{x}_{1:T}, \theta) ]表示时刻(t)处于状态(i)的后验概率以及[ \xi_t(i,j) P(z_{t-1} i, z_t j \mid \mathbf{x}_{1:T}, \theta) ]表示从状态(i)转移到状态(j)的后验概率。这两个量都要用前向后向算法来算。前向变量(\alpha_t(i))表示观测(x_1, \dots, x_t)且时刻(t)处于状态(i)的联合概率。递推不是标准HMM里那个简洁的“上一时刻状态只通过转移概率影响当前观测的发射概率”因为这里的发射概率不是简单查表而是要计算带自回归项的高斯密度[ \alpha_1(i) \pi_i , \mathcal{N}\left(x_1 \mid \sum_{d1}^{p} a_{i,d} x_{1-d}, \sigma_i^2\right) ][ \alpha_t(i) \mathcal{N}\left(x_t \mid \sum_{d1}^{p} a_{i,d} x_{t-d}, \sigma_i^2\right) \sum_{j} \alpha_{t-1}(j) A_{j,i} ]反向变量(\beta_t(i))表示从时刻(t1)到终点观测的后验概率递推反向进行。有了(\alpha)和(\beta)后验量就很简单[ \gamma_t(i) \frac{\alpha_t(i)\beta_t(i)}{\sum_j \alpha_t(j)\beta_t(j)} ][ \xi_t(i,j) \frac{\alpha_{t-1}(i) A_{i,j} , \mathcal{N}\left(x_t \mid \sum_{d1}^{p} a_{j,d} x_{t-d}, \sigma_j^2\right) \beta_t(j)} {\sum_{i,j} \alpha_{t-1}(i) A_{i,j} , \mathcal{N}\left(x_t \mid \sum_{d1}^{p} a_{j,d} x_{t-d}, \sigma_{j}^2\right) \beta_t(j)} ]实际工程中所有概率都要在对数域计算否则序列一长连乘概率会立刻下溢成0。我在自己的实现里都是把前向后向算法改成logα和logβ递推用log-sum-exp技巧做归一化和后验计算。3.2 M步的闭式解回归系数与协方差更新M步的目标是对每个状态用上一步得到的后验概率重新估计参数。转移概率和初始分布的更新和普通HMM完全一样[ \hat{\pi}_i \gamma_1(i) ][ \hat{A}{i,j} \frac{\sum{t2}^{T} \xi_t(i,j)}{\sum_{j1}^{K} \sum_{t2}^{T} \xi_t(i,j)} ]关键是AR系数和方差怎么更新。把当前状态(k)下的观测方程看成一个加权线性回归问题每个时刻(t)的权重就是后验概率(\gamma_t(k))。定义设计矩阵(\mathbf{X})第(t)行是滞后向量([x_{t-1}, x_{t-2}, \dots, x_{t-p}])观测向量(\mathbf{y})的第(t)个元素是(x_t)对角权重矩阵(\Gamma_k)的对角线元素为(\gamma_t(k))。那么该状态下的AR系数闭式解为[ \mathbf{b}_k \left( \mathbf{X}^T \Gamma_k \mathbf{X} \right)^{-1} \mathbf{X}^T \Gamma_k \mathbf{y} ]噪声方差为[ \sigma_k^2 \frac{\sum_{t1}^{T} \gamma_t(k) \left( x_t - \sum_{i1}^{p} \hat{a}{k,i} x{t-i} \right)^2}{\sum_{t1}^{T} \gamma_t(k)} ]这里要特别留意一个工程细节如果某个状态的后验权重总和过小比如(\sum_t \gamma_t(k) 10)那这个状态的参数估计极不靠谱。我在M步里会加一个“最小权重阈值”判断权重不足的状态就不更新参数等下一轮EM看它是否还能获得足够的数据归属。否则你会在训练中看到某个状态被彻底抛弃最后得到一组无意义的系数。3.3 贝叶斯变分推断和MCMC的适用场景EM得到的最大似然估计有一个隐患当状态数多、序列短、或者某些状态本身数据稀疏时参数估计方差很大甚至产生退化。这时候可以考虑走贝叶斯路线给参数加上先验分布。转移矩阵每行放一个Dirichlet先验比如(A_{i,:} \sim \text{Dir}(\mathbf{1}_K))。AR系数放高斯先验比如(\mathbf{b}_k \sim \mathcal{N}(\mathbf{0}, \lambda^{-1} I))这相当于给加权回归加了(L2)正则。噪声方差放Inverse-Gamma先验。完整贝叶斯推断可以借助变分推断用平均场近似分解出每个参数的后验分布EM中的E步换成变分E步M步换成参数后验更新。也可以用MCMC比如Gibbs采样逐样本更新状态分配和参数。但说实话在实际项目里MCMC的计算开销太大尤其在观测序列几十万条数据时根本跑不动。变分推断速度尚可但实现复杂度比EM高一个量级。我的个人建议是**如果数据量足够大状态平均样本数几百以上直接用EM就行如果数据量小或者存在明显过拟合风险选变分贝叶斯AR-HMM。**不要一开始就上贝叶斯大炮EM跑不出来的问题通常通过初始化和模型选择能解决而不是靠换推断框架。4. 动手实战用Python实现一个可用的AR-HMM训练器4.1 选型参考hmmlearn自定义类、Pyro还是自己写很多人会问有没有现成的库可以直接调用hmmlearn是Python最常用的隐马尔可夫库但它的内置模型只支持多项式发射和独立高斯发射不直接支持自回归发射。不过可以利用GaussianHMM配合自定义特征把滞后值当作额外特征拼进观测向量让发射均值成为滞后特征的线性函数。这种做法的缺点是协方差结构不够灵活也没有把“每个状态各自的AR模型”显式建模出来。Pyro或NumPyro支持概率编程可以非常灵活地搭建AR-HMM的生成模型并做变分推断。优点是设计自由缺点是学习曲线陡峭且调试隐状态后验比较麻烦。最可控的方案是自己写EM。AR-HMM的EM代码量并不大核心也就一两百行。我自己主力项目里用的就是自研的这个版本方便后续加各种改进比如半马尔可夫状态持续时间、非高斯噪声、不确定性量化。如果你的目的不是搞研究而是趁早把AR-HMM用在业务里我建议先自己实现一个简单的EM版本跑通后再决定要不要迁移到概率编程框架。4.2 自写EM实现的核心代码分段解释下面给出一个最小可用EM训练器的核心骨架。为了清晰我只列了训练阶段的关键部分忽略了许多边界判断。from scipy.special import logsumexp def ar_hmm_em(x, K, p, A_init, ar_init, sigma_init, pi_init, max_iter100, tol1e-4, min_weights10.0): T len(x) # 构造滞后观测矩阵X[t] [x[t-1], ..., x[t-p]] X np.zeros((T, p)) for i in range(p): # 预热期直接使用x[0]填充简化处理 X[:, i] np.concatenate([np.full(i 1, x[0]), x[:T - i - 1]]) A A_init.copy() ar_coef ar_init.copy() sigma sigma_init.copy() log_pi np.log(pi_init) prev_ll -np.inf for it in range(max_iter): # ---------- E步 ---------- # 遍历时刻计算 log 发射概率 log_emit np.zeros((T, K)) for k in range(K): mean X ar_coef[k] residual x - mean log_emit[:, k] -0.5 * np.log(2 * np.pi * sigma[k] ** 2) \ - 0.5 * residual ** 2 / sigma[k] ** 2 # 前向和后向的具体递推这里省略 # 关键是得到 log_gamma 和 log_xi # 伪代码 # alpha forward(log_emit, A, log_pi) # beta backward(log_emit, A) # log_gamma alpha beta - logsumexp(alpha beta, axis1, keepdimsTrue) # log_xi alpha[:-1, :, None] ... (详见课程讲义) # ---------- 计算对数似然用于收敛判断 ---------- ll logsumexp(alpha[-1] beta[-1]) # 实际要标准化 if abs(ll - prev_ll) tol: break prev_ll ll # ---------- M步 ---------- gamma np.exp(log_gamma) xi np.exp(log_xi) # 更新初始状态和转移矩阵 pi_new gamma[0] / gamma[0].sum() A_new xi.sum(axis2) / xi.sum(axis(1, 2))[:, None] # 更新AR系数和方差 ar_new np.zeros_like(ar_coef) sigma_new np.zeros_like(sigma) for k in range(K): w gamma[:, k] w_sum w.sum() if w_sum min_weights: ar_new[k] ar_coef[k] sigma_new[k] sigma[k] continue # 加权最小二乘 WX X * w[:, None] Wy x * w beta_k np.linalg.solve(WX.T X 1e-6 * np.eye(p), WX.T y) ar_new[k] beta_k residual x - X beta_k sigma_new[k] (w * residual ** 2).sum() / w_sum A A_new ar_coef ar_new sigma sigma_new log_pi np.log(pi_new 1e-300) return { A: A, ar_coef: ar_coef, sigma: sigma, pi: np.exp(log_pi), log_likelihood: ll, }上面这段代码刻意隐藏了前向后向的细节因为真正实现时需要处理大量对数加法还要注意log_xi的形状。核心思路就是在E步把每个时刻在每个状态下的发射概率算出来其余和标准HMM完全统一在M步把状态后验当作样本权重做K组加权线性回归。4.3 状态数与阶数选择的模型选择方法BIC / 留一法AR-HMM最常被问的两个问题状态数(K)选多少AR阶数(p)选多少我的做法是初筛用K-Means或者GMM对观测序列做简单的聚类看每个簇内部残差的自相关粗略估计可能的(K)范围。网格搜索遍历(K)和(p)的组合每组跑多个随机初始化用BIC作为评分准则[ \text{BIC} -2\log \hat{L} m \log T ]其中自由参数个数(m)包括转移矩阵自由参数(K(K-1))、每个状态的AR系数(Kp)、每个状态的方差(K)、初始分布(K-1)。所以[ m K(K-1) Kp 2K - 1 ]验证对于更复杂的场景把数据按时间切片训练集和测试集分开。测试集的平均对数似然比BIC更可靠尤其是在状态占比不平衡时。BIC只是惩罚项不一定兜得住标签偏移和数据非平稳的问题。我在升降机项目里就是用这个流程最后选了(K3, p2)的组合。BIC在(K4)的时候也略有上升但实际去看状态后验时第四个状态几乎被0到极少数据占用属于典型的“占着茅坑不拉屎”果断砍掉。5. 真实应用与效果评估工业质检、脑电信号与金融波动5.1 例一升降机振动信号状态识别回到开头那个升降机项目。振动传感器采样率是1kHz我们采集了20分钟连续运行数据发现设备在启动、稳定上升、满载停留、下降四个阶段振动模式差异很大。我一开始用滑动窗口标准差做阈值判断但窗口长度很难调太短波动导致的误触发频繁太长切换点检测滞后严重。改用AR-HMM后我做了两个预处理一是带通滤波到10~500Hz二是做一阶差分去掉低频漂移。模型输入是单通道加速度信号设置(K4, p3)。训练完成后最明显的收益是每个状态内部的残差基本白噪声化而且状态切换时刻和我们在现场用摄像机录到的帧基本对齐。尤其在“满载停留”这个状态设备本质上接近静止但还是有微风和轻微机械振动AR(3)模型能捕捉到这个状态特有的谐振模式这是单纯靠幅值阈值和普通HMM都做不到的。输出状态标签后我们统计了每个状态占比和设备启停次数这部分结果直接用于指导维保周期调整。后来我们把模型封装成服务对新采集的数据在线滑动窗口预测状态概率发现偶尔会出现状态抖动于是加了“惰性切换”连续两个状态的概率都超过阈值时才真正切换抖动明显减少。5.2 例二运动捕捉数据的动作切分另一个我印象很深的场景是人体动作识别。拿惯性传感器IMU采集的加速度和角速度数据走路、跑步、上楼梯、下楼梯、转身这些动作模式不同每个动作内部又有明显的周期特性。如果直接用分类模型识别率取决于滑动窗口切得好不好用AR-HMM隐藏状态就是动作类别状态内部的自回归项天然建模了动作的周期性。有意思的是直接用原始6维信号做AR-HMM效果并不好。后来我们做了一个关键改动把每帧数据先投影到主成分空间保留前3个主成分再在每个状态内做AR(2)。这一改动把训练时间缩短了约60%原因很简单——原始6维信号里相关度太高多数特征在同一动作内部高度冗余加权回归的有效自由度被浪费了。状态内部自回归的“记忆”主要体现在主成分时间序列的相位连续性上而不是具体在哪个传感器通道上。这个项目让我养成了习惯**给AR-HMM输入任何特征前先做一次主成分分析不是为了压缩维度而是为了去相关。**虽然AR-HMM的发射分布是高斯协方差理论上能建模特征相关性但在样本量不够大时去相关预处理能显著提高估计稳定性。5.3 评估指标与结果可视化状态分配图、残差检验模型训得好不好不能只看对数似然我一般会看四张图状态分配图和原始观测叠加图。一眼能看出状态切换点是否与业务语义吻合比如是否把同一个稳定运行段切得七零八落。每个状态的残差时间序列和自相关图。如果某个状态下的残差仍然有明显AR结构说明这个状态没有一个AR模型能描述可能该状态内部还藏着子状态。状态转移矩阵热力图。冷门状态和不可能转移对会在图上暴露无遗。状态后验概率的时间演化图。有些样本的状态后验长期维持在0.5/0.5说明模型对这段数据“拿不准”多半是数据本身位于两个状态的模糊边界。数值指标方面我常用测试集逐点预测误差的RMSE和MAE对比普通AR、普通HMM和AR-HMM。在振动信号上AR-HMM的RMSE通常比单一AR低10%~20%比普通HMM低30%以上。如果结果没有这种改善请回头检查是否状态数过多导致过拟合或者预处理把状态间的差异抹平了。6. 踩过的坑和调试经验收敛陷阱、过拟合与标签偏移6.1 局部最优与初始化策略EM算法严格依赖初始化。我在早期实现里用随机初始化结果跑出来的模型十个里有三四个处于明显的局部最优状态转移矩阵在某些行接近均匀分布AR系数则回到全局均值。后来我改用如下初始化策略先做K-Means聚类把观测序列分割成K段每个簇内的样本估计AR系数和方差。用这些估计作为EM的初始AR系数和方差。转移矩阵初始化成对角线占优的矩阵比如对角线0.8非对角线均分0.2。这种做法让最终模型的稳定性大幅度提升。除了这种“聚类热启动”还有一个经验是**多跑几次随机重启选择训练似然最高的模型。**如果两次重启得到的模型参数差异巨大说明模型对初始化非常敏感这时更需要怀疑是不是状态数选多了。6.2 状态数设置偏大时的“状态碎片化”问题我曾经在一个动作识别任务里设置了6个状态但数据本身只有4个明确动作。训练完成后发现有两个状态被频繁交替分配到同一条动作曲线上形成“碎片化状态”模型为了增加似然把一段平稳的AR(2)序列用两个AR系数相近但方差略不同的状态去拼凑后验概率在相邻时刻间来回横跳。这其实就相当于过拟合除了导致标签语义不清晰还会严重膨胀转移矩阵的不确定性。对付状态碎片化有两个思路在M步给AR系数增加正则化比如把目标函数改成(-\log\hat{L} \lambda \sum_k |\mathbf{b}_k - \mathbf{b}_0|^2)。这个(\mathbf{b}_0)可以是全局AR系数估计也就是“状态差异要被数据支撑否则收回去”。在后处理阶段合并状态如果两个状态的AR系数余弦相似度超过0.95且转移概率两者互相很高则可以合并成一个状态。我在项目里常把第二个思路作为固定检查项加在模型训练完的自检环节里。6.3 数值稳定性对数域计算与协方差正则化AR-HMM的观测概率是高斯密度短序列还好序列一旦上万个点连乘概率必然下溢。所有实现必须在对数域运转。这里有两个关键点log-sum-exp技巧计算归一化因子时( \log\left( \sum_i e^{a_i} \right) m \log\sum_i e^{a_i - m})其中(m \max_i a_i)。协方差正则化加权最小二乘中矩阵(\mathbf{X}^T \Gamma_k \mathbf{X})在某个状态权重几乎全集中在少数样本上时可能奇异。我在代码里给它加一个小的对角惩罚比如(10^{-6}I)。不要加太大否则AR系数偏离真实估计太远状态内残差会重新出现自相关。6.4 调试工具箱从无监督聚类结果反查模型错误当AR-HMM训练结果不理想时我推荐的排查顺序是先看数据生成过程。如果不对后面对模型的所有判断都是多余的。用第2.3节模拟数据先跑通确保自己实现的EM能把真实参数恢复到可接受精度。用可视化检查Y轴尺度。如果观测信号的量级在不同状态间差异极大比如状态1方差0.1状态2方差1000高斯发射模型容易把小方差状态的细节忽略掉。这种情况下预先做标准化比如除以全局标准差很有帮助。把预测误差和聚类结果对照。先用K-Means给每帧数据打硬标签再按聚类标签分别拟合AR模型观察每个AR模型的残差和状态切换点。如果K-Means结果和AR-HMM的结果差异特别大多半是数据预处理或者状态数设置的问题。我记得有一次调了半天发现AR-HMM把同一个稳定状态切成两半原因是原始信号里混了一个低频正弦干扰。AR(2)为了拟合这个正弦干扰特地构造了一个近单位根的AR系数于是原本同一个状态被拆成“正弦相位A”和“正弦相位B”。这个问题不是模型参数能解决的必须先把干扰滤波掉或者在设计特征时去除波长大于状态持续时间的成分。回到升降机项目我在跑通AR-HMM之后顺手把状态内残差的功率谱也做了分析发现满载状态在特定频率附近始终有一个窄带峰这个峰反映了液压系统泵阀的正常振动。后来我把这条信息反馈给设备厂商对方确认这个频率和液压缸的固有频率吻合。这种跨层级的洞察正是AR-HMM把状态和状态内动态同时建模后带给我的额外价值。如果你正准备把AR-HMM用在新的数据集上我建议从模拟数据开始再到单条真实序列最后再评估多条序列的联合建模需求。每一步都建立一张可视化图状态分配、残差自相关、对数似然收敛曲线。别看这些图简单它们往往比任何高级指标都更能帮你说清楚模型是不是在耍花招。
上一篇/下一篇内容由系统自动关联 返回资讯列表 →