如何用 fpp3 绘制包含多条预测分位数曲线的图?
数据阿明
可以先用 autoplot() 绘制预测结果,再用 geom_line() 叠加分位数曲线。将百分位数编号映射到 group,就能把不同预测季度中的同一百分位数连成曲线。
完整示例
这段代码适用于题目中的单序列、单模型预测:
library(fpp3)
library(distributional)
fc <- aus_production |>
model(ARIMA(Beer)) |>
forecast(h = 20)
pc <- seq_len(99)
qf <- fc |>
as_tibble() |>
group_by(Quarter) |>
reframe(percentile = quantile(Beer, pc / 100)) |>
unnest(percentile) |>
group_by(Quarter) |>
mutate(pc = row_number()) |>
ungroup()
autoplot(fc, aus_production, level = 95) +
geom_line(
data = qf,
mapping = aes(
x = Quarter,
y = percentile,
group = pc,
colour = factor(pc)
),
inherit.aes = FALSE,
linewidth = 0.35
) +
scale_colour_manual(
values = rainbow(length(pc)),
guide = "none"
) +
labs(
x = "季度",
y = "Beer"
)
为什么要按 pc 分组?
展开后的 qf 中,每个预测季度都有 99 个分位数值。传入的概率依次为 0.01 到 0.99,因此可以在各季度内用 row_number() 为这些值标记对应的百分位数编号。
绘图时,各映射的作用是:
x = Quarter:保留预测结果中的季度时间索引。y = percentile:将计算出的分位数值作为纵坐标。group = pc:连接不同季度中相同百分位数的点。colour = factor(pc):为每条分位数曲线分配一种颜色。
inherit.aes = FALSE 让该图层使用自己的映射,避免继承预测图中针对其他数据列的映射。
题目里的 rep(pc, 20) 也可用于当前结果,但它依赖预测期数和展开后的行顺序。按季度编号后,调整 forecast(h = ...) 时就不必同步修改这里的 20。
与第一段代码的区别
第一段代码先根据 95% 预测区间反推标准差,再用 qnorm() 按正态分布计算分位数,依赖正态分布假设。
在 fpp3 的预测结果中,Beer 列保存的是预测分布,可以直接调用 quantile(Beer, pc / 100) 提取分位数,无需从区间宽度重新推算标准差。
图中的 95% 预测区间由 autoplot() 绘制,99 条彩色曲线由额外的 geom_line() 图层绘制。每条曲线表示各预测季度的同一分位数,不代表一条模拟出来的未来样本路径。
如果以后同时预测多个序列或多个模型,计算分位数时需要保留相应的序列键和 .model。绘图时也要将它们纳入分组,或使用分面展示,避免连接不同序列的点。若所用 ggplot2 不支持 linewidth,可将该参数改为 size。
备注:内容仅供参考。
