You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何计算并可视化ARIMA(1,1,1)模型中AR与MA项的拟合值贡献?

量化ARIMA模型中AR项与MA项对拟合值的贡献

很高兴看到你已经动手尝试拆分ARIMA(1,0,1)的拟合贡献了!接下来我帮你理清现有代码的细节问题,再延伸到你真正关注的ARIMA(1,1,1)模型,一步步实现准确的贡献量化。

先明确ARIMA(1,0,1)的模型逻辑

ARIMA(1,0,1)本质是ARMA(1,1)(差分阶数d=0),公式为:

$Y_t = \phi_1 Y_{t-1} + \theta_1 \epsilon_{t-1} + \epsilon_t$

对应的拟合值公式是:

$\hat{Y}t = \phi_1 Y{t-1} + \theta_1 \hat{\epsilon}{t-1}$
这里$\hat{\epsilon}
{t-1} = Y_{t-1} - \hat{Y}_{t-1}$,是模型输出的滞后残差

你现有代码的思路是对的,但开头几个值不匹配,核心原因是初始条件的处理——forecast::Arima()会自动填充第一个滞后项的缺失值,而手动计算时没对齐这个逻辑。

修正ARIMA(1,0,1)的贡献计算

我们直接利用模型内部的序列和残差来计算,确保和fitted()的结果完全匹配:

library(forecast)
library(tidyverse)
library(ggfortify)

# 拟合ARIMA(1,0,1)模型
arima_101 <- Arima(AirPassengers, c(1, 0, 1), include.mean = F)
autoplot(arima_101)

ARIMA(1,0,1)模型诊断图

# 提取模型系数
ar1_coef <- coef(arima_101)["ar1"]
ma1_coef <- coef(arima_101)["ma1"]

# 从模型中获取准确的滞后序列和滞后残差
y_lag <- stats::lag(arima_101$x, k = 1)
resid_lag <- stats::lag(arima_101$residuals, k = 1)
# 对齐模型逻辑:初始滞后残差填充为0(Arima()默认处理方式)
resid_lag[is.na(resid_lag)] <- 0

# 计算AR和MA项的贡献
ar1_part <- y_lag * ar1_coef
ma1_part <- resid_lag * ma1_coef
fitted_values <- as.numeric(fitted(arima_101))

# 验证所有值匹配(忽略初始NA)
all.equal(fitted_values, ar1_part + ma1_part, na.rm = TRUE)
#> [1] TRUE

现在可以可视化各部分的贡献:

df <- tibble(
  idx = 1:length(AirPassengers),
  ar1_part = ar1_part,
  ma1_part = ma1_part,
  fitted_values = fitted_values
) %>% mutate(sum_ar1_ma1 = ar1_part + ma1_part)

# 绘制堆叠贡献图+拟合值线
df %>% 
  gather("component", "contribution", -idx, -fitted_values, -sum_ar1_ma1) %>%
  ggplot(aes(x = idx)) +
  geom_area(aes(y = contribution, fill = component), alpha = 0.7) +
  geom_line(aes(y = fitted_values), color = "black", size = 0.8) +
  labs(title = "ARIMA(1,0,1):AR项与MA项对拟合值的贡献",
       x = "时间步", y = "数值", fill = "贡献项") +
  theme_minimal()

ARIMA(1,0,1)贡献可视化图

延伸到ARIMA(1,1,1)模型

ARIMA(1,1,1)是对原序列做1阶差分后拟合ARMA(1,1),公式为:

$\nabla Y_t = \phi_1 \nabla Y_{t-1} + \theta_1 \epsilon_{t-1} + \epsilon_t$
其中$\nabla Y_t = Y_t - Y_{t-1}$,代表序列的变化量

要计算原序列拟合值的AR/MA贡献,需要先拆分差分序列的贡献,再还原到原序列维度:

# 拟合ARIMA(1,1,1)模型
arima_111 <- Arima(AirPassengers, c(1, 1, 1))
autoplot(arima_111)

# 提取模型系数
ar1_coef_111 <- coef(arima_111)["ar1"]
ma1_coef_111 <- coef(arima_111)["ma1"]

# 获取差分序列和模型残差
diff_y <- diff(AirPassengers)
resid_111 <- arima_111$residuals

# 计算差分序列的AR/MA贡献
diff_ar_part <- stats::lag(diff_y, k = 1) * ar1_coef_111
diff_ma_part <- stats::lag(resid_111, k = 1) * ma1_coef_111

# 还原到原序列:原序列拟合值 = 前一期实际值 + 差分拟合值
# 拆分原序列的AR/MA贡献(对应变化量的贡献)
df_111 <- tibble(
  idx = 1:length(AirPassengers),
  y_prev = stats::lag(AirPassengers, k = 1),  # 前一期实际值
  ar_contribution = diff_ar_part,  # AR项对变化量的贡献
  ma_contribution = diff_ma_part,  # MA项对变化量的贡献
  fitted_values = as.numeric(fitted(arima_111))
) %>% mutate(
  # 验证拟合值:前一期值 + AR贡献 + MA贡献
  check_fitted = y_prev + ar_contribution + ma_contribution
)

# 确认所有值匹配(忽略初始NA)
all.equal(df_111$fitted_values, df_111$check_fitted, na.rm = TRUE)
#> [1] TRUE

# 可视化ARIMA(1,1,1)的贡献(聚焦变化量)
df_111 %>% 
  filter(!is.na(ar_contribution)) %>%
  gather("component", "contribution", ar_contribution, ma_contribution) %>%
  ggplot(aes(x = idx)) +
  geom_area(aes(y = contribution, fill = component), alpha = 0.7) +
  geom_line(aes(y = fitted_values - y_prev), color = "black", size = 0.8) +  # 拟合变化量
  labs(title = "ARIMA(1,1,1):AR项与MA项对拟合变化量的贡献",
       x = "时间步", y = "序列变化量", fill = "贡献项") +
  theme_minimal()

关键注意事项

  • 初始条件对齐:模型会自动处理第一个滞后项的缺失值(通常填充为0),手动计算时要和这个逻辑保持一致,否则开头的拟合值会不匹配。
  • 差分模型的视角:ARIMA(1,1,1)的AR/MA项作用于序列的变化量,而非原序列的绝对值,所以可视化时聚焦变化量的贡献更有意义。
  • 残差的正确性:必须使用模型输出的residuals,而不是手动计算的残差,因为模型内部的残差计算已经考虑了初始条件和拟合逻辑。

内容的提问来源于stack exchange,提问作者stats-hb

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 10:19:04