如何计算并可视化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)

# 提取模型系数 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,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
相关产品推荐
相关产品推荐

