library(forecast)
library(ggplot2)
autoplot(AirPassengers, colour = "#3a86d4") +
labs(x = "Year", y = "Passengers (thousands)",
title = "International airline passengers, 1949–1960") +
theme_minimal()
Tracez, décomposez, découpez, ajustez deux modèles et mesurez honnêtement la prévision — un flux de travail pratique avec le package forecast
Un flux de travail pratique de prévision de séries temporelles en R avec le package forecast sur le jeu de données intégré AirPassengers : tracer et décomposer la série en tendance et saisonnalité, mettre de côté un jeu de test, ajuster ETS et auto.arima, prévoir à l’avance avec des intervalles de prédiction, et comparer la précision avec RMSE et MAE. Chaque étape est du base R exécutable que vous pouvez copier.
decompose, stl).auto.arima() — ajustés en une ligne chacun et expliqués en langage clair.La prévision de séries temporelles consiste à prédire les valeurs futures d’une variable mesurée dans le temps — les ventes du trimestre prochain, la charge serveur du mois prochain, le nombre de passagers de l’an prochain — à partir de son propre passé. Ce qui distingue une série temporelle de données ordinaires, c’est l’ordre : les observations arrivent en séquence et portent généralement deux motifs qu’il vaut la peine de nommer. La tendance est la lente dérive vers le haut ou le bas (une entreprise qui croît d’année en année) ; la saisonnalité est le cycle qui se répète au sein de l’année (plus de glaces en été, plus de vols en juillet). Une bonne prévision apprend les deux, les projette vers l’avant et — surtout — vous dit à quel point elle est incertaine.
En R, la manière idiomatique de stocker une série est un objet ts : un vecteur numérique accompagné de sa date de début et de sa fréquence (12 pour des données mensuelles, 4 pour des trimestrielles). Nous utiliserons le jeu de données intégré AirPassengers — les totaux mensuels de passagers des lignes aériennes internationales de 1949 à 1960. C’est la série pédagogique classique, car elle présente une tendance ascendante évidente et un fort cycle annuel qui croît avec le niveau — exactement les deux motifs qu’un prévisionniste doit modéliser.
Tout ce qui suit s’appuie sur le package forecast de Rob Hyndman — la boîte à outils standard de longue date pour ce flux de travail en R.
Tracez toujours la série d’abord. Avant tout modèle, vos yeux doivent confirmer la tendance et la saisonnalité. AirPassengers est déjà un objet ts, donc autoplot() du package forecast la dessine correctement en fonction du temps :

Deux choses sautent aux yeux. La série est en hausse — triplant à peu près en douze ans — et elle cycle chaque année, culminant chaque été. Et les oscillations saisonnières deviennent plus larges à mesure que le niveau monte : l’écart été-hiver est petit en 1949 et grand en 1960. Cette amplitude croissante s’appelle une saisonnalité multiplicative (la saison se met à l’échelle du niveau), et elle nous indique vers quels réglages de modèle nous tourner.
Avant de prévoir, il est utile de séparer les motifs pour voir chacun isolément. decompose() scinde une série en trois parties : la tendance (le mouvement lisse de long terme), la composante saisonnière (la forme annuelle répétée) et le résidu (ce qui reste — le bruit). Comme les oscillations saisonnières croissent avec le niveau, nous demandons une décomposition "multiplicative" :

Lisez les panneaux de haut en bas. Le panneau tendance est la nette montée ascendante, saisonnalité retirée. Le panneau saisonnier est la vague annuelle répétée — la même forme chaque année, culminant en été. Le résidu est petit et sans motif, ce que l’on veut : cela signifie que tendance plus saisonnalité expliquent l’essentiel de la série. Une alternative plus robuste est stl() (décomposition saisonnière-tendance par loess), qui gère une forme saisonnière évoluant lentement dans le temps — remplacez-la par stl(AirPassengers, s.window = "periodic") |> autoplot().
Voici l’étape que les gens sautent et regrettent. Pour savoir si une prévision vaut quelque chose, vous devez la confronter à des données que le modèle n’a jamais vues — sinon vous mesurez seulement à quel point il a mémorisé le passé. Alors mettez de côté la queue de la série comme jeu de test. window() découpe un ts par date ; nous entraînons sur 1949–1958 et gardons les 24 derniers mois (1959–1960) pour noter la prévision :
train_months test_months
120 24
Cela laisse 120 mois pour apprendre et 24 pour tester. La règle empirique : le jeu de test doit être au moins aussi long que l’horizon qui vous intéresse réellement — ici, deux cycles saisonniers complets. Nous ne touchons jamais à test avant l’étape d’évaluation.
Deux familles de modèles dominent la prévision univariée pratique, et le package forecast ajuste chacune en une ligne.
ETS signifie error, trend, seasonal (erreur, tendance, saisonnalité) — le nom moderne du lissage exponentiel. Il construit une prévision à partir de trois pièces lissées (un niveau, une tendance et une forme saisonnière), en donnant plus de poids aux observations récentes. ets() explore les variantes automatiquement et retient la meilleure selon un critère d’ajustement (l’AICc, le critère d’information d’Akaike corrigé) :
ETS(M,Ad,M)
Call:
ets(y = train)
Smoothing parameters:
alpha = 0.7459
beta = 0.0189
gamma = 3e-04
phi = 0.9793
Initial states:
l = 120.667
b = 1.7375
s = 0.8978 0.7964 0.919 1.0576 1.2072 1.218
1.1113 0.9779 0.9838 1.0253 0.8973 0.9084
sigma: 0.0381
AIC AICc BIC
1110.450 1117.222 1160.625
Il a choisi ETS(M,Ad,M) — une erreur multiplicative, une tendance additive damped (amortie) et une saisonnalité multiplicative. En clair : il a reconnu l’amplification des oscillations saisonnières (les deux « M ») et une tendance qui continue de monter mais s’aplatit doucement (le « Ad » amorti) — précisément ce que montraient les graphiques.
ARIMA — autoregressive integrated moving average (moyenne mobile intégrée autorégressive) — emprunte une autre voie : au lieu de lisser, elle modélise chaque valeur comme une fonction de ses propres valeurs récentes et des erreurs de prévision récentes, en différenciant d’abord la série pour retirer la tendance et la saisonnalité. auto.arima() explore les paramètres d’ordre pour vous :
Series: train
ARIMA(1,1,0)(0,1,0)[12]
Coefficients:
ar1
-0.2397
s.e. 0.0935
sigma^2 = 103.6: log likelihood = -399.64
AIC=803.28 AICc=803.4 BIC=808.63
Elle a sélectionné ARIMA(1,1,0)(0,1,0)[12] : un terme autorégressif non saisonnier, une différenciation pour retirer la tendance et une différenciation saisonnière (le [12]) pour retirer le cycle annuel. Deux moteurs très différents — lissage contre autocorrélation — voyons maintenant lequel prévoit le mieux les deux années mises de côté.
forecast() projette un modèle ajusté h pas en avant et — c’est ce qui compte — renvoie un intervalle de prédiction, pas seulement une ligne unique. Nous prévoyons les deux modèles à 24 mois et traçons la prévision ETS face à ce qui s’est réellement produit :
library(forecast)
library(ggplot2)
train <- window(AirPassengers, end = c(1958, 12))
test <- window(AirPassengers, start = c(1959, 1))
fit_ets <- ets(train)
fc_ets <- forecast(fit_ets, h = 24)
autoplot(fc_ets) +
autolayer(test, series = "Actual") +
scale_colour_manual(values = c("Actual" = "#fb5607")) +
labs(x = "Year", y = "Passengers (thousands)", colour = NULL,
title = "ETS forecast vs. actual (held-out 1959–1960)") +
theme_minimal()
La prévision poursuit la tendance et répète la forme saisonnière, et les bandes ombrées sont les intervalles de prédiction : la bande intérieure est à 80 % et l’extérieure à 95 %, ce qui signifie que le modèle s’attend à ce que la vraie valeur tombe à l’intérieur 80 % et 95 % du temps. Remarquez que les bandes s’évasent à mesure que l’on prévoit plus loin — l’incertitude honnête croît avec l’horizon. Les valeurs réelles (en orange) se situent près du haut des intervalles : les modèles sous-estiment légèrement le vrai boom de 1959–1960, car la croissance du nombre de passagers s’est accélérée au-delà de la tendance qu’ils avaient apprise. C’est exactement le genre d’écart que le test mis de côté est conçu pour révéler.
Estimer à l’œil ne suffit pas — mesurez-le. accuracy() compare une prévision aux valeurs réelles mises de côté et rapporte des métriques d’erreur. Les deux que vous utiliserez le plus :
Les deux suivent le principe « plus c’est bas, mieux c’est ». Passez la prévision et le jeu test pour noter les lignes hors échantillon :
library(forecast)
train <- window(AirPassengers, end = c(1958, 12))
test <- window(AirPassengers, start = c(1959, 1))
fit_ets <- ets(train)
fit_arima <- auto.arima(train)
fc_ets <- forecast(fit_ets, h = 24)
fc_arima <- forecast(fit_arima, h = 24)
rbind(
ETS = accuracy(fc_ets, test)["Test set", c("RMSE", "MAE", "MAPE")],
ARIMA = accuracy(fc_arima, test)["Test set", c("RMSE", "MAE", "MAPE")]
) RMSE MAE MAPE
ETS 72.54791 63.21297 13.30345
ARIMA 74.25224 68.57729 14.92756
ETS l’emporte sur le jeu de test : RMSE 72.5 contre 74.3, MAE 63.2 contre 68.6, et MAPE (erreur absolue moyenne en pourcentage) 13.3 % contre 14.9 %. La marge est modeste, mais elle est cohérente sur les trois métriques, donc ETS est le choix ici — sa saisonnalité multiplicative a un peu mieux collé aux oscillations croissantes de cette série que la différenciation d’ARIMA. Un MAPE autour de 13 % signifie que les prévisions se trompaient d’environ un huitième en moyenne — respectable à deux ans d’échéance, et un chiffre que vous pouvez rapporter honnêtement plutôt qu’une seule ligne pleine d’assurance.
Ne surinterprétez pas un seul découpage. Pour un test plus sévère, utilisez la validation croisée pour séries temporelles (tsCV() dans le package forecast), qui fait rouler la coupe entraînement/test vers l’avant sur de nombreuses origines et moyenne les erreurs — un verdict bien plus stable qu’un seul jeu mis de côté.
Une fois un modèle choisi, réajustez-le sur la série entière — vous voulez que chaque observation nourrisse la vraie prévision — et projetez au-delà de la fin des données. Voici la récompense : ETS réajusté sur les douze années, prévoyant les 24 prochains mois vers un territoire véritablement inexploré :

La prévision ponctuelle porte la tendance et les pics saisonniers vers l’avant, et l’intervalle de prédiction s’élargit mois après mois — fin 1962, la bande à 95 % s’étend de 300 à 620 mille passagers environ. Cette bande qui s’élargit est la partie la plus utile du tableau : une prévision est une fourchette, et une bonne prévision est honnête sur la vitesse à laquelle cette fourchette grandit.
Un flux de travail que vous pouvez réexécuter sur toute nouvelle série, dans l’ordre :
ts — les valeurs plus start et frequency (12 mensuel, 4 trimestriel).autoplot) — confirmez d’abord la tendance et la saisonnalité de vos yeux.decompose ou stl) — séparez tendance, saisonnier et résidu ; notez additif contre multiplicatif.window) — mettez de côté une queue de test au moins aussi longue que votre horizon de prévision.ets() et auto.arima() sont les modèles de référence en une ligne ; ajustez les deux.forecast(fit, h = ...)) — gardez toujours les intervalles de prédiction, pas seulement la ligne ponctuelle.accuracy(fc, test)) — comparez sur RMSE / MAE / MAPE ; envisagez tsCV() pour un verdict plus stable.Quand aller au-delà de forecast. Pour une série à saisonnalités multiples ou irrégulières, jours fériés ou points de rupture connus, Prophet (le modèle additif de Meta, disponible en package R prophet) est conçu exactement pour cela et tolère les données manquantes. Pour un flux de travail moderne natif tidyverse — des données tsibble bien rangées, de nombreuses séries à la fois et une grammaire cohérente couvrant ETS, ARIMA et plus — le package fable est le successeur de forecast, du même auteur. Et quand les facteurs sont des variables externes plutôt que le propre passé de la série, un modèle de régression ou d’apprentissage automatique (avec des variables décalées) peut mieux convenir. forecast reste le chemin le plus rapide pour une seule série à tendance et saisonnalité claires — ce qui couvre une large part des tâches de prévision réelles.
Placez vos données dans un objet ts (les valeurs plus start et frequency), puis ajustez un modèle et appelez forecast(). Le chemin le plus court et fiable passe par le package forecast : fit <- ets(my_ts) (ou auto.arima(my_ts)), puis fc <- forecast(fit, h = 12) pour projeter 12 pas en avant, et autoplot(fc) pour tracer la prévision avec ses intervalles de prédiction. Mettez toujours de côté un jeu de test avec window() d’abord et notez la prévision avec accuracy() pour savoir ce qu’elle vaut.
Les deux sont des modèles de prévision univariés, mais ils fonctionnent différemment. ETS (error, trend, seasonal) est le lissage exponentiel : il construit la prévision à partir de composantes lissées de niveau, tendance et saisonnalité, en pondérant davantage les données récentes. ARIMA (autoregressive integrated moving average) modélise chaque valeur à partir de ses propres valeurs récentes et de ses erreurs récentes, en différenciant la série pour retirer tendance et saisonnalité. Aucun n’est universellement meilleur — ajustez les deux avec ets() et auto.arima() et laissez la précision hors échantillon sur un jeu de test mis de côté décider.
Mettez de côté la fin de votre série comme jeu de test, puis appelez accuracy(forecast_object, test_set) du package forecast. Il renvoie des métriques d’erreur dont le RMSE (erreur quadratique moyenne, qui pénalise les gros écarts), le MAE (erreur absolue moyenne) et le MAPE (erreur absolue moyenne en pourcentage, sans unité). Comparez les modèles sur la ligne Test set — plus c’est bas, mieux c’est. Pour une estimation plus stable qu’un seul découpage, utilisez la validation croisée pour séries temporelles avec tsCV(), qui fait rouler l’origine de la prévision vers l’avant à travers la série.
Utilisez auto.arima() (ou ets()) pour une seule série à tendance claire et un seul cycle saisonnier — c’est rapide, bien compris, et cela donne des intervalles de prédiction calibrés. Tournez-vous vers Prophet lorsque vous avez des saisonnalités multiples ou irrégulières, des effets de jours fériés, des points de rupture connus, ou des données brouillonnes avec des lacunes, puisqu’il est bâti pour ces cas et tolère les valeurs manquantes. Pour un flux de travail natif tidyverse couvrant de nombreuses séries, le package fable (le successeur de forecast) est un solide choix moderne.
Ce billet est la visite pratique. Pour les fondations sur lesquelles chaque étape s’appuie, avec des parcours à reproductibilité garantie et du code exécutable :
autoplot().ts, lm, l’ACP et plus. · dplyr contre pandas — remodeler les données qui alimentent un ts. · Visualisation de données · Programmation.Demandez à Prova « prévois ma série de ventes mensuelles en R — trace-la, ajuste ETS et auto.arima, et dis-moi laquelle est la plus précise » — elle répond avec du code que vous pouvez exécuter sur vos propres données. The runtime is the judge. Demander à Prova →
@online{kassambara2026,
author = {Kassambara, Alboukadel},
title = {Séries temporelles en R : prévision ETS, ARIMA \& précision},
date = {2026-07-17},
url = {https://www.datanovia.com/blog/time-series-forecasting-in-r},
langid = {fr}
}