Vous essayez de prévoir une série chronologique de composition . Autrement dit, vous avez trois composants qui sont tous contraints de se situer entre 0 et 1 et de s'additionner à 1.
Vous pouvez résoudre ce problème en utilisant le lissage exponentiel standard, en utilisant une transformation logistique généralisée appropriée. Il y a eu une présentation à ce sujet par Koehler, Snyder, Ord & Beaumont lors du Symposium international de 2010 sur les prévisions , qui s'est transformé en un article ( Snyder et al., 2017, International Journal of Forecasting ).
Voyons cela avec vos données. Lisez les données dans une matrice obs
de séries chronologiques:
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"
))
Vous pouvez vérifier si cela a fonctionné en tapant
obs
Maintenant, vous avez quelques zéros là-dedans, ce qui sera un problème une fois que vous prendrez des logarithmes. Une solution simple consiste à définir tout ce qui est inférieur à un petit à ce :ϵϵ
epsilon <- 0.0001
obs[obs<epsilon] <- epsilon
Maintenant, les lignes modifiées ne totalisent plus 1. Nous pouvons rectifier cela (même si je pense que cela pourrait aggraver les prévisions):
obs <- obs/matrix(rowSums(obs),nrow=nrow(obs),ncol=ncol(obs),byrow=FALSE)
Maintenant, nous transformons les données selon la page 35 de la présentation:
zz <- log(obs[,-ncol(obs)]/obs[,ncol(obs)])
colnames(zz) <- head(colnames(obs),-1)
zz
Chargez le forecast
package et définissez un horizon de 5 points dans le temps:
library(forecast)
horizon <- 5
Modélisez et prévoyez maintenant les données transformées colonne par colonne. Ici, j'appelle simplement ets()
, qui tentera d'adapter un modèle de lissage exponentiel de l'espace d'états. Il s'avère qu'il utilise un lissage exponentiel unique pour les trois séries, mais surtout si vous avez plus de 15 périodes, il peut sélectionner des modèles de tendance. Ou si vous avez des données mensuelles, expliquez à R que vous avez une saisonnalité potentielle, en utilisant ts()
avec frequency=12
- alors vous ets()
examinerez les modèles saisonniers.
baz <- apply(zz,2,function(xx)forecast(ets(xx),horizon=horizon)["mean"])
forecasts.transformed <- cbind(baz[[1]]$mean,baz[[2]]$mean)
Ensuite, nous retransformons les prévisions conformément à la page 38 de la présentation:
forecasts <- cbind(exp(forecasts.transformed),1)/(1+rowSums(exp(forecasts.transformed)))
Enfin, tracons les historiques et les prévisions:
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))
EDIT: un article sur les prévisions chronologiques de composition vient de paraître. Je ne l'ai pas lu, mais cela peut être intéressant.