时间序列预测的问题

机器算法验证 r 时间序列 预测 组成数据
2022-03-18 22:52:52

我有一个关于在 R 中建模时间序列的问题。我的数据包含以下矩阵:

1   0.03333333 0.01111111 0.9555556
2   0.03810624 0.02309469 0.9387991
3   0.00000000 0.03846154 0.9615385
4   0.03776683 0.03119869 0.9310345
5   0.06606607 0.01201201 0.9219219
6   0.03900325 0.02058505 0.9404117
7   0.03125000 0.01562500 0.9531250
8   0.00000000 0.00000000 1.0000000
9   0.04927885 0.01802885 0.9326923
10  0.06106870 0.02290076 0.9160305
11  0.03846154 0.00000000 0.9615385
12  0.00000000 0.00000000 1.0000000
13  0.06028636 0.03843256 0.9012811
14  0.09646302 0.05144695 0.8520900
15  0.04444444 0.06666667 0.8888889

这些矩阵总共有 200 行。

正如您在每种情况下所看到的,每行的总和为 1,因为这些值是整体的百分比。例如,第 1 行包含变量 a 的 3.33%、变量 2 的 1.11% 和可验证变量 3 的 95.5%。第一列表示测量值的年份。

我的目标是预测未来 5 年,即从 200 年到 205 年。

我可以通过进行三个正常的时间序列预测来做到这一点。但是对于那个预测,总和永远不会等于 1,这非常重要。Normaly 是使用 arima 和指数平滑等技术。

有人知道对此类问题进行预测的方法吗?

1个回答

您正在尝试预测组成时间序列。也就是说,您有三个分量都被限制在 0 和 1 之间并且加起来等于 1。

您可以通过使用适当的广义逻辑变换来使用标准指数平滑来解决此问题。Koehler、Snyder、Ord 和 Beaumont在 2010 年国际预测研讨会上对此进行了介绍,并发表了一篇论文(Snyder 等人,2017 年,国际预测杂志)。

让我们用你的数据来看看这个。将数据读入obs时间序列矩阵:

obs <- structure(c(0.03333333, 0.03810624, 0, 0.03776683, 0.06606607, 
0.03900325, 0.03125, 0, 0.04927885, 0.0610687, 0.03846154, 0, 
0.06028636, 0.09646302, 0.04444444, 0.01111111, 0.02309469, 0.03846154, 
0.03119869, 0.01201201, 0.02058505, 0.015625, 0, 0.01802885, 
0.02290076, 0, 0, 0.03843256, 0.05144695, 0.06666667, 0.9555556, 
0.9387991, 0.9615385, 0.9310345, 0.9219219, 0.9404117, 0.953125, 
1, 0.9326923, 0.9160305, 0.9615385, 1, 0.9012811, 0.85209, 0.8888889
), .Dim = c(15L, 3L), .Dimnames = list(NULL, c("Series 1", "Series 2", 
"Series 3")), .Tsp = c(1, 15, 1), class = c("mts", "ts", "matrix"
))

您可以通过键入来检查这是否有效

obs

现在,你有几个零,一旦你取对数,这将是一个问题。一个简单的解决方案是设置小于小的所有内容ϵ到那个ϵ

epsilon <- 0.0001
obs[obs<epsilon] <- epsilon

现在修改后的行不再总和为 1。我们可以纠正这一点(尽管我认为这可能会使预测变得更糟):

obs <- obs/matrix(rowSums(obs),nrow=nrow(obs),ncol=ncol(obs),byrow=FALSE)

现在我们按照演示文稿的第 35 页转换数据:

zz <- log(obs[,-ncol(obs)]/obs[,ncol(obs)])
colnames(zz) <- head(colnames(obs),-1)
zz

加载forecast包并设置 5 个时间点的范围:

library(forecast)
horizon <- 5

现在逐列建模和预测转换后的数据。这里我只是调用ets(),它将尝试拟合状态空间指数平滑模型。事实证明,它对所有三个系列都使用单指数平滑,但特别是如果您有超过 15 个时间段,它可能会选择趋势模型。或者,如果您有月度数据,请向 R 解释您​​有潜在的季节性,使用ts()with frequency=12- 然后ets()查看季节性模型。

baz <- apply(zz,2,function(xx)forecast(ets(xx),horizon=horizon)["mean"])
forecasts.transformed <- cbind(baz[[1]]$mean,baz[[2]]$mean)

接下来,我们根据演示文稿的第 38 页对预测进行反向转换:

forecasts <- cbind(exp(forecasts.transformed),1)/(1+rowSums(exp(forecasts.transformed)))

最后,让我们绘制历史和预测:

plot(obs[,1],ylim=c(0,1),xlim=c(1,nrow(obs)+horizon),type="n",ylab="")
for ( ii in 1:ncol(obs) ) {
    lines(obs[,ii],type="o",pch=19,col=ii)
    lines(forecasts[,ii],type="o",pch=21,col=ii,lty=2)
}
legend("left",inset=.01,lwd=1,col=1:ncol(obs),pch=19,legend=colnames(obs))

成分预测

编辑:一篇关于成分时间序列预测的论文刚刚出现。我没读过,但可能很有趣。