AR、MA 与 ARMA 模型识别
下面的辅助函数分别整理ADF检验的\(p\)值、ACF/PACF数值、参数估计与Ljung–Box检验结果,并统一绘制诊断图和预测图。函数代码作为实验的一部分完整展示,便于读者直接复现计算。
adf_result_table <- function(x, series_name) {
test <- tseries::adf.test(as.numeric(na.omit(x)))
data.frame(
Series = series_name,
LagOrder = unname(test$parameter),
PValue = unname(test$p.value),
row.names = NULL
)
}
correlation_table <- function(x, lag_max = 10L) {
data.frame(
Lag = seq_len(lag_max),
ACF = as.numeric(acf(x, lag.max = lag_max, plot = FALSE)$acf)[-1],
PACF = as.numeric(pacf(x, lag.max = lag_max, plot = FALSE)$acf),
Approximate95PercentBound = 1.96 / sqrt(length(x)),
row.names = NULL
)
}
coefficient_table <- function(model) {
standard_errors <- sqrt(diag(model$var.coef))
z_statistics <- coef(model) / standard_errors
data.frame(
Term = names(coef(model)),
Estimate = unname(coef(model)),
StandardError = unname(standard_errors),
PValue = unname(2 * pnorm(-abs(z_statistics))),
row.names = NULL
)
}
ljung_box_table <- function(model, lag, fitdf) {
test <- Box.test(
na.omit(residuals(model)),
lag = lag,
type = "Ljung-Box",
fitdf = fitdf
)
data.frame(
Lag = lag,
Statistic = unname(test$statistic),
DegreesOfFreedom = unname(test$parameter),
PValue = unname(test$p.value),
row.names = NULL
)
}
forecast_table <- function(prediction) {
data.frame(
Horizon = seq_along(prediction$pred),
PointForecast = as.numeric(prediction$pred),
Lower95 = as.numeric(prediction$pred - 1.96 * prediction$se),
Upper95 = as.numeric(prediction$pred + 1.96 * prediction$se),
row.names = NULL
)
}
plot_acf_pacf <- function(x, series_name) {
old_par <- par(mfrow = c(1, 2), mar = c(4, 4, 3, 1))
acf(
as.numeric(x),
lag.max = 20,
col = colour_main,
main = paste("ACF:", series_name)
)
pacf(
as.numeric(x),
lag.max = 20,
col = colour_smooth,
main = paste("PACF:", series_name)
)
par(old_par)
}
plot_residuals <- function(model, model_name) {
model_residuals <- na.omit(residuals(model))
old_par <- par(mfrow = c(1, 2), mar = c(4, 4, 3, 1))
plot(
model_residuals,
type = "l",
lwd = 1.2,
col = colour_main,
main = paste(model_name, "Residuals"),
xlab = "Time",
ylab = "Residual"
)
abline(h = 0, lty = 2, col = "grey45")
acf(
as.numeric(model_residuals),
lag.max = 20,
col = colour_smooth,
main = paste("Residual ACF:", model_name)
)
par(old_par)
}
plot_forecast <- function(observed, prediction, title, y_label) {
point_forecast <- prediction$pred
lower <- point_forecast - 1.96 * prediction$se
upper <- point_forecast + 1.96 * prediction$se
plot(
observed,
type = "l",
lwd = 1.4,
col = colour_main,
xlim = range(c(time(observed), time(point_forecast))),
ylim = range(c(observed, lower, upper), na.rm = TRUE),
main = title,
xlab = "Time",
ylab = y_label
)
polygon(
c(time(point_forecast), rev(time(point_forecast))),
c(lower, rev(upper)),
border = NA,
col = grDevices::adjustcolor(colour_smooth, alpha.f = 0.22)
)
lines(point_forecast, lwd = 1.6, col = colour_smooth)
legend(
"topleft",
legend = c("Observed", "Forecast", "95% interval"),
col = c(colour_main, colour_smooth, NA),
lty = c(1, 1, NA),
lwd = c(1.4, 1.6, NA),
fill = c(
NA,
NA,
grDevices::adjustcolor(colour_smooth, alpha.f = 0.22)
),
border = NA,
bty = "n"
)
}本实验用三个彼此独立的真实时间序列,完成从原始数据、平稳性判断、ACF与PACF识别,到模型拟合、残差诊断和预测的完整过程。重点是根据样本相关图提出一个有统计依据的低阶模型,而不是自动搜索模型或比较信息准则。
三个实验使用统一的识别逻辑:AR模型的ACF通常逐渐衰减而PACF近似截尾;MA模型的ACF近似截尾而PACF逐渐衰减;ARMA模型的ACF和PACF通常都不在某个很低的阶数后突然消失。样本相关图不会完全复制理论图形,因而应结合相邻滞后的整体形态,而不能根据某一根偶然越过置信界限的竖线机械判断。
平稳性辅助判断采用tseries::adf.test()。该实现以“序列具有单位根”为原假设、以“序列平稳”为备择假设,在检验回归中包含常数项和线性趋势项,默认滞后阶数为\(\lfloor(n-1)^{1/3}\rfloor\)。下面直接报告\(p\)值,并与5%显著性水平比较:\(p<0.05\)时拒绝单位根原假设。ADF检验只作为时间序列图和ACF之外的辅助证据。
实验一:AR模型
原始序列与平稳性
R自带的lh数据记录一名女性血样中黄体生成素的浓度,共连续观测48次,相邻观测间隔10分钟。时间坐标表示观测次序,而不是年份。
ar_series <- datasets::lh
data.frame(
Series = "lh",
Observations = length(ar_series),
FirstObservation = start(ar_series)[1],
LastObservation = end(ar_series)[1],
SamplingIntervalMinutes = 10
) Series Observations FirstObservation LastObservation SamplingIntervalMinutes
1 lh 48 1 48 10
plot(
ar_series,
type = "l",
lwd = 1.4,
col = colour_main,
main = "Luteinizing Hormone Level",
xlab = "Observation number",
ylab = "Hormone level"
)序列在1.4至3.5之间上下波动,没有持续趋势或随时间扩大的波动幅度。ADF检验得到\(p=0.0462\),在5%水平拒绝单位根原假设,不过这一结果接近\(0.05\)的判断界限。结合时间序列图,没有必要再作差分;原序列直接作为平稳工作序列。
adf_result_table(ar_series, "lh") Series LagOrder PValue
1 lh 3 0.046242
ACF、PACF与阶数判断
plot_acf_pacf(ar_series, "Hormone Level")correlation_table(ar_series, lag_max = 10L) Lag ACF PACF Approximate95PercentBound
1 1 0.5755245 0.575524 0.2829
2 2 0.1818182 -0.223410 0.2829
3 3 -0.1447552 -0.226940 0.2829
4 4 -0.1748252 0.102768 0.2829
5 5 -0.1496503 -0.075934 0.2829
6 6 -0.0209790 0.067558 0.2829
7 7 -0.0202797 -0.104170 0.2829
8 8 -0.0041958 0.012014 0.2829
9 9 -0.1356643 -0.187687 0.2829
10 10 -0.1538462 0.002551 0.2829
样本ACF在第1阶为\(0.5755\),随后迅速减弱并以正负交替的小幅相关逐渐趋近于零,表现为较快的拖尾。PACF只有第1阶的\(0.5755\)越过约\(\pm0.2829\)的置信界限,第2阶及以后均落在界限内,因而呈现清楚的一阶截尾特征。这一组合与AR(1)模型最为一致。
模型拟合
ar_model <- arima(
ar_series,
order = c(1, 0, 0),
include.mean = TRUE,
method = "ML"
)
coefficient_table(ar_model) Term Estimate StandardError PValue
1 ar1 0.57394 0.11614 7.7414e-07
2 intercept 2.41326 0.14662 7.1301e-61
data.frame(InnovationVariance = ar_model$sigma2) InnovationVariance
1 0.19749
AR系数估计为\(0.5739\),标准误为\(0.1161\),近似双侧检验得到\(p<0.001\),说明一阶线性依赖十分明确。均值参数估计为\(2.4133\),其\(p<0.001\)。arima()输出的intercept是平稳序列的均值参数,而不是非中心化方程中的常数项;估计模型应写为
\[ X_t-2.4133=0.5739(X_{t-1}-2.4133)+\varepsilon_t, \qquad \widehat{\sigma}^2_{\varepsilon}=0.1975. \]
残差诊断
plot_residuals(ar_model, "Hormone Level AR(1)")ljung_box_table(ar_model, lag = 10L, fitdf = 1L) Lag Statistic DegreesOfFreedom PValue
1 10 9.3564 9 0.40505
残差围绕零波动,前20阶残差ACF全部位于约\(\pm0.2829\)的置信界限内。10阶Ljung–Box统计量为\(9.3564\),自由度为9,\(p=0.4050\),没有证据拒绝残差无自相关的原假设。因此,AR(1)已经提取了该序列中主要的线性时间依赖;这里的“近似白噪声”仅指没有发现剩余线性自相关,并不等同于证明残差彼此独立。
向前预测
ar_prediction <- predict(ar_model, n.ahead = 8L)
forecast_table(ar_prediction) Horizon PointForecast Lower95 Upper95
1 1 2.6926 1.8216 3.5636
2 2 2.5736 1.5693 3.5779
3 3 2.5053 1.4608 3.5498
4 4 2.4661 1.4087 3.5234
5 5 2.4436 1.3820 3.5052
6 6 2.4307 1.3677 3.4936
7 7 2.4232 1.3598 3.4867
8 8 2.4190 1.3554 3.4826
plot_forecast(
ar_series,
ar_prediction,
"AR(1) Forecast for Hormone Level",
"Hormone level"
)点预测从\(2.6926\)逐步回到长期均值\(2.4133\)附近,这是平稳AR(1)多步预测的典型形态;随着预测步长增加,预测区间先扩张,然后逐渐接近长期预测不确定性。
实验二:MA模型
原始序列与一阶差分
R自带的Nile数据记录1871年至1970年阿斯旺的尼罗河年流量,单位为\(10^8\ \mathrm{m}^3\)。原始图在约1898年前后出现明显的水平变化,均值稳定性值得怀疑。
ma_series <- datasets::Nile
ma_working <- diff(ma_series)
data.frame(
Series = "Nile",
Observations = length(ma_series),
FirstYear = start(ma_series)[1],
LastYear = end(ma_series)[1],
Unit = "10^8 cubic metres"
) Series Observations FirstYear LastYear Unit
1 Nile 100 1871 1970 10^8 cubic metres
old_par <- par(mfrow = c(1, 2), mar = c(4, 4, 3, 1))
plot(
ma_series,
type = "l",
lwd = 1.4,
col = colour_main,
main = "Annual Nile Flow",
xlab = "Year",
ylab = expression(Flow ~ (10^8 ~ m^3))
)
plot(
ma_working,
type = "l",
lwd = 1.2,
col = colour_accent,
main = "First Difference of Annual Nile Flow",
xlab = "Year",
ylab = "First difference"
)par(old_par)原序列ADF检验得到\(p=0.0642\),在5%水平不能拒绝单位根原假设。作一次普通一阶差分后,序列围绕零上下波动,没有继续差分的图形理由;差分序列的ADF检验输出\(p=0.0100\),并提示真实\(p\)值小于该数值。因而可以拒绝单位根原假设,后续对\(W_t=Y_t-Y_{t-1}\)进行相关结构识别。
rbind(
adf_result_table(ma_series, "Nile level"),
adf_result_table(ma_working, "First difference")
) Series LagOrder PValue
1 Nile level 4 0.064195
2 First difference 4 0.010000
ACF、PACF与阶数判断
plot_acf_pacf(ma_working, "First Difference of Nile Flow")correlation_table(ma_working, lag_max = 10L) Lag ACF PACF Approximate95PercentBound
1 1 -0.40204263 -0.402043 0.19699
2 2 -0.04427462 -0.245613 0.19699
3 3 0.02740458 -0.118706 0.19699
4 4 -0.08789743 -0.173308 0.19699
5 5 0.00050262 -0.155406 0.19699
6 6 0.04652927 -0.073677 0.19699
7 7 -0.13322828 -0.220527 0.19699
8 8 0.23116331 0.073627 0.19699
9 9 -0.08493644 0.016780 0.19699
10 10 -0.18486616 -0.234254 0.19699
差分序列ACF在第1阶为\(-0.4020\),明显越过约\(\pm0.1970\)的置信界限;第2阶起大部分相关已经接近零。第8阶的\(0.2312\)是一个孤立的样本尖峰,并没有形成连续衰减结构。与此相对,PACF从\(-0.4020\)、\(-0.2456\)开始,随后以较小的负相关总体向零衰减,表现为拖尾。因而,这里将ACF解释为近似一阶截尾,并为差分序列选择MA(1)模型;对原始流量而言,这就是无漂移的ARIMA(0,1,1)模型。
模型拟合
ma_model <- arima(
ma_series,
order = c(0, 1, 1),
include.mean = FALSE,
method = "ML"
)
coefficient_table(ma_model) Term Estimate StandardError PValue
1 ma1 -0.73294 0.11432 0.00000000014431
data.frame(InnovationVariance = ma_model$sigma2) InnovationVariance
1 20600
MA系数估计为\(-0.7329\),标准误为\(0.1143\),近似双侧检验得到\(p<0.001\)。工作序列的估计方程为
\[ W_t=\varepsilon_t-0.7329\varepsilon_{t-1}, \qquad W_t=Y_t-Y_{t-1}, \qquad \widehat{\sigma}^2_{\varepsilon}=20599.9. \]
残差诊断
plot_residuals(ma_model, "Nile ARIMA(0,1,1)")ljung_box_table(ma_model, lag = 10L, fitdf = 1L) Lag Statistic DegreesOfFreedom PValue
1 10 13.387 9 0.14585
残差ACF没有持续的拖尾,第10阶相关\(-0.1978\)仅略微越过约\(\pm0.1960\)的界限。10阶Ljung–Box统计量为\(13.3873\),自由度为9,\(p=0.1459\),整体上没有证据拒绝无自相关原假设。综合判断,ARIMA(0,1,1)已经提取了主要线性依赖;孤立的边界尖峰提醒我们,“近似白噪声”是有限样本下的判断,而不是所有样本相关恰好为零。
向前预测
ma_prediction <- predict(ma_model, n.ahead = 8L)
forecast_table(ma_prediction) Horizon PointForecast Lower95 Upper95
1 1 798.37 517.05 1079.7
2 2 798.37 507.20 1089.5
3 3 798.37 497.66 1099.1
4 4 798.37 488.42 1108.3
5 5 798.37 479.44 1117.3
6 6 798.37 470.71 1126.0
7 7 798.37 462.21 1134.5
8 8 798.37 453.92 1142.8
plot_forecast(
ma_series,
ma_prediction,
"ARIMA(0,1,1) Forecast for Annual Nile Flow",
expression(Flow ~ (10^8 ~ m^3))
)无漂移ARIMA(0,1,1)的8个点预测均为\(798.367\),而预测区间随步长逐渐变宽。点预测保持不变并不表示未来流量没有波动;它表示在模型给定的信息下,未来创新的条件均值为零,而累积的不确定性仍在增加。
实验三:ARMA模型
原始序列与平稳性
fpp3::us_change记录美国消费、收入、生产、储蓄和失业率等经济变量的季度百分比变动。本实验使用1970年第1季度至2019年第2季度的失业率变动序列,共198个观测。这里分析的是“失业率的季度变动”,而不是失业率水平本身。
unemployment_data <- as.data.frame(fpp3::us_change)
quarter_label <- as.character(unemployment_data$Quarter[1])
start_year <- as.integer(substr(quarter_label, 1L, 4L))
start_quarter <- as.integer(sub(".*Q", "", quarter_label))
arma_series <- ts(
unemployment_data$Unemployment,
start = c(start_year, start_quarter),
frequency = 4
)
arma_working <- arma_series
data.frame(
Series = "Quarterly change in US unemployment",
Observations = length(arma_series),
FirstQuarter = "1970 Q1",
LastQuarter = "2019 Q2"
) Series Observations FirstQuarter LastQuarter
1 Quarterly change in US unemployment 198 1970 Q1 2019 Q2
plot(
arma_series,
type = "l",
lwd = 1.4,
col = colour_main,
main = "Quarterly Change in US Unemployment",
xlab = "Year",
ylab = "Percentage change"
)
abline(h = 0, lty = 2, col = "grey45")序列大部分时间围绕零上下波动,没有持续趋势,也没有需要季节差分的稳定季度周期;少数经济冲击时期出现较大的正负变动。ADF检验输出\(p=0.0100\),并提示真实\(p\)值小于该数值,因此在5%水平拒绝单位根原假设。原序列已经适合作为平稳工作序列,不作额外差分或去趋势。
adf_result_table(arma_series, "US unemployment change") Series LagOrder PValue
1 US unemployment change 5 0.01
ACF、PACF与混合结构
plot_acf_pacf(arma_working, "US Unemployment Change")correlation_table(arma_working, lag_max = 20L) Lag ACF PACF Approximate95PercentBound
1 1 0.52372878 0.5237288 0.13929
2 2 0.38341180 0.1503634 0.13929
3 3 0.24686847 -0.0035125 0.13929
4 4 0.03281128 -0.1883304 0.13929
5 5 -0.00481512 0.0056000 0.13929
6 6 0.01474097 0.0900630 0.13929
7 7 -0.00030809 0.0131158 0.13929
8 8 -0.16058403 -0.2744015 0.13929
9 9 -0.10416163 0.0380855 0.13929
10 10 -0.11320628 0.0465084 0.13929
11 11 -0.17831235 -0.0861485 0.13929
12 12 -0.12564840 -0.0726362 0.13929
13 13 -0.12829722 -0.0388179 0.13929
14 14 -0.09556564 0.0747686 0.13929
15 15 -0.12491507 -0.0881683 0.13929
16 16 -0.10197295 -0.0995464 0.13929
17 17 -0.05268364 0.0679308 0.13929
18 18 -0.03725462 0.0672445 0.13929
19 19 -0.00263431 -0.0590087 0.13929
20 20 -0.02027515 -0.1133737 0.13929
ACF前3阶依次为\(0.5237\)、\(0.3834\)和\(0.2469\),先逐步衰减而不是在第1阶突然截尾;随后出现一段接近零的相关,又在第8至16阶形成较小的负相关尾部。PACF前两阶为\(0.5237\)和\(0.1504\),第4阶和第8阶分别为\(-0.1883\)和\(-0.2744\),其余多为较小的正负相关。两幅图都没有呈现纯AR或纯MA模型那种整齐、低阶的截尾,而是带有逐渐减弱和零星波动的拖尾形态。因此先考虑同时包含一阶AR和一阶MA项的最简混合模型ARMA(1,1)。
为了检验这一图形判断,下面只检查两个最直接的纯模型候选AR(1)和MA(1)是否留下明显相关。这是对ACF/PACF解释的针对性核验,不是枚举模型或按信息准则选阶。
arma_ar1 <- arima(
arma_working,
order = c(1, 0, 0),
include.mean = TRUE,
method = "ML"
)
arma_ma1 <- arima(
arma_working,
order = c(0, 0, 1),
include.mean = TRUE,
method = "ML"
)
rbind(
AR1 = ljung_box_table(arma_ar1, lag = 20L, fitdf = 1L),
MA1 = ljung_box_table(arma_ma1, lag = 20L, fitdf = 1L)
) Lag Statistic DegreesOfFreedom PValue
AR1 20 30.309 19 0.04799336
MA1 20 49.541 19 0.00015305
AR(1)残差的20阶Ljung–Box检验得到\(Q=30.3092\)、\(p=0.0480\),在5%水平刚好拒绝无自相关原假设;MA(1)残差得到\(Q=49.5413\)、\(p=0.00015\),明确留下了线性自相关。两个最简单的纯模型都没有充分解释相关结构,这支持在低阶模型中同时保留AR项和MA项。
模型拟合
arma_model <- arima(
arma_working,
order = c(1, 0, 1),
include.mean = TRUE,
method = "ML"
)
coefficient_table(arma_model) Term Estimate StandardError PValue
1 ar1 0.6977231 0.081986 1.7352e-17
2 ma1 -0.2221954 0.103057 3.1080e-02
3 intercept 0.0081231 0.055650 8.8395e-01
data.frame(InnovationVariance = arma_model$sigma2) InnovationVariance
1 0.094321
AR系数估计为\(0.6977\),标准误为\(0.0820\),近似双侧检验的\(p<0.001\);MA系数估计为\(-0.2222\),标准误为\(0.1031\),\(p=0.0311\)。因此AR项和MA项都提供了可辨认的线性信息。intercept给出的平稳序列均值估计为\(0.0081\),标准误为\(0.0557\),\(p=0.8839\),与序列围绕零波动的图形一致。以\(\mu=0.0081\)表示均值,估计模型为
\[ X_t-\mu=0.6977(X_{t-1}-\mu)+\varepsilon_t -0.2222\varepsilon_{t-1}, \qquad \widehat{\sigma}^2_{\varepsilon}=0.0943. \]
残差诊断
plot_residuals(arma_model, "Unemployment Change ARMA(1,1)")ljung_box_table(arma_model, lag = 20L, fitdf = 2L) Lag Statistic DegreesOfFreedom PValue
1 20 25.509 18 0.11152
残差大体围绕零波动,前20阶残差ACF不再表现出连续衰减;第4阶和第8阶分别为\(-0.1578\)和\(-0.1993\),越过约\(\pm0.1393\)的置信界限,但属于相隔较远的孤立尖峰。20阶Ljung–Box统计量为\(25.5094\),自由度为18,\(p=0.1115\),整体上没有证据拒绝残差无自相关的原假设。与AR(1)和MA(1)的结果相比,ARMA(1,1)已经较好地提取主要线性依赖。这里仍不能据此断言残差独立、正态或同方差,因为Ljung–Box检验只针对一组残差自相关的联合显著性。
向前预测
arma_prediction <- predict(arma_model, n.ahead = 8L)
forecast_table(arma_prediction) Horizon PointForecast Lower95 Upper95
1 1 -0.0518647 -0.65382 0.55009
2 2 -0.0337318 -0.70028 0.63281
3 3 -0.0210800 -0.71690 0.67474
4 4 -0.0122526 -0.72189 0.69739
5 5 -0.0060935 -0.72236 0.71017
6 6 -0.0017961 -0.72127 0.71768
7 7 0.0012022 -0.71983 0.72223
8 8 0.0032942 -0.71849 0.72508
plot_forecast(
arma_series,
arma_prediction,
"ARMA(1,1) Forecast for US Unemployment Change",
"Percentage change"
)未来8个季度的点预测从\(-0.0519\)逐步回到接近零的长期均值,第8步为\(0.0033\)。95%预测区间逐渐稳定在约\([-0.72,0.73]\)。这正是平稳ARMA模型的典型多步预测:当前冲击的影响逐步衰减,点预测回归长期均值,预测不确定性则接近过程的长期水平。
三个实验的对照
| 实验 | 平稳化处理 | 工作序列ADF \(p\)值 | ACF形态 | PACF形态 | 最终模型 | 检验滞后阶数 | Ljung–Box \(p\)值 |
|---|---|---|---|---|---|---|---|
| 黄体生成素浓度 | 不变换 | 0.0462 | 快速拖尾 | 1阶后截尾 | AR(1) | 10 | 0.4050 |
| 尼罗河年流量 | 一阶差分 | 0.0100(报告下限) | 近似1阶截尾 | 总体拖尾 | ARIMA(0,1,1) | 10 | 0.1459 |
| 美国失业率季度变动 | 不变换 | 0.0100(报告下限) | 逐步衰减并有负相关尾部 | 无清晰低阶截尾 | ARMA(1,1) | 20 | 0.1115 |
三个实验说明,ACF与PACF的“截尾”和“拖尾”是模型识别线索而不是机械规则。面对实际数据,应先用时间序列图和简单单位根检验确定工作序列,再根据ACF/PACF提出低阶模型,最后由残差图、残差ACF和Ljung–Box检验检查是否仍有系统性的线性相关。只有这三个环节彼此一致时,一个简单ARIMA模型才构成完整、可解释的分析结果。