将先验信息纳入时间序列预测

机器算法验证 时间序列 贝叶斯 预测 有马 bsts
2022-04-05 09:24:00

假设我有每周测量我孩子 C 身高的数据。大概有一个积极的趋势,由于增长,以及由于测量误差引起的一些噪音,甚至可能是季节性的(冬靴或理发增加了额外的高度)。如果想预测 C 未来的身高(比如说 t+s),我可能会使用 ARIMA 模型,它将下周 C 的身高表示为他前几周身高的函数。

现在假设在过去,我有另外 2 个孩子,A 和 B,他们比 C 大。因此我有关于我孩子在时间 t+s 的身高分布的先验信息。如何将其纳入我的预测中?

例如,考虑以下数据。请注意,虽然 C6(t=6 时 C 的高度)未知,但 A6 和 B6 是已知的。

set.seed(1)
A = seq(1,6,.5) + rnorm(11)/4 
B = seq(1,6,.5) + rnorm(11)/4
C = c((seq(1,3,.5) + rnorm(5)/4), rep(NA, 6))
df = data.frame(A, B, C)

> df
           A        B        C
1  0.8433865 1.097461 1.018641
2  1.5459108 1.344690 1.002662
3  1.7910928 1.446325 2.154956
4  2.8988202 2.781233 2.485968
5  3.0823769 2.988767 2.961051
6  3.2948829 3.495952       NA
7  4.1218573 4.235959       NA
8  4.6845812 4.705305       NA
9  5.1439453 5.148475       NA
10 5.4236529 5.729744       NA
11 6.3779453 6.195534       NA

我考虑使用 2NN(2 个最近邻)来预测 C6。2NN 将 C6 估计为 2.485968 和 2.961051 的平均值,这不是很好(尽管如果我们对数据进行差异化,我们会得到更好的结果)。
或者,我们可以说 C6 是先前观察的预期值,因此在这种情况下为 (3.2948829, 3.495952)/2。

我可以使用哪些其他方法将这些先验信息纳入我的预测?我能否以某种方式将我的 ARIMA 预测与这些先验信息结合起来形成一个整体预测?

我也开始研究贝叶斯时间序列、动态线性模型和状态空间模型,但在这些领域没有太多经验,可以使用指针。

2个回答

我认为一个很好的方法是通过贝叶斯结构时间序列(BSTS)。我通过这两个站点( 12发现了这种方法。我仍然会对其他方法感兴趣。

这是使用 R 中的 bsts 包完成的示例。我使用时间序列组件和回归组件。回归组件包含先验信息。在回归组件上使用堆栈和平板先验。

下面是时间序列特征图。为了测试BSTS的特征选择能力,我故意将C与其他特征和响应变量(D)不同。

特点

下图显示 BSTS 模型正确地观察到特征 C 对预测 D 没有用处。

特征选择

实际(蓝色)与预测(红色) 实际(蓝色)与预测(红色)

代码如下:

library(ggplot2, bsts, ggplotly, data.table)

# generate some data
set.seed(1)
n = 20
train_size = 10
A = seq(1,n) + rnorm(n)
B = seq(1,n) + rnorm(n)
# this variable is not like the others
C = rnorm(n) + 5*sin(seq(1,n))
D = seq(1,n) + rnorm(n)
X = data.table(A, B, C, D)
# transform the data for ggplot
long_data = melt(X)
m[, t := seq_len(.N), by = variable]
g1 = ggplot(data=m, aes(x=t, y=value, colour=variable)) + geom_line() + labs(title="Evolution of Parameters over Time")
ggplotly(g1)
#break the data into training/testing data
train_ind = seq(1,train_size)
train_X = X[train_ind,]
test_X = X[-train_ind,]


ss <- AddLocalLinearTrend(list(), train_X$D)
model4 <- bsts(D ~ .,
               state.specification = ss,
               niter = 1000,
               data = train_X,
               expected.model.size = 3) 
plot(model4, "components")
# observe that the model can tell that C isn't strongly related to D, but A and B are. 
plot(model4, "coef")
pred4 <- predict(model4, newdata = test_X, horizon = 24)
# plot predictions, vs actual (in red)
plot(pred4, ylim=c(0,50))
lines((max(train_ind)+1):nrow(X), test_X$D, col="red")

好问题!

“我能否以某种方式将我的 ARIMA 预测与这些先验信息结合起来形成一个整体预测?”

我参与了一个名为 AUTOBOX 的商业时间序列预测包,并结合了 delphi 类型的预测器序列,其中用户提供间隔概率,然后将其用于 monte-carlo 输入序列未来值的一系列可能值,其中用户通常会根据完全的知识提供 1 分的估计。

然后,以这种方式开发的“实现”与 arima 模拟相互连接,为相关系列提供一系列集合预测值,这些预测值也可能受到在分析阶段通过干预检测方案识别的可能异常的影响。

您应该能够像我所做的那样使用此建议进行编程。当可以“预先猜测”预测变量序列分布时,这个问题/机会就会很自然地出现,例如下一个时期石油价格的替代假设。拥有像这样的先验知识,可以从替代产品中选择那些具有最大预期回报的产品。