ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

随机信号参数建模:AR/MA/ARMA模型原理与Matlab实践

随机信号参数建模:AR/MA/ARMA模型原理与Matlab实践 1. 项目概述从随机信号到参数化建模在信号处理、通信系统乃至金融时间序列分析等领域我们常常面对一个核心挑战如何用尽可能简洁的方式描述一个看似杂乱无章、充满不确定性的随机信号直接存储或传输原始信号数据往往意味着巨大的存储开销和带宽压力。这就引出了“数据压缩”这一经典课题。而“随机信号的参数建模法”正是解决这一问题的利器。它不再试图记录信号的每一个采样点而是转而寻找一个能够“生成”或“解释”该信号的数学模型我们只需要存储这个模型的少数几个关键参数就能在需要时高保真地重建出原始信号的大致样貌。简单来说这个项目的核心思想是“以模型代数据”。想象一下你要向朋友描述一段复杂的音乐旋律。笨办法是录下每一个音符的振动细节发过去而聪明办法则是告诉他“这是一段C大调、4/4拍、主旋律由几个特定和弦走向构成的音乐。”后者就是参数建模的思路——用调性、节奏、和弦这几个“参数”来概括整段音乐。对于随机信号我们则是用自回归模型、滑动平均模型或其组合ARMA模型的系数、阶数等参数来刻画其内在的统计特性如相关性、频谱形状等。本次作业将深入探讨随机信号参数建模法的原理并利用Matlab这一强大的工程计算软件进行完整的验证实现。我们将从理论推导走到代码实践不仅告诉你公式是什么更会解释为什么选择这个模型、参数如何估计、结果如何评价并分享在Matlab实现过程中那些容易踩坑的细节和调试技巧。无论你是正在学习《数字信号处理》或《时间序列分析》课程的学生还是希望将参数建模应用于实际工程问题的工程师这篇内容都将提供一条从理论到实践的清晰路径。2. 核心原理三种基础参数模型深度解析随机信号的参数建模其本质是认为一个平稳随机信号 (x(n)) 可以由一个输入为白噪声 (w(n)) 的线性时不变系统来产生。这个系统的特性就由模型的参数来描述。最经典、最常用的三种模型是自回归模型、滑动平均模型以及它们的组合。2.1 自回归模型用历史预测现在自回归模型简称AR模型其核心思想非常直观当前时刻的信号值可以由过去若干个时刻的信号值的线性组合再加上一个当前时刻的随机冲击白噪声来解释。其差分方程定义为[ x(n) -\sum_{k1}^{p} a_p(k) x(n-k) w(n) ]其中(p) 是模型的阶数它决定了我们用多“远”的历史来预测现在。(a_p(1), a_p(2), ..., a_p(p)) 就是我们需要估计的AR模型参数也称为反射系数或线性预测系数。(w(n)) 是均值为零、方差为 (\sigma^2) 的白噪声。为什么AR模型有效因为它巧妙地利用了信号样本之间的相关性。对于大多数实际信号如语音、脑电、振动信号相邻的样本点不是独立的而是高度相关的。AR模型通过参数 (a_p(k)) 量化了这种相关性。从系统函数的角度看AR模型对应一个全极点的系统其传递函数为[ H(z) \frac{1}{1 \sum_{k1}^{p} a_p(k) z^{-k}} \frac{1}{A(z)} ]这意味着AR模型特别擅长刻画具有尖峰频谱的信号。例如语音信号的共振峰、机械系统的谐振频率都可以通过AR模型谱中的峰值来清晰地反映。注意AR模型参数估计的稳定性是关键。并非所有估计出的参数都能保证对应的系统是稳定的即极点都在单位圆内。常用的Yule-Walker方程基于自相关函数求解在理论上能保证最小相位解即稳定性。但在数值计算中尤其是阶数p较高时自相关矩阵可能病态导致参数求解误差较大。2.2 滑动平均模型关注噪声的滞后影响与AR模型关注信号自身的历史不同滑动平均模型关注的是驱动噪声的历史影响。MA模型认为当前信号值是当前以及过去若干时刻的白噪声的线性组合。其定义式为[ x(n) \sum_{k0}^{q} b_q(k) w(n-k) ]其中(q) 是MA模型的阶数(b_q(k)) 是MA模型的参数且通常约定 (b_q(0) 1)。MA模型的系统函数是一个全零点的系统[ H(z) B(z) 1 \sum_{k1}^{q} b_q(k) z^{-k} ]MA模型适合建模那些频谱具有深谷特性的信号或者说其自相关函数在滞后超过阶数q后截尾理论上为零。在实际应用中纯粹的MA模型使用不如AR模型广泛因为其参数估计通常比AR模型更困难。估计MA参数通常需要更复杂的迭代算法如牛顿法或通过高阶矩来求解。2.3 ARMA模型强强联合的通用模型为了更灵活地拟合各种统计特性的随机信号自然想到了将AR和MA结合起来这就是自回归滑动平均模型。ARMA(p, q)模型的定义结合了前两者[ x(n) -\sum_{k1}^{p} a_p(k) x(n-k) \sum_{k0}^{q} b_q(k) w(n-k) ]其系统函数为[ H(z) \frac{B(z)}{A(z)} \frac{1 \sum_{k1}^{q} b_q(k) z^{-k}}{1 \sum_{k1}^{p} a_p(k) z^{-k}} ]这是一个零极点模型既能描述频谱的峰值极点贡献也能描述频谱的谷值零点贡献因此建模能力最强理论上可以用较低的阶数(p,q)来精确描述一个高阶的AR或MA过程。然而ARMA模型的参数估计是最复杂的因为其需要同时估计AR和MA两部分参数通常采用迭代优化算法如最小二乘迭代、辅助变量法等计算量大且可能陷入局部最优。模型选择的心得在实际项目中通常遵循“从简到繁”的原则。优先尝试AR模型因为其参数估计简单、稳定且很多物理过程如受白噪声激励的振动系统天然符合AR模型。如果AR模型残差预测误差仍表现出显著的相关性或者待建模信号的频谱有明显的凹槽再考虑引入MA部分尝试ARMA模型。纯粹的MA模型单独使用场景较少。3. 关键算法模型参数估计与阶次确定有了模型下一步就是从一段有限长的观测信号数据 (x(1), x(2), ..., x(N)) 中估计出模型的参数 ((a_p(k), b_q(k))) 以及噪声方差 (\sigma^2)。同时我们还需要确定模型的阶数 ((p, q))这是一个模型复杂度与拟合精度之间的权衡问题。3.1 AR模型参数估计Yule-Walker方程与Levinson-Durbin递推AR模型最经典的参数估计方法基于Yule-Walker方程。该方程建立了模型参数与信号自相关函数之间的直接联系[ \begin{bmatrix} r(0) r(1) \cdots r(p-1) \ r(1) r(0) \cdots r(p-2) \ \vdots \vdots \ddots \vdots \ r(p-1) r(p-2) \cdots r(0) \end{bmatrix} \begin{bmatrix} a_p(1) \ a_p(2) \ \vdots \ a_p(p) \end{bmatrix} - \begin{bmatrix} r(1) \ r(2) \ \vdots \ r(p) \end{bmatrix} ][ \sigma^2 r(0) \sum_{k1}^{p} a_p(k) r(k) ]其中(r(m) E[x(n)x(nm)]) 是信号的理论自相关函数。实践中我们用样本自相关函数 (\hat{r}(m) \frac{1}{N} \sum_{n1}^{N-m} x(n)x(nm)) 来替代。直接求解这个线性方程组使用linsolve或\运算符是可行的。但更高效、数值稳定性更好的方法是Levinson-Durbin递推算法。该算法从1阶开始逐步递推到p阶在每一步同时计算出该阶次下的所有反射系数PARCOR系数和AR参数以及该阶次对应的前向预测误差功率。Matlab信号处理工具箱中的aryule函数就是基于此算法实现的。% 使用Levinson-Durbin递推估计AR模型参数 order 10; % 假设阶数p10 [ar_coeffs, noise_variance, reflection_coeffs] aryule(signal, order); % ar_coeffs: 返回的AR参数向量第一个元素为1后面是a1, a2, ..., ap % noise_variance: 估计的白噪声方差 sigma^2 % reflection_coeffs: 各阶反射系数可用于模型稳定性判断3.2 MA与ARMA模型参数估计非线性优化与子空间方法MA和ARMA模型的参数估计没有像AR模型那样的闭式线性解。常用的方法包括矩估计法通过使模型的理论自相关函数与样本自相关函数匹配来求解。对于MA(q)这导致一组非线性方程。对于ARMA(p,q)情况更复杂。最小二乘估计将模型改写为回归形式通过最小化预测误差的平方和来估计参数。这通常需要非线性优化算法如fminsearch,lsqnonlin。基于长AR模型的近似估计先用一个高阶的AR模型阶数L远大于pq去拟合数据然后从该高阶AR模型的参数中通过谱分解或多项式因式分解的方法近似提取出ARMA(p,q)的参数。这种方法相对稳定。子空间方法如随机子空间识别适用于多变量情况在单变量时间序列中也有应用。在Matlab中可以使用armax函数来自系统辨识工具箱来估计ARMA模型参数它内部使用了预测误差最小化方法。% 使用系统辨识工具箱估计ARMA模型 data iddata(signal, [], 1); % 将信号封装为iddata对象采样时间设为1 model_order [p, q]; % p为AR阶数q为MA阶数 estimated_model armax(data, model_order); % 提取参数 A_coeffs estimated_model.A; % AR多项式系数首项为1 B_coeffs estimated_model.B; % MA多项式系数首项为13.3 模型阶次确定信息准则的权衡艺术模型阶数(p, q)选多少合适阶数太低模型欠拟合无法捕捉信号细节阶数太高模型过拟合会将噪声的特性也建模进去泛化能力变差。常用的判定准则有最终预测误差准则FPE(k) \hat{\sigma}_k^2 * (Nk)/(N-k)其中k为模型参数总数(\hat{\sigma}_k^2)为k阶模型下的噪声方差估计值。选择使FPE最小的k。阿卡克信息准则AIC(k) N * ln(\hat{\sigma}_k^2) 2k。同样取最小值。贝叶斯信息准则BIC(k) N * ln(\hat{\sigma}_k^2) k * ln(N)。BIC对参数个数的惩罚比AIC更重倾向于选择更简单的模型。在Matlab中可以循环计算不同阶数模型下的这些准则值。N length(signal); max_order 30; % 假设最大试探阶数 fpe zeros(max_order, 1); aic zeros(max_order, 1); bic zeros(max_order, 1); for p 1:max_order [ar_coeffs, sigma2] aryule(signal, p); aic(p) N * log(sigma2) 2 * p; bic(p) N * log(sigma2) p * log(N); fpe(p) sigma2 * (N p) / (N - p); end [~, optimal_p_aic] min(aic); [~, optimal_p_bic] min(bic); [~, optimal_p_fpe] min(fpe); % 通常几个准则给出的最优阶数接近可选择其中一个如BIC的结果实操心得在实际操作中信息准则给出的“最优阶数”只是一个重要参考。一定要结合模型残差检验。一个良好的模型其残差序列预测误差应该近似为白噪声。可以用lbqtest函数进行Ljung-Box Q检验或者直接绘制残差的自相关函数图。如果残差在非零滞后处仍有显著相关性说明当前阶数可能不足或者模型类型AR/MA/ARMA选择不当。4. Matlab验证实战从信号生成到模型评估现在我们用一个完整的Matlab仿真案例来串联上述所有步骤。我们将合成一个已知参数的ARMA信号然后假装不知道这些参数仅从观测信号出发重新估计模型参数和阶数最后评估估计效果。4.1 步骤一生成仿真测试信号我们首先定义一个ARMA(2,2)过程作为真实的数据生成模型。clear; clc; close all; % 1. 定义真实ARMA模型参数 true_ar [1, -1.5, 0.7]; % A(z) 1 - 1.5z^{-1} 0.7z^{-2} true_ma [1, 0.5, -0.3]; % B(z) 1 0.5z^{-1} - 0.3z^{-2} true_model idpoly(true_ar, true_ma, 1, 1, 1, NoiseVariance, 0.1); % idpoly: 创建多项式模型对象参数依次为A, B, C, D, F, 附加属性 % 2. 生成仿真信号 N 1000; % 信号长度 rng(42); % 固定随机种子确保结果可复现 e sqrt(0.1) * randn(N100, 1); % 生成方差为0.1的白噪声多生成100点用于瞬态衰减 y_true filter(true_ma, true_ar, e); % 用filter函数模拟ARMA过程 y y_true(101:end); % 舍弃前100个点消除初始瞬态影响 t (1:N);4.2 步骤二模型识别与阶次选择现在我们只有观测信号y。先绘制其波形和自相关函数有一个直观认识。figure(Position, [100, 100, 1200, 400]); subplot(1,2,1); plot(t, y); xlabel(采样点); ylabel(幅值); title(观测信号波形); grid on; subplot(1,2,2); autocorr(y, 50); title(观测信号样本自相关函数); % 计算并绘制前50个滞后的自相关接下来我们使用AIC/BIC准则为AR模型确定一个初始的阶数范围。对于ARMA模型我们可以先尝试用高阶AR模型去近似。max_AR_order 30; [aic_vec, bic_vec] aic_bic(y, max_AR_order); figure; plot(1:max_AR_order, aic_vec, b-o, LineWidth, 1.5, MarkerSize, 6); hold on; plot(1:max_AR_order, bic_vec, r-s, LineWidth, 1.5, MarkerSize, 6); xlabel(AR模型阶数 p); ylabel(准则值); legend(AIC, BIC); grid on; title(AR模型阶数选择准则); [~, p_aic] min(aic_vec); [~, p_bic] min(bic_vec); fprintf(AIC建议的AR阶数: %d\n, p_aic); fprintf(BIC建议的AR阶数: %d\n, p_bic);这里aic_bic是一个需要自定义的函数用于计算不同AR阶数下的AIC和BIC值。function [aic, bic] aic_bic(signal, max_order) N length(signal); aic zeros(max_order, 1); bic zeros(max_order, 1); for p 1:max_order [~, sigma2] aryule(signal, p); aic(p) N * log(sigma2) 2 * p; bic(p) N * log(sigma2) p * log(N); end end假设BIC准则建议p10。我们可以先拟合一个AR(10)模型并分析其残差。p_tentative p_bic; [ar_coeffs_est, sigma2_est] aryule(y, p_tentative); % 计算残差 residual filter(ar_coeffs_est, 1, y); % 注意filter(A,B,X)是B(z)/A(z)这里A(z)ar_coeffs_est residual residual(length(ar_coeffs_est):end); % 去除初始瞬态 % 检验残差是否为白噪声 figure; subplot(2,1,1); plot(residual); title(AR(10)模型残差序列); xlabel(采样点); ylabel(幅值); grid on; subplot(2,1,2); autocorr(residual, 50); title(残差序列自相关函数); [lbq_h, lbq_p] lbqtest(residual, Lags, [10, 20]); % Ljung-Box Q检验 fprintf(Ljung-Box检验p值滞后10: %.4f\n, lbq_p(1)); fprintf(Ljung-Box检验p值滞后20: %.4f\n, lbq_p(2)); % 如果p值小于显著性水平如0.05则拒绝残差为白噪声的原假设说明AR模型可能不合适。4.3 步骤三ARMA模型估计与验证如果残差检验未通过或者从自相关函数图看出拖尾/截尾混合特性我们考虑ARMA模型。我们使用系统辨识工具箱。由于我们知道真实阶数大概是(2,2)但实际中不知道可以尝试一个小的网格搜索。% 尝试几种可能的(p,q)组合 orders_to_try [1,1; 2,1; 2,2; 3,2]; best_bic inf; best_model []; best_order [0,0]; data_iddata iddata(y, [], 1); % 创建辨识数据对象 for idx 1:size(orders_to_try, 1) current_order orders_to_try(idx, :); try model_temp armax(data_iddata, current_order); % 计算该模型的BIC值 residual_temp pe(model_temp, data_iddata); % 计算预测误差 sigma2_temp var(residual_temp.OutputData); k sum(current_order) 1; % 参数个数: pq 噪声方差 bic_temp N * log(sigma2_temp) k * log(N); if bic_temp best_bic best_bic bic_temp; best_model model_temp; best_order current_order; end catch ME warning(阶数 (%d,%d) 估计失败: %s, current_order(1), current_order(2), ME.message); end end fprintf(最优模型阶数 (p,q) (%d, %d) BIC %.2f\n, best_order(1), best_order(2), best_bic); estimated_ar best_model.A; estimated_ma best_model.B; estimated_noise_var best_model.NoiseVariance; fprintf(估计的AR参数: ); fprintf(%.4f , estimated_ar); fprintf(\n); fprintf(估计的MA参数: ); fprintf(%.4f , estimated_ma); fprintf(\n); fprintf(估计的噪声方差: %.4f\n, estimated_noise_var);4.4 步骤四性能评估与结果可视化最后我们比较真实模型与估计模型的频率响应功率谱密度这是评估建模效果最直观的方式。% 计算真实模型的频谱 [h_true, w_true] freqz(true_ma, true_ar, 1024, whole); psd_true abs(h_true).^2 * 0.1; % 乘以噪声方差得到功率谱密度 % 计算估计模型的频谱 [h_est, w_est] freqz(estimated_ma, estimated_ar, 1024, whole); psd_est abs(h_est).^2 * estimated_noise_var; % 绘制对比图 figure(Position, [100, 100, 800, 600]); subplot(2,2,1); plot(w_true/pi, 10*log10(psd_true), b-, LineWidth, 2); hold on; plot(w_est/pi, 10*log10(psd_est), r--, LineWidth, 1.5); xlabel(归一化频率 (\times \pi rad/sample)); ylabel(功率谱密度 (dB)); legend(真实模型, 估计模型); title(模型功率谱密度对比); grid on; % 绘制零极点图 subplot(2,2,2); zplane(true_ma, true_ar); title(真实模型零极点图); subplot(2,2,4); zplane(estimated_ma, estimated_ar); title(估计模型零极点图); % 绘制一段信号的拟合对比 y_sim_est filter(estimated_ma, estimated_ar, sqrt(estimated_noise_var)*randn(N,1)); subplot(2,2,3); plot(t(1:100), y(1:100), k-, LineWidth, 1.5); hold on; plot(t(1:100), y_sim_est(1:100), r:, LineWidth, 1.5); xlabel(采样点); ylabel(幅值); legend(原始信号, 模型生成信号); title(时域波形对比前100点); grid on;5. 常见问题与排查技巧实录在实际操作中你几乎一定会遇到下面这些问题。这里记录了我的排查思路和解决方法。5.1 问题一模型不稳定生成信号发散现象用估计出的AR或ARMA模型参数通过filter函数生成仿真信号时信号幅值急剧增大直至溢出。原因模型的极点落在了单位圆外对于AR部分或非常接近单位圆。这通常是由于参数估计算法数值不稳定特别是当自相关矩阵接近奇异时。信号本身非平稳或者包含了强趋势/周期分量未被有效去除。模型阶数选择过高导致过拟合参数估计误差大。排查与解决检查极点位置使用roots函数计算AR多项式A(z)的根并计算其模值。poles roots(estimated_ar); abs_poles abs(poles); if any(abs_poles 1) warning(模型不稳定存在单位圆外或上的极点。); % 可以将极点投影到单位圆内乘以一个略小于1的因子但这会改变频谱特性 poles_stable poles ./ (abs(poles) 1e-5); % 一种简单的稳定化方法 estimated_ar_stable poly(poles_stable); end预处理信号建模前务必对信号进行零均值化减去均值。如果信号有趋势先进行去趋势处理如减去线性拟合项或使用detrend函数。对于有明显周期性的信号考虑先进行带阻滤波或使用季节性ARIMA模型。降低模型阶数尝试使用BIC等更倾向于简约模型的准则或通过观察残差白噪声检验结果选择一个更低的、足以使残差近似为白噪声的阶数。使用更稳健的估计方法尝试使用Burg算法arburg函数估计AR参数它对短数据或某些情况可能比Yule-Walker方法更稳定。5.2 问题二谱估计出现负值或严重畸变现象由模型参数计算出的功率谱密度在某些频段为负值物理上不可能或谱峰位置、宽度与预期严重不符。原因参数估计不准根本原因还是模型参数误差大可能源于数据长度不足、信噪比低或模型阶数不当。MA参数估计困难MA部分的参数估计本身就是一个非线性难题容易陷入局部最优或得到不可逆的模型其谱可能为负。数值计算误差在计算频率响应freqz或进行多项式运算时高阶系数可能带来数值精度问题。排查与解决验证模型最小相位性对于ARMA模型确保估计出的模型是最小相位系统因果且逆因果稳定。可以检查B(z)的根是否都在单位圆内。如果不是谱可能会出现问题。一些估计算法如armax的默认设置会保证这一点。增加数据长度这是最根本的方法。参数估计的方差通常与数据长度N成反比。尝试用更长的数据段进行建模。尝试不同的初始值对于使用迭代优化算法的armax可以尝试提供不同的初始参数猜测看结果是否收敛到更合理的解。谱平滑如果只是个别频点出现微小负值可以将其置零或进行简单的频域平滑。但这只是掩盖问题并非根本解决。5.3 问题三残差检验始终无法通过现象无论怎么调整AR/ARMA模型的阶数(p,q)Ljung-Box检验的p值始终很小如0.05残差自相关图在滞后1或2处仍有明显超出置信区间的值。原因模型类型选择错误信号可能本质上不适合用线性ARMA模型刻画。例如存在非线性特性、突变点或异方差性。未考虑外部输入信号可能是一个受控系统的输出受到可观测输入的影响此时应使用ARX、ARMAX等带外部输入模型而非单纯的ARMA。数据中存在异常值个别离群点会严重干扰参数估计。排查与解决绘制残差序列图仔细查看残差是否存在明显的模式如周期性、成簇的波动异方差或孤立的尖峰异常值。尝试非线性检验可以计算残差的高阶矩或使用如BDS检验等非线性检验工具判断是否存在非线性依赖。处理异常值使用中值滤波、Hampel滤波器等方法识别并处理异常值或用稳健的估计方法对异常值不敏感。考虑更复杂的模型如果线性模型确实不适用可能需要研究非线性时间序列模型如阈值自回归、GARCH模型针对波动率等。5.4 问题四Matlab函数armax估计失败或报警告现象调用armax时返回错误如“迭代次数超限”、“矩阵接近奇异”或给出“模型不可辨识”的警告。原因与解决迭代次数超限默认的迭代次数可能不够。增加MaxIter选项的值。opt armaxOptions(Focus, prediction, MaxIter, 200); model armax(data, [p q], opt);矩阵接近奇异/模型不可辨识这通常意味着你尝试估计的模型阶数(p,q)对于当前数据来说太高了或者(p,q)的某种组合导致模型参数存在冗余例如AR和MA部分有近似对消的零极点。降低模型阶数是首选。尝试从低阶开始如(1,0), (1,1), (2,0)等逐步增加。也可以尝试先固定一个部分如先估计一个高阶AR模型再估计另一部分。初始条件敏感提供更好的初始参数猜测。可以从一个高阶AR模型的估计结果中通过长AR模型近似法得到ARMA参数的初始值。最后一个非常实用的调试技巧是分步验证先用一个已知参数的简单模型如AR(1)生成数据然后用你的代码去估计看能否准确恢复参数。这能快速定位是算法实现问题还是数据/模型本身的问题。参数建模是一个结合了理论、经验和反复调试的过程耐心和细致的分析往往比盲目尝试更有效。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进