简介:这是一份围绕ARMA模型的时间序列数据预测MATLAB资源包,面向有数据预测需求的财经、工程及科研学习者,旨在帮助使用者理解并实现自回归滑动平均模型的建模与预测过程。压缩包共包含12个文件(约322KB),其中10个txt文件为TCP、UDP、ICMP等多种网络流量指标的数据序列,可作为模型训练与验证的输入;1个m脚本承担数据读取、模型构建、参数估计及预测输出的核心功能;另有1个xls表格便于查看数据或整理结果。截至目前已有227人学习下载,具备一定的参考热度。借助该资源可掌握从平稳性检查、差分处理、ACF/PACF定阶到ARIMA建模预测的完整操作链路,并可通过真实数据对比不同参数下的预测效果,适合需要快速上手MATLAB时间序列分析的读者。
1. ARMA数据预测:为什么先跑通这个老模型,再谈深度学习
做数据预测的时候,很多人都想在Matlab里直接上一个“看起来厉害”的模型,但我的经验恰恰相反。拿到ARMA数据,先别急着堆特征,先用ARMA(自回归滑动平均模型)跑一条基线,它把历史值和过去几期的误差同时作为输入,输出未来的点预测和置信区间,一套流程下来不到五十行代码。ARMA虽然是上世纪提出的模型,但对平稳时间序列的短期预测依然稳,尤其在数据量不大、没有明显季节性的场景里,它比很多花哨模型更不容易翻车。这篇笔记适合刚接触时间序列预测、想在Matlab里把ARMA预测从数据预处理跑到预测结果落盘的人,也会把定阶、参数估计和那些让人头疼的坑一并说清。
2. ARMA建模第一步:平稳性检验与Matlab数据预处理
ARMA模型的数学假设非常明确:序列是平稳的。所谓平稳,直观理解就是序列的均值、方差和自相关结构不随时间发生系统性变化。为什么这个条件是硬门槛?因为ARMA只用历史值去线性组合,如果序列本身带着向上的趋势或者方差一直在变大,模型会把趋势误当成可预测的规律,结果就是预测值看起来拟合得很好,一旦趋势出现拐点就立刻崩掉。
一个典型误用是:在Matlab里直接把原始销量序列丢给arima函数,拟合出来的系数看起来都显著,预测曲线也对得上历史,但等到真正预测未来时,预测值要么发散,要么完全跟不上新数据的走向。这不是模型坏了,而是它从一开始就拟合了一个不平稳的过程。
2.1 平稳性是ARMA的命门:先看数据长什么样
拿到数据的第一步永远是用plot画一下原始曲线。我一般会把时序图、自相关图并排打印出来,先肉眼判断三个问题:有没有明显的递增或递减趋势?波动幅度是不是在不同区间差别很大?有没有以固定周期出现的波峰波谷?如果三个问题里中了任何一个,就不能直接进入ARMA建模。
这里有一个常见错觉,很多人以为只要趋势是线性的,ARMA就能自动处理。实际上ARMA的AR部分虽然能对趋势做一定程度的跟踪,但那只是用一条回归线去凑趋势,模型本身不具备差分能力。想要处理趋势,必须由建模的人在预处理阶段把趋势先去除,这也是ARMA和ARIMA最本质的差别:ARIMA自带差分项,ARMA不带。
提示:在Matlab里先用plot(1:length(y), y)看一眼原始序列,再决定要不要差分。这一眼看不出大问题,后面的adftest也会告诉你答案。
2.2 用adftest和kpss做单位根检验:两条命令锁定平稳性
肉眼判断不顶用的时候,就用统计检验说话。Matlab自带的adftest是做ADF单位根检验的,它的原假设是序列存在单位根(即非平稳),如果返回的h等于1,表示在给定显著性水平下拒绝原假设,说明序列已经平稳。与之互补的是kpss检验,它的原假设反过来,是序列平稳,所以两个检验一起看更稳妥。
这里给出一个最小可运行的Matlab数据处理脚本,用于读取数据并完成平稳性判断:
% load_data.m y = load('sales_data.txt'); % 用你解压后的ARMA数据替换文件名,列向量 y = y(:); % 强制转成列向量,arima函数只接受列向量 [h_adf, p_adf, stat_adf, cval_adf] = adftest(y); % ADF单位根检验 [h_kpss, p_kpss, stat_kpss, cval_kpss] = kpss(y, 'lags', 6); % KPSS平稳性检验 fprintf('ADF: h=%d, p=%.4f, 检验值=%.4f, 临界值=%.4f\n', ... h_adf, p_adf, stat_adf, cval_adf); fprintf('KPSS: h=%d, p=%.4f, 检验值=%.4f, 临界值=%.4f\n', ... h_kpss, p_kpss, stat_kpss, cval_kpss); if h_adf == 1 && h_kpss == 0 disp('序列通过平稳性检验,可以进入ARMA建模'); else disp('序列未通过平稳性检验,需要差分或变换'); end这段脚本里adftest返回四个值:h是结论、p是p值、stat是检验统计量、cval是临界值。kpss的lags参数控制检验用到的滞后阶数,对月度数据我一般设成12,对日度数据设成6到8,没有绝对标准,但不要不设直接跑,不同滞后值下结论可能不同。当ADF说平稳、KPSS也说平稳,才算是双保险通过。
这里有一点要特别注意:h等于1只是“在默认5%显著性水平上拒绝了原假设”。如果你把显著性水平改成0.01,h可能就变成0了。要不要把边界案例当平稳处理,取决于你对预测结果的要求,做基线模型时5%够用,做正式交付时建议把p值一并打出来给人看。另外,两个检验结论冲突也很常见:ADF说平稳但KPSS说非平稳,这时候可以再算一下一阶差分的检验结果,如果一阶差分后两者都通过,按一阶差分处理,因为业务上趋势项的存在比统计判断更直观。
2.3 差分与对数变换:非平稳数据怎么救回来
如果检验没通过,最常见的手段是对数变换加差分。对数变换适合方差随均值增长的数据,典型例子是点击量、销量、流量这类只能取正值的序列,先做log(y)能让波动幅度变得均匀。差分则专门对付趋势,一阶差分等价于计算相邻两个时间点的变化量,如果一阶差分后还不平稳,再做二阶差分。
差分操作在Matlab里就一行:dy = diff(y)。但有个细节容易忽略:差分后序列长度会少一个点,后续写预测代码时Y0的索引要注意对齐,否则做预测时模型内部用的滞后项会和你传进去的数据错位,导致的报错很隐蔽,我后面避坑章节会专门说。同时,预测完成之后,所有结果都必须做逆变换还原回原始量纲,差分结果要累加,对数结果要取指数,这一步漏掉的话,预测值看起来会和真实值差一个数量级。
% make_stationary.m y = load('sales_data.txt'); % 从ARMA数据压缩包解压出的原始序列,列向量 y = y(:); % 先处理方差问题 if min(y) > 0 ly = log(y); % 对数变换,压缩方差异质性 else ly = y; % 数据含非正值时只能用原始值 end % 再做差分直到通过adftest diff_order = 0; test_y = ly; while diff_order < 2 [h, p] = adftest(test_y); if h == 1 break; end test_y = diff(test_y); diff_order = diff_order + 1; end fprintf('最终差分阶数: %d\n', diff_order);这段脚本的循环逻辑是:从原始值开始,每做一次差分就重新做一次ADF检验,最多差分两阶。为什么上限设成2?因为实际业务数据里差分超过两阶之后,序列虽然“平稳”,但可预测的信息量已经被差得差不多了,继续差分只会把信号差成噪声。差分阶数每加一,模型就要多丢失一个样本点,为了一点点平稳性代价不划算。
到这里,预处理阶段就完成了。记住最后保留下来的那个test_y才是进入ARMA建模的输入,原始序列和变换过程要单独保存下来,因为预测完之后要把差分和对数还原回去,才能得到和原始数据同一个量纲的预测结果。这一步做完,你手里应该有一个长度缩短、均值恒定、波动幅度均匀的平稳序列,接下来才能放心地进入定阶环节。
3. 用Matlab完成ARMA定阶与参数估计:从ACF/PACF到arima函数
预处理做完,下一步就是确定ARMA(p,q)的阶数p和q。这一步是整个ARMA预测里最像“玄学”的部分,因为判断阶数有两种路径:一种是人眼看图,对ACF和PACF做截尾和拖尾分析;另一种是交给信息准则自动扫描。对新手来说,先把看图的方法学会,再去看自动定阶的结果,才不会在模型选择上完全失去判断力。
3.1 从自相关图和偏自相关图判断p和q:看图说话的门道
在Matlab里autocorr和parcorr两个函数直接画图,它们会在图上画出相关系数序列,并附带95%置信带。看图的核心规则是这样的:如果一个序列的ACF在q阶之后突然掉进置信带内不再有突出的峰值,称为“截尾”,而PACF衰减得很慢,称为“拖尾”,那这个序列适合MA(q)模型;反过来PACF在p阶截尾、ACF拖尾,适合AR(p);如果两个都拖尾,说明要用ARMA(p,q)。
这套规则说起来简单,实际操作时经常翻车,因为样本量不够大时,ACF和PACF会在置信带边缘晃来晃去,看起来像是截尾又像是拖尾。我见过不少人在这个环节纠结很久,甚至为了迎合某个阶数去反复调整数据长度。所以我的做法是:先按规则看图定一个候选区间,比如觉得p可能在1到3、q可能在0到2,然后把这个范围内的所有组合都交给AIC去比较,而不是只认死一组数字。图是给人找方向的,AIC才是给人做决定的。
这里可以直接用一个表格把规则和安全判断法列出来:
| 自相关图ACF | 偏自相关图PACF | 候选模型 |
|---|---|---|
| q阶截尾 | 逐渐衰减(拖尾) | MA(q) |
| 逐渐衰减(拖尾) | p阶截尾 | AR(p) |
| 逐渐衰减(拖尾) | 逐渐衰减(拖尾) | ARMA(p,q) |
| 完全无显著峰值 | 完全无显著峰值 | 白噪声,不适合ARMA |
表格最后一行很关键,很多人忽视:如果ACF和PACF都没有显著峰值,说明这个序列已经是白噪声,没有可提取的线性依赖关系,ARMA拟合上去只会得到一个常数,这种数据就不要浪费时间了。我把这种检查放在建模前,能省掉后面一大半的无效调参时间。
3.2 用arima函数拟合ARMA模型:最小可运行代码
Matlab的arima函数是Econometrics Toolbox里的核心接口,注意ARMA模型在Matlab里写作arima(p,0,q),中间那个0表示差分阶数为0。很多人一开始会用arima(p,1,q)去拟合原始序列,那其实是ARIMA模型,虽然也能跑通,但模型解释已经不同,预测前还要做积分还原,容易绕晕。
% fit_arma.m y = load('stationary_series.txt'); % 这是预处理完成后的平稳序列 y = y(:); p = 2; % AR阶数,由ACF/PACF或AIC确定 q = 1; % MA阶数,同上 Mdl = arima(p, 0, q); % 建立ARMA(p,q)模型对象 EstMdl = estimate(Mdl, y); % 极大似然估计模型参数 disp(EstMdl); % 输出系数、标准差、信息准则这段代码的要点在第3行和第4行。arima(p,0,q)的第二个参数就是差分阶数D,取0代表ARMA,取1代表ARIMA。estimate函数默认用极大似然估计,Matlab在估计过程中会输出迭代日志,你可以看到每一步的似然值和参数变化,如果日志里出现发散,通常是数据不平稳或者阶数太高,要回头检查预处理。
EstMdl里面主要的字段包括AR系数、MA系数、常数项和方差。解释一下:AR系数表示当前值受前几期自身值影响的程度,MA系数表示当前值受前几期误差影响的程度,常数项相当于序列的均值。系数估计出来后还要看一眼对应的标准差,如果标准差比系数本身还大,说明这个参数估计得很不稳,可以考虑降低阶数重新拟合。一个实用的经验是:p和q的取值尽量不要超过样本量开根号,100个点就选1到3之间的阶数,超出这个范围的结果基本都不可信。
一个非常容易踩的坑:arima函数不接受数据里有NaN值。如果你的原始数据里有缺失值,必须先处理掉,常见做法是插值或者用之前的值填充,但无论哪种方式都会改变数据分布,所以要在预处理阶段把这个操作明确记录下来。我一般会在数据文件旁边放一个processing_notes.txt,记录每一步变换,方便几周之后回看还能对上。
3.3 残差白噪声检验:模型能不能用,看这一项就够了
模型拟合完,永远不要直接去预测。先拿拟合好的模型对历史数据做一遍“回头看”,算出每个时间点模型估计值与真实值的差距,也就是残差。一个合格的ARMA模型,其残差应当是白噪声序列,意思是残差之间不存在任何自相关关系。如果残差里还有结构,说明模型没有提取干净时间依赖,预测结果必然有偏。
Matlab里用infer函数提取残差,再用lbqtest做Ljung-Box检验:
% check_residual.m res = infer(EstMdl, y); % 用拟合好的模型反推残差 % 画残差自相关图,肉眼确认近似白噪声 autocorr(res); % Ljung-Box检验:原假设是残差无自相关 [h_lb, p_lb] = lbqtest(res, 'Lags', [5 10 15]); fprintf('Ljung-Box: h=%d, p=%.4f\n', h_lb(1), p_lb(1)); if h_lb(1) == 0 disp('残差通过白噪声检验,模型可接受'); else disp('残差仍存在自相关,考虑增大p或q,或检查季节成分'); end这段代码里infer(EstMdl, y)返回的是条件方差和残差,用变量接收时默认拿到残差序列。lbqtest的Lags参数可以指定要检验的滞后阶数,我这里一次检验了5、10、15三个延迟,任何一组显著都说明残差不白。p值大于0.05时不能拒绝无自相关的原假设,模型算是过关,否则就要回到定阶步骤重新搜索。
残差检验的一个补充操作是画一下残差的正态概率图,用qqplot(res)就能看出来是否有离群点。ARMA的系数估计并不严格要求正态,但极大似然估计的置信区间推导基于近似正态,残差偏离太远会让预测区间的可信度打折。如果只是零星几个离群点,问题不大;如果残差整体呈现偏态或者重尾,我就要回头检查数据里是不是混入了异常日期或突变点。
4. 用forecast做ARMA预测:一步预测、多步预测与滚动预测怎么落地
模型通过残差检验后,预测就是最后一步。forecast是Matlab里做ARMA/ARIMA预测的官方函数,它基于模型的结构化递推公式,不需要你自己手写预测方程。但要注意,forecast处理的是平稳序列的预测,如果你的数据经过差分和对数变换,预测结果必须先还原,再和原始数据比较。
4.1 forecast函数的最小代码:预测未来N个点
最常见做法是:把历史数据y传给forecast的Y0参数,指定要预测的步数num_periods,函数返回未来num_periods个点的预测值。这里的关键是Y0必须包含模型所需的全部滞后信息,举个例子,ARMA(2,1)模型预测第1个未来点时,需要用到最近2个历史值和最近1个误差,如果你把Y0砍得太短,forecast会直接报错。
% arma_forecast.m y = load('stationary_series.txt'); % 平稳化处理后的ARMA数据 y = y(:); p = 2; q = 1; % 刚才定的阶数 Mdl = arima(p, 0, q); EstMdl = estimate(Mdl, y); num_periods = 10; % 预测未来10个时间点 [YF, YMSE] = forecast(EstMdl, num_periods, 'Y0', y); % 计算95%置信区间 z = 1.96; lower = YF - z * sqrt(YMSE); upper = YF + z * sqrt(YMSE); % 绘图对比 t = (length(y)+1 : length(y)+num_periods)'; plot(t, YF, 'r-o', 'LineWidth', 1.5); hold on; plot(t, lower, 'k--', t, upper, 'k--'); legend('预测值', '95%下限', '95%上限');这里forecast的返回值有两个:YF是点预测值,YMSE是预测均方误差。预测均方误差随预测步数增加而增大,所以置信区间会呈现一种喇叭口形态。这是ARMA的正常现象,代表模型对远期预测的信心天然不足。如果你看到区间大到无法接受,说明要么数据本身噪声太大,要么模型没有充分捕捉规律,这两种情况下换复杂的深度学习模型也不一定有用,先把数据质量问题解决。
4.2 预测区间怎么解读:别只盯着那条预测曲线
很多人在拿到预测结果后只截图看那条红色曲线,这是不对的。预测模型给出的不是一个确定值,而是一个置信区间,ARMA的预测本质上是用条件期望描述最可能的位置,再用方差描述不确定性。比如你要拿预测值去做库存决策,应当直接把下限和上限用到安全库存计算里,而不是用点预测值加一个拍脑袋的安全系数。
如果YMSE显示区间特别窄,有两种可能:一是模型确实拟合得好,预测可信;二是模型过拟合了历史噪声,把本来不该学的波动学进去了,发生了“伪自信”。区分两者的办法是留出一段历史数据不参与拟合,然后拿它和预测值比较,看看真实值落在区间内的频率是否接近95%。这个回测步骤虽然多花几分钟,但能有效避免把过拟合当成好的预测。
注意:预测区间的宽度和预测步数强相关,多步预测的区间在步数递增时必然变宽。如果你用滚动预测,每一步的区间宽度才是一致的,所以业务上对长期预测不要期待窄区间。
4.3 滚动预测:边预测边更新窗口的实战做法
一次性预测未来10个点叫多步预测,但实际业务中更常见的是滚动预测:每次只预测下一步,等这一步的真实值拿到后,把它追加到历史窗口里重新估计模型,再预测下一步。滚动预测的好处是模型始终在用最新数据,对结构和缓变的序列尤其有效。
% rolling_forecast.m y = load('stationary_series.txt'); y = y(:); window = 120; % 滚动窗口长度:至少大于 p+q,经验值取数据长度的2/3 num_future = 20; % 滚动预测的总步数 pred = zeros(num_future, 1); for i = 1:num_future train_data = y(end-window+1:end); % 当前窗口 Mdl = arima(2, 0, 1); EstMdl = estimate(Mdl, train_data, 'Display', 'off'); [YF, ~] = forecast(EstMdl, 1, 'Y0', train_data); pred(i) = YF(1); % 真实数据出来后,把这一步的真实值追加到 y 序列末尾 % 这里假设你有一份 future_actual 保存了未来真实值 % y = [y; future_actual(i)]; end这段代码里window的取值是一个需要反复试的参数。窗口太小,估计方差大,模型不稳定;窗口太大,模型对数据变化反应迟钝。我通常的做法是先取一个大致值跑一遍回测,然后按步长10去搜索最优窗口长度。另一个细节是estimate函数在循环里每次都重新估计参数,计算量比只估计一次大不少,如果数据量和预测步数都很大,可以考虑每5步重新估计一次,中间几步直接用上一次的模型参数,速度会快很多,精度损失通常可接受。
滚动预测的代码中有个容易被人忽略的问题:你拿真实值去更新y,但ARMA模型估计时用的残差全部来自训练数据,下一步预测时模型并不知道上一步的预测误差是多少。想让它知道,就需要在循环中把上一步真实值和预测值的差作为MA项的新误差喂给模型,这已经属于状态更新的范畴,Matlab的arima函数不直接支持,一个替代方案是用simulate配合已知残差来做条件模拟,复杂度较高,基线预测不必强求。
5. ARMA实战避坑指南:5个最容易翻车的地方
ARMA看起来简单,真正落地时坑不少。下面这5个是我在Matlab里反复踩过的,每条都按现象、原因、解决的顺序写,可以作为你排查预测结果时的检查清单。
5.1 翻车点一:拿非平稳数据直接拟合
现象:模型在训练集上表现非常好,拟合曲线几乎贴着真实值走,但一预测未来就开始发散,或者预测值越来越平。这个现象最迷惑人,因为训练阶段没有任何报错,参数估计也正常收敛。
原因:原始序列带有趋势项,ARMA把趋势当成可以利用的规律学了进去。对短期预测来说,趋势似乎还在,预测结果勉强能用;一旦预测步数变长,模型预测的不是趋势的延续,而是趋势在AR系数作用下的指数放大或衰减,所以发散。
解决:别跳过adftest这一步。直接对原始数据跑一遍adftest,h=1再建模。如果序列确实不平稳,就做一阶差分,然后对差分后序列建模,预测后再累加还原。这个流程多写两行代码,但能避免一大类说不清的预测失败。
5.2 翻车点二:阶数定太高导致过拟合
现象:ACF和PACF图上好几个柱子都稍微超出置信带,你觉得p和q都大到可以建模,结果拟合时部分系数不显著,预测区间宽到没有价值。
原因:样本量有限时,自相关估计本身有波动,5%的置信水平意味着平均每20个滞后里就有1个柱子“假装显著”。把这些噪声柱子当成真实依赖关系,就会多估计好几个本不存在的AR或MA项。系数一多,模型方差变大,预测自然不稳。
解决:遵守一个经验法则:p+q最多不超过样本量的平方根。100个样本点的情况下,p和q都往1、2这个量级选,不要超过4。同时用AIC做横向比较,AIC每多一个参数会加惩罚,AIC最小的组合通常比人眼判断更靠谱。我在定阶时会把AIC前5名打出来,如果第一名比第二名多用了3个参数但AIC只小了一点点,我就会选第二名。
5.3 翻车点三:预测结果比真实值滞后一拍
现象:你把预测曲线和真实曲线叠在一起看,发现预测曲线像是真实曲线向右平移了一个时间点,波峰波谷都对得上,但永远慢一步。
原因:这对ARMA来说是“正常现象”,不是bug。ARMA本质是历史值的加权平均,它对突变无能为力,只能预测趋势的惯性。遇到拐点、突增、突降时,模型必然要等真实值先变,然后才在下一步修正回来。
解决:接受这个特性,并把预测区间用起来。在有突变的业务场景里,把预测值标记为“趋势参考”而不是“准确发生值”,再用异常检测或人工复核去处理突变点。想做超前预测,就只能引入外部协变量或者切换到能处理非线性跳变的模型。这不是ARMA的缺陷,而是所有线性模型共同的边界。
5.4 翻车点四:残差检验没过就把模型拿去上线
现象:预测值在大部分时间都准,但每隔一段会出现系统性偏差,比如连续几天预测值偏低,然后恢复正常。
原因:残差里还残留着自相关或季节性,说明ARMA模型没有把数据里的依赖结构提取干净。最常见的是周期成分,比如按周的周期性在ACF的滞后7、14处有明显的正峰值,而你在建模时完全没处理周期项。
解决:拟合完成后,跑一下infer+lbqtest,如果p值小于0.05,回到定阶流程,先考虑是否要给序列加季节性差分,或者改用SARIMA(带季节性ARMA)。在纯ARMA框架里,也可以把周期均值作为外生变量去掉,再做差分。上线之前多花两分钟做残差检验,比上线后被人投诉预测失准要划算得多。
5.5 翻车点五:把ARMA当万能模型硬套
现象:对波动率序列、金融收益序列建模时,预测区间窄得让人不敢相信,但真实值频繁落在区间之外。
原因:ARMA建模的是条件均值,假设方差恒定。但像收益率、部分流量数据这类序列,方差本身会聚集,大波动后跟着大波动,小波动后跟着小波动,这个现象叫波动聚集,ARMA完全没有处理能力。
解决:先对残差平方做lbqtest,如果显示显著自相关,说明数据存在条件异方差,这时可以考虑ARMA-GARCH模型组合。Matlab里garch函数可以单独拟合GARCH项,用它对接ARMA残差的方差部分。不过这种组合的参数估计更敏感,样本量不够时非常容易过拟合,不是默认选项。我的建议是,先确认自己的业务数据是不是真的方差不恒定,再决定要不要上这个复杂度。
6. 用AIC自动定阶:Matlab里把ARMA预测流程串成一条龙
在定阶这件事上,最实用的技巧是在Matlab里写一个循环,把p和q的所有组合扫一遍,再用AIC排序,这样既验证了第3章看图得出的候选范围,也能在样本量不足时保持相对客观的模型选择标准。
% auto_select.m y = load('stationary_series.txt'); y = y(:); pmax = 4; qmax = 4; results = []; for p = 0:pmax for q = 0:qmax if p == 0 && q == 0 continue; % 白噪声模型,跳过 end try Mdl = arima(p, 0, q); EstMdl = estimate(Mdl, y, 'Display', 'off'); [~, ~, LogL] = infer(EstMdl, y); % AIC = -2*LogL + 2*k,k是参数个数 k = p + q + 1; % 含常数项的粗略估计 aic = -2 * LogL + 2 * k; results = [results; p, q, aic]; catch fprintf('p=%d, q=%d 估计失败\n', p, q); end end end results = sortrows(results, 3); % 按AIC升序排列 disp(results(1:5, 1:3));这段代码里infer的第三个返回参数是对数似然值LogL,AIC的计算公式是负两倍对数似然加两倍参数个数。参数个数这里粗略用p+q+1,因为除了AR和MA系数外还有一个常数项,严格一点还要加上回归系数和方差参数,但对模型排序影响不大,关键是所有组合用同一个口径比较才公平。
循环里用try-catch是必须的,因为有些p和q组合(比如p=0,q=4)在数值优化时会碰到收敛困难,estimate会报错。把报错吞掉并继续扫描,是自动定阶的标准处理。跑完之后,results的前5行就是AIC排名从低到高的模型组合,结合起来看基本能确定最终阶数。
我自己现在的习惯是,图上看的结论只用来决定搜索范围,真正的模型选择交给AIC排序,结果列在控制台里后我会手动看前5名的残差检验。遇到过好几次这样的情况:AIC排名第一的模型残差没通过检验,排名第二的反而过了,这种时候就选第二,因为一个残差有问题的模型AIC再小也不该上线。不同组合之间AIC差值如果小于2,通常认为没有显著差别,这时我优先选阶数更低的那个,也就是更节省参数的模型。
这套流程不仅适用于ARMA,你后面做ARIMA、带外生变量的回归模型,甚至深度学习matlab里的LSTM超参数搜索,都可以复用“先扫参数范围、再按指标排序、最后人工复核”的思路。先把一条路走通,再在它上面做扩展,是数据预测算法里最稳妥的学习路线。希望帮到你。
本文还有配套的精品资源,点击获取