Méthodes de prévision des séries temporelles

5.3 Méthodes de prévision des séries temporelles

Objectifs d'apprentissage

À la fin de cette section, vous devriez être capable de :

  • 5.3.1 Analyser une série temporelle en la décomposant en ses composants, notamment la tendance, la variation saisonnière et cyclique, et le bruit résiduel.
  • 5.3.2 Calculer divers types de moyennes mobiles, de moyennes mobiles pondérées et de techniques de lissage connexes.
  • 5.3.3 Décrire la procédure ARIMA et la manière dont les fonctions d'autocorrélation peuvent être utilisées pour trouver les paramètres appropriés.
  • 5.3.4 Utiliser ARIMA pour faire des prévisions, à l'aide de Python.

Cette section se concentre sur l'analyse d'une série temporelle en ses composants dans le but de construire un modèle robuste pour la prévision. Bien qu'une grande partie de l'analyse puisse être effectuée à la main, de nombreuses applications logicielles informatiques ont été développées pour prendre en charge cette tâche. Enfin, nous verrons comment Python peut être utilisé pour décomposer une série temporelle et créer un modèle d'application générale appelé le modèle autorégressif à moyenne mobile intégrée (communément appelé ARIMA) pour réaliser des prévisions.

Élimination de la tendance des données et techniques de lissage

L'élimination de la tendance (detrending) d'une série temporelle fait référence au processus consistant à séparer le composant de tendance sous-jacent tntn de la série temporelle dans son ensemble au moyen de l'une de deux opérations complémentaires : isoler la tendance puis la supprimer, ou lisser la tendance en ne laissant que les composants saisonniers et d'erreur. Les méthodes qui réduisent le terme d'erreur et aplanissent les variations saisonnières aboutissent à un composant tendance-cycle tntn qui suit toujours de près les hauts et les bas à long terme de la série temporelle. Dans ce cas, les autres composants de la série temporelle peuvent être trouvés en supprimant le composant de tendance :

xn−tn=sn+εnxn−tn=sn+εn

D'un autre côté, il existe des méthodes d'élimination de la tendance qui transforment les données en une nouvelle série temporelle avec une ligne de tendance plus proche d'une ligne constante au niveau 0. En d'autres termes, après avoir appliqué une telle transformation, la nouvelle série temporelle, znzn, serait uniquement constituée des composants saisonniers et de bruit :

zn=sn+εnzn=sn+εn

Les méthodes courantes pour isoler ou supprimer le composant de tendance ou de tendance-cycle comprennent les suivantes :

  1. Moyenne mobile simple (SMA). La moyenne mobile simple (SMA) (simple moving average (SMA)) est obtenue en calculant la moyenne (moyenne arithmétique) d'un nombre fixe de points de données consécutifs. Cela a pour effet de lisser les variations à court terme dans les données et d'isoler la tendance. Si les données présentent une variation saisonnière, alors une SMA de même longueur peut éliminer efficacement et complètement le composant saisonnier — vous en saurez plus à ce sujet dans Méthodes de prévision des séries temporelles.
  2. Moyenne mobile pondérée (WMA). Il existe plusieurs variantes de l'idée de moyenne mobile, dans lesquelles des poids différents sont attribués aux termes précédents de la série, appelées par conséquent moyenne mobile pondérée (WMA) (weighted moving average (WMA)). L'une des moyennes mobiles pondérées les plus courantes est la moyenne mobile exponentielle (EMA) (exponential moving average (EMA)), dans laquelle les poids suivent une décroissance exponentielle, accordant beaucoup plus de poids aux points de données les plus récents qu'à ceux plus éloignés dans le temps. Ces techniques sont plus souvent utilisées en prévision, comme nous le verrons plus loin dans cette section, mais elles peuvent également être employées comme méthode de lissage pour isoler une tendance dans les données.
  3. Différenciation. La différence (de premier ordre) d'une série temporelle est obtenue par différenciation (differencing), ou en prenant les différences de termes consécutifs — c'est-à-dire que le ne terme de la différence serait xn+1−xnxn+1−xn. Si la série temporelle originale présentait une tendance linéaire, la différence afficherait alors une tendance relativement constante avec seulement du bruit et des variations saisonnières présents. De même, la différence de la différence, ou différence de second ordre, peut transformer une tendance quadratique en une tendance constante. Les tendances polynomiales d'ordre supérieur peuvent être identifiées à l'aide de différences d'ordre supérieur. Ainsi, nous pouvons utiliser la différenciation pour vérifier la présence d'une tendance globale d'un certain type (linéaire, quadratique, etc.) tout en supprimant simultanément la tendance originale de la série temporelle.
  4. Régression. Comme mentionné dans l'Exemple 5.1, la régression linéaire peut être appliquée à une série temporelle qui semble afficher une tendance uniforme à la hausse ou à la baisse. En utilisant la différenciation pour déterminer s'il existe une tendance d'un ordre particulier, une régression linéaire, quadratique ou polynomiale d'ordre supérieur peut alors être utilisée pour trouver cette tendance.
  5. Décomposition saisonnière-tendance à l'aide de LOESS (STL). La décomposition saisonnière-tendance à l'aide de LOESS (STL) (Seasonal-Trend decomposition using LOESS (STL)) est un outil puissant qui décompose une série temporelle en composants de tendance-cycle, saisonniers et de bruit. Plus loin dans cette section, nous découvrirons comment effectuer une STL à l'aide de Python. (Remarque : LOESS est une technique de régression qui ajuste un polynôme de bas degré — généralement linéaire ou quadratique — à de petites portions de données à la fois. Une compréhension complète de LOESS n'est pas requise pour utiliser la STL.)

Il existe, bien sûr, des méthodes plus complexes pour analyser et isoler les tendances des séries temporelles, mais dans ce manuel, nous nous en tiendrons aux principes de base et ferons appel à la technologie lorsque cela sera approprié.

Moyennes mobiles simples (SMA)

Rappelez-vous que nous utilisons le terme fenêtre (window) pour désigner des termes consécutifs d'une série temporelle. Dans ce qui suit, supposons que la taille de la fenêtre est une constante, TT. Étant donné une série temporelle avec des valeurs (xn)(xn), c'est-à-dire une séquence (x1, x2, x3,x4,…,xN)(x1,x2,x3,x4,…,xN), la moyenne mobile simple avec une taille de fenêtre TT est définie comme une nouvelle série (yn)(yn) avec des valeurs données par la formule

yn=xn+xn−1+xn−2+…+xn−T+1T=1T∑k=1Txn−T+kyn=xn+xn−1+xn−2+…+xn−T+1T=1T∑k=1Txn−T+k

Cette formule n'est pas aussi difficile qu'elle en a l'air. Considérez-la simplement comme la moyenne des TT derniers termes. Par exemple, étant donné la suite (5, 4, 2, 6, 2, 3, 1, 7), la SMA de longueur 4 serait obtenue en calculant la moyenne de 4 termes consécutifs à la fois. Notez que le premier terme de la SMA est y4y4 car au moins 4 termes sont nécessaires dans la moyenne.

Terme k=4k=4 : (5,4,2,6,2,3,1,7)→y4=5+4+2+64=174=4.25(5,4,2,6,2,3,1,7)→y4=5+4+2+64=174=4.25

Terme k=5k=5 : (5,4,2,6,2,3,1,7)→y5=4+2+6+24=144=3.5(5,4,2,6,2,3,1,7)→y5=4+2+6+24=144=3.5

Terme k=6k=6 : (5,4,2,6,2,3,1,7)→y6=2+6+2+34=134=3.25(5,4,2,6,2,3,1,7)→y6=2+6+2+34=134=3.25

Terme k=7k=7 : (5,4,2,6,2,3,1,7)→y7=6+2+3+14=124=3(5,4,2,6,2,3,1,7)→y7=6+2+3+14=124=3

Terme k=8k=8 : (5,4,2,6,2,3,1,7)→y8=2+3+1+74=134=3.25(5,4,2,6,2,3,1,7)→y8=2+3+1+74=134=3.25

Ainsi, la SMA de longueur 4 est la suite (4.25, 3.5, 3.25, 3, 3.25). Remarquez que les valeurs de la SMA ne sautent pas autant que les valeurs de la suite originale.

Le nombre de termes à utiliser dans une moyenne mobile simple dépend de l'ensemble de données et du résultat souhaité. Si le but est de réduire le bruit, un petit nombre de termes (par exemple, 3 à 5) peut être suffisant. Parfois, les incohérences dans la collecte des données peuvent être atténuées par une utilisation judicieuse de la SMA. Par exemple, supposons que des données soient collectées sur le nombre de clients sans rendez-vous au service des permis de conduire, qui ne fonctionne que du lundi au vendredi. Aucune donnée n'est collectée les week-ends, tandis que le nombre de visites le lundi peut être disproportionnellement élevé parce que les usagers ont dû attendre le lundi pour accéder aux services. Ici, une SMA de 7 jours lisserait les données, répartissant les données hebdomadaires des visites de manière plus uniforme sur tous les jours de la semaine.

Exemple 5.3

Problème

Trouvez la moyenne mobile simple de taille de fenêtre 3 pour les données du Tableau 5.1 et comparez-la avec le graphique linéaire original.

Solution

La SMA commencera à l'index k=3k=3.

y 3 = 1,848.36 + 2,058.9 + 2,043.94 3 = 1,983.73 y 3 = 1,848.36 + 2,058.9 + 2,043.94 3 = 1,983.73
y 4 = 2,058.9 + 2,043.94 + 2,238.83 3 = 2,113.89 y 4 = 2,058.9 + 2,043.94 + 2,238.83 3 = 2,113.89
y 5 = 2,043.94 + 2,238.83 + 2,673.61 3 = 2,318.79 y 5 = 2,043.94 + 2,238.83 + 2,673.61 3 = 2,318.79
y 6 = 2,238.83 + 2,673.61 + 2,506.85 3 = 2,473.1 y 6 = 2,238.83 + 2,673.61 + 2,506.85 3 = 2,473.1
y 7 = 2,673.61 + 2,506.85 + 3,230.78 3 = 2,803.75 y 7 = 2,673.61 + 2,506.85 + 3,230.78 3 = 2,803.75
y 8 = 2,506.85 + 3,230.78 + 3,756.07 3 = 3,164.57 y 8 = 2,506.85 + 3,230.78 + 3,756.07 3 = 3,164.57
y 9 = 3,230.78 + 3,756.07 + 4,766.18 3 = 3,917.68 y 9 = 3,230.78 + 3,756.07 + 4,766.18 3 = 3,917.68
y 10 = 3,756.07 + 4,766.18 + 3,839.5 3 = 4,120.58 y 10 = 3,756.07 + 4,766.18 + 3,839.5 3 = 4,120.58
y 11 = 4,766.18 + 3,839.5 + 4,769.83 3 = 4,458.5 y 11 = 4,766.18 + 3,839.5 + 4,769.83 3 = 4,458.5

La SMA est représentée graphiquement avec la série temporelle originale sur la Figure 5.10.

Un graphique linéaire intitulé Indice S&P à la fin de l'année 2013-2023. L'axe X comprend les années de 2013 à 2023 et l'axe Y s'étend de 0 à 6 000. Une ligne bleue dentelée représentant le S&P 500 montre une tendance générale à la hausse au cours de la dernière décennie. Une ligne orange représentant la moyenne mobile simple de longueur 3 commence en 2015 et monte avec la ligne du S&P 500. Les deux lignes montrent une tendance à la hausse, le S&P 500 connaissant une plus grande volatilité. Le S&P 500 commence à environ 1 500 en 2013, monte à environ 2 500 en 2016, puis fluctue entre 2 000 et 3 000 jusqu'en 2021, où il monte fortement pour atteindre 5 000 en 2023. La ligne SMA (3) montre une tendance à la hausse plus lisse, commençant à environ 1 500 en 2013 et atteignant environ 4 500 en 2023.
Figure 5.10 Graphique linéaire de l'indice S&P 500 avec la moyenne mobile simple de longueur 3 (source des données : adaptée de S&P 500 [SPX] Historical Data)

Les moyennes mobiles simples constituent un moyen facile d'identifier une courbe tendance-cycle dans la série temporelle. En fait, la SMA peut servir d'estimation du composant tntn de la série temporelle. En pratique, lors de l'utilisation de la SMA pour isoler le composant tendance-cycle, les termes de la SMA sont centrés, ce qui signifie que lors du calcul des termes de la SMA, ykyk, le terme xkxk apparaît en plein milieu de la fenêtre, avec le même nombre de termes à gauche et à droite.

Par exemple, la SMA trouvée dans l'Exemple 5.3 peut être décalée de manière à ce que yk=xk−1+xk+xk+13yk=xk−1+xk+xk+13. Cela a pour effet de décaler l'index des termes de la SMA de 1 en arrière, de sorte que la SMA commence à l'index k=2k=2.

y2=x1+x2+x33=1,848.36+2,058.9+2,043.943=1,983.73y2=x1+x2+x33=1,848.36+2,058.9+2,043.943=1,983.73

Cette procédure fonctionne bien lorsque la taille de la fenêtre est impaire, mais lorsqu'elle est paire, une pratique courante consiste à calculer deux SMA dans lesquelles xkxk se trouve très près du milieu de la séquence, puis à faire la moyenne de leurs résultats. Par exemple, en utilisant les mêmes données que dans l'Exemple 5.3, si nous voulions calculer une SMA centrée de longueur 4, le premier terme serait y3y3, et nous trouverions deux moyennes.

x1+x2+x3+x44=1,848.36+2,058.9+2,043.94+2,238.834=2,047.51x1+x2+x3+x44=1,848.36+2,058.9+2,043.94+2,238.834=2,047.51
x2+x3+x4+x54=2,058.9+2,043.94+2,238.83+2,673.614=2,253.82x2+x3+x4+x54=2,058.9+2,043.94+2,238.83+2,673.614=2,253.82
y3=2,047.51+2,253.822=2,150.67y3=2,047.51+2,253.822=2,150.67

La moyenne des deux moyennes est équivalente à la formule plus efficace suivante. Considérons d'abord l'exemple précédent.

y3=12(x1+x2+x3+x44+x2+x3+x4+x54)=x18+x24+x34+x44+x58y3=12(x1+x2+x3+x44+x2+x3+x4+x54)=x18+x24+x34+x44+x58

Cela suggère un motif général pour les tailles de fenêtres paires. En résumé, nous avons deux formules étroitement liées pour la SMA centrée, selon que TT est pair ou impair.

yk=1T(xk−(T−1)/2+…+xk+(T−1)/2),pourTimpairyk=1T(xk−(T−1)/2+…+xk+(T−1)/2),forTodd
yk=xk−T/22T+1T−2(xk−T/2+1+…+xk+T/2−1)+xk+T/22T,pourTpairyk=xk−T/22T+1T−2(xk−T/2+1+…+xk+T/2−1)+xk+T/22T,forTeven

Bien entendu, il existe des fonctions dans les logiciels statistiques qui peuvent calculer automatiquement la SMA centrée pour vous.

Différenciation

En mathématiques, la différence de premier ordre d'une suite (xn)=(x1,x2,x3,x4,…,xN)(xn)=(x1,x2,x3,x4,…,xN) est une autre suite, notée Δ(xk)Δ(xk), constituée des différences de termes consécutifs. C'est-à-dire :

Δ(xn)=(xn+1−xn)=(x2−x1,x3−x2,x4−x3,…,xN−xN−1)Δ(xn)=(xn+1−xn)=(x2−x1,x3−x2,x4−x3,…,xN−xN−1)

Notez qu'il y a un terme de moins dans la différence Δ(xn)Δ(xn) par rapport à la série temporelle originale (xn)(xn). La différenciation (differencing) a pour effet de stabiliser une tendance uniforme à la hausse ou à la baisse sans affecter les autres facteurs tels que les variations saisonnières et le bruit.

De plus, la moyenne (moyenne arithmétique) des termes de la série différentielle mesure le taux de variation de la série temporelle originale, tout comme le fait la pente de la régression linéaire. (En effet, si vous avez des notions de calcul infinitésimal, vous remarquerez peut-être qu'il existe un lien étroit entre la différenciation et le calcul de la dérivée d'une fonction continue.)

Exemple 5.4

Problème

Trouvez la série temporelle de différence de premier ordre pour les données du Tableau 5.1 et comparez-la avec le graphique linéaire original. Trouvez la moyenne de la série différentielle et comparez cette valeur à la pente de la régression linéaire trouvée dans l'Exemple 5.1.

Solution

Puisque la série temporelle originale du Tableau 5.1 comporte N=10N=10 termes, la différence ne comportera que 9 termes, comme le montre le Tableau 5.3.

Terme n Terme de l'indice S&P xnxn nenth terme de Δ(xn)Δ(xn)
1 1848,36 S/O
2 2058,9 2058.9−1848.36=210.542058.9−1848.36=210.54
3 2043,94 2043.94−2058.9=−14.962043.94−2058.9=−14.96
4 2238,83 2238.83−2043.94=194.892238.83−2043.94=194.89
5 2673,61 2673.61−2238.84=434.782673.61−2238.84=434.78
6 2506,85 2506.85−2673.61=−166.762506.85−2673.61=−166.76
7 3230,78 3230.78−2506.85=723.933230.78−2506.85=723.93
8 3756,07 3756.07−3230.78=525.293756.07−3230.78=525.29
9 4766,18 4766.18−3756.07=1010.114766.18−3756.07=1010.11
10 3839,5 3839.5−4766.18=−926.683839.5−4766.18=−926.68
11 4769,83 4769.83−3839.5=930.334769.83−3839.5=930.33
Tableau 5.3 Série temporelle de différence de premier ordre pour les données du Tableau 5.1 (source : adaptée de https://www.nasdaq.com/market-activity/index/spx/historical)

La Figure 5.11 montre le graphique des données originales avec leur série différentielle.

Un graphique linéaire intitulé Indice S&P à la fin de l'année 2013-2023. L'axe X comprend les années de 2013 à 2023 et l'axe Y s'étend de -2 000 à 6 000. L'indice S&P 500 commence à environ 1 900 en 2013, monte à environ 2 200 en 2016, puis fluctue entre 2 000 et 4 000 jusqu'en 2020 ; il monte à 4 800 en 2021, redescend à 4 000 en 2022 et remonte à 4 800 en 2023. La différence de premier ordre montre la variation de l'indice S&P 500 d'une année sur l'autre, les valeurs positives indiquant une augmentation et les valeurs négatives indiquant une diminution. La différence de premier ordre fluctue entre -2 000 et 1 000, avec une tendance générale à une volatilité croissante au fil du temps.
Figure 5.11 Comparaison des valeurs de l'indice S&P et de leur série différentielle (source des données : adaptée de S&P 500 [SPX] Historical Data)

La valeur moyenne de Δ(xn)Δ(xn) est :

1 10 ( 210.54 + ( − 14.96 ) + 194.89 + 434.78 + ( − 166.76 ) + 723.93 + 525.29 + 1,010.11 + ( − 926.68 ) + 930.33 ) = 292.15 1 10 ( 210.54 + ( − 14.96 ) + 194.89 + 434.78 + ( − 166.76 ) + 723.93 + 525.29 + 1,010.11 + ( − 926.68 ) + 930.33 ) = 292.15

En comparant avec la pente de la régression linéaire, qui est d'environ 304 (rappel de l'Exemple 5.1), nous constatons que les deux valeurs sont relativement proches l'une de l'autre.

La différenciation peut être utilisée pour vérifier si la courbe de tendance d'une série temporelle est essentiellement linéaire, quadratique ou polynomiale d'ordre supérieur. Tout d'abord, nous devons rappeler une définition d'algèbre qui s'applique généralement aux fonctions polynomiales mais qui peut également s'appliquer aux suites. Si une suite (xn)(xn) est donnée par une formule polynomiale de la forme

xn=f(n)=arnr+ar−1nr−1+…+a1n+a0xn=f(n)=arnr+ar−1nr−1+…+a1n+a0

où rr est un entier naturel, chacun des coefficients akak (pour k=1,2,3,…,nk=1,2,3,…,n) est une constante, et le terme de plus haut degré est non nul (ar≠0ar≠0), alors la suite a pour ordre ou degré rr. (L'ordre (order) ou degré (degree) fait référence au nombre de termes ou de décalages utilisés dans un modèle pour décrire la série temporelle.)

Par exemple, toute suite de la forme xn=an+bxn=an+b est d'ordre 1 (et peut être qualifiée de linéaire). Une suite de la forme xn=an2+bn+cxn=an2+bn+c est d'ordre 2 (et est appelée quadratique). Des données quadratiques s'ajustent bien à une parabole, ce qui indiquerait une tendance incurvée dans les données.

Si une suite (xn)(xn) est d'ordre r>0r>0, alors la suite des différences Δ(xn)Δ(xn) est d'ordre r−1r−1. Si la suite originale est déjà d'ordre 0, ce qui signifie que la suite est constante (tous les termes étant égaux à la même constante), alors la suite des différences produit simplement une autre suite constante (ordre 0) dans laquelle chaque terme est égal à 0. Ce résultat important peut être démontré mathématiquement, mais nous ne présenterons pas la démonstration dans ce texte.

À titre d'exemple, considérons la suite (xn)=(2,5,8,11,14,17,20)(xn)=(2,5,8,11,14,17,20), qui est d'ordre 1, puisque vous pouvez trouver ses valeurs à l'aide de la formule xn=3n−1xn=3n−1. La suite des différences est Δ(xn)=(3,3,3,3,3,3)Δ(xn)=(3,3,3,3,3,3), qui est une suite constante, donc d'ordre 0. Remarquez que prendre la différence une fois de plus donne la suite constante nulle, Δ(Δ(xn))=(0,0,0,0,0)Δ(Δ(xn))=(0,0,0,0,0), et calculer d'autres différences successives ne ferait que réduire le nombre de termes, mais chaque terme conserverait la valeur 0. (Par souci de simplicité, nous supposerons qu'il y a toujours suffisamment de termes dans une suite pour que la différence soit également une suite non vide.)

La différence de second ordre, Δ2(xn)=Δ(Δ(xn))Δ2(xn)=Δ(Δ(xn)), ou différence de la différence, réduirait l'ordre d'une suite d'ordre rr deux fois, pour atteindre r−2r−2 si r≥2r≥2, ou la suite constante nulle si r≤1r≤1. De manière générale, une différence d'ordre dd, définie par Δd(xn)=Δ(Δd−1(xn))Δd(xn)=Δ(Δd−1(xn)), réduit l'ordre d'une suite d'ordre rr à r−dr−d si r≥dr≥d, ou à l'ordre 0 sinon. En y réfléchissant un peu, vous réaliserez peut-être que nous disposons maintenant d'une procédure simple pour déterminer l'ordre d'une suite qui ne nécessite pas d'avoir sous la main la formule explicite de xnxn.

Si une suite (xn)(xn) a un ordre bien défini (en d'autres termes, s'il existe une formule polynomiale constituant un bon modèle pour les termes de la suite, même si nous ne connaissons pas encore cette formule), alors l'ordre rr est le plus petit entier naturel tel que la différence d'ordre rr, Δr+1(xn)Δr+1(xn), soit égale soit à une suite constante 0, soit à un bruit blanc.

Exemple 5.5

Problème

Déterminez l'ordre de la suite (10, 9, 6, 7, 18, 45, 94, 171) par différenciation.

Solution

Soit (xn)(xn) la suite donnée.

Différence de premier ordre : Δ(xn)=(−1,−3,1,11,27,49,77)Δ(xn)=(−1,−3,1,11,27,49,77)

Différence de second ordre : Δ2(xn)=(−2,4,10,16,22,28)Δ2(xn)=(−2,4,10,16,22,28)

Différence de troisième ordre : Δ3(xn)=(6,6,6,6,6)Δ3(xn)=(6,6,6,6,6)

Différence de quatrième ordre : Δ4(xn)=(0,0,0,0)Δ4(xn)=(0,0,0,0)

La suite donnée est d'ordre 3 puisque la différence d'ordre (3+1)(3+1) a donné uniquement des zéros.

Nous ne pouvons pas espérer rencontrer des données de séries temporelles réelles qui soient rigoureusement linéaires, quadratiques ou d'un degré exact donné. Chaque série temporelle comportera du bruit en plus d'éventuels motifs saisonniers. Cependant, la courbe tendance-cycle peut tout de même être bien approchée par un modèle polynomial d'un certain ordre.

SMA et différenciation dans Excel

Excel peut facilement calculer des moyennes mobiles simples et effectuer des différenciations. La possibilité d'écrire une formule dans une cellule, puis de la faire glisser vers le bas pour qu'elle s'applique à toutes les lignes de données est une fonctionnalité très puissante et pratique. À titre d'exemple, explorons le jeu de données MonthlyCoalConsumption.xlsx. Tout d'abord, vous devrez enregistrer le fichier en tant que feuille de calcul Excel, car les fichiers CSV ne prennent pas en charge les formules.

Incluons une SMA centrée avec une fenêtre de 13 termes (voir Figure 5.12). Dans la cellule C8, tapez « =AVERAGE(B2:B14) » comme indiqué sur la Figure 5.12. Remarque : il doit y avoir exactement 6 lignes au-dessus et 6 lignes en dessous de la ligne centrale au niveau de laquelle la formule est saisie.

Une capture d'écran d'une feuille de calcul Excel avec deux colonnes de texte intitulées Month et Value. 13 points de données dans la colonne Value (B) sont sélectionnés et la formule =AVERAGE(B2:B14) est appliquée dans la barre de formule.
Figure 5.12 Capture d'écran d'une SMA de fenêtre de 13 termes dans Excel (utilisée avec l'autorisation de Microsoft)

Ensuite, cliquez sur le petit carré dans le coin inférieur droit de la cellule C8 et faites-le glisser jusqu'à la cellule C173, qui se trouve 6 lignes avant la dernière valeur de données. La colonne C contient désormais la série temporelle SMA pour vos données, comme le montre la Figure 5.13.

Une capture d'écran d'une feuille de calcul Excel avec trois colonnes de texte étiquetées Month, Value et SMA. Les colonnes A et B comportent 19 lignes de données. La colonne C, commençant à la ligne 8, affiche la série temporelle SMA.
Figure 5.13 Capture d'écran montrant la série temporelle SMA dans la colonne C (utilisée avec l'autorisation de Microsoft)

Vous pouvez générer le graphique de la série temporelle et de la SMA ensemble, comme illustré à la Figure 5.14. Comparez votre SMA calculée avec la ligne de tendance créée par Excel dans la Figure 5.7.

Un graphique linéaire intitulé Consommation mensuelle de charbon pour la production d'électricité aux États-Unis de 2016 à 2022. L'axe X présente les mois de janvier 2016 à mai 2022. L'axe Y s'étend de 0 à 80 000. La ligne bleue représente la consommation réelle de charbon, qui fluctue de manière saisonnière avec des pics en hiver et des creux en été. La ligne orange représente la tendance de la consommation de charbon au fil du temps, montrant une tendance générale à la baisse passant d'environ 80 000 tonnes par mois en 2016 à environ 40 000 tonnes par mois en 2022.
Figure 5.14 Consommation mensuelle de charbon pour la production d'électricité aux États-Unis de 2016 à 2022. La SMA avec une fenêtre de longueur 13 a été ajoutée au graphique en orange. (source des données : https://www.statista.com/statistics/1170053/monthly-coal-energy-consumption-in-the-us/)

Calculons maintenant la différence de premier ordre. Le principe est très similaire. Placez la formule de la différence, qui n'est rien d'autre que « =B3-B2 », dans la cellule D3, comme sur la Figure 5.15.

Une capture d'écran d'une feuille de calcul Excel avec quatre colonnes étiquetées Month, Value, SMA et Difference. Les cellules B2 et B3 sont sélectionnées et la formule de différence =B3-B2 est appliquée dans la barre de formule.
Figure 5.15 Capture d'écran d'Excel montrant la formule de différence dans la colonne D (utilisée avec l'autorisation de Microsoft)

Faites ensuite glisser la formule vers le bas jusqu'à la fin de la colonne. Le résultat est présenté sur la Figure 5.16.

Une capture d'écran d'une feuille de calcul Excel avec quatre colonnes étiquetées Month, Value, SMA et Difference. La ligne D montre que la formule de différence =B3-B2 a été appliquée à l'ensemble de la colonne.
Figure 5.16 Capture d'écran d'Excel montrant la différence dans la colonne D (utilisée avec l'autorisation de Microsoft)

Si vous devez calculer les différences de second ordre, appliquez simplement la même procédure pour trouver la différence de la colonne D. Les différences d'ordre supérieur peuvent facilement être calculées de façon analogue.

SMA et différenciation en Python

Le calcul d'une SMA en Python ne nécessite qu'une seule ligne de code. Voici comment cela fonctionne sur l'ensemble de données sur la consommation de charbon (trouvé dans MonthlyCoalConsumption.xlsx), en utilisant une taille de fenêtre de 12. (Auparavant, nous avions utilisé une fenêtre de 13 car les fenêtres de longueur impaire sont plus simples à manipuler que celles de longueur paire. Cependant, Python gère facilement tous les cas de manière automatique.) L'élément clé ici est la fonction rolling() qui crée un DataFrame de fenêtres glissantes de la longueur spécifiée. Ensuite, la commande mean() calcule la moyenne de chaque fenêtre de données. Le calcul de la différence de premier ordre est tout aussi simple, grâce à la commande diff().

Code Python

    
    # Import libraries
    import pandas as pd # for dataset management
    import matplotlib.pyplot as plt # for visualizations
    from matplotlib.ticker import MaxNLocator, FuncFormatter # for graph formatting and y-axis formatting
    import matplotlib.dates as mdates # for date formatting
    
    # Read the Excel file into a Pandas DataFrame
    df = pd.read_excel('MonthlyCoalConsumption.xlsx')
    
    # Convert 'Month' column to datetime format
    df['Month'] = pd.to_datetime(df['Month'], format='%m/%d/%Y')
    
    # Calculate a simple moving average with a window size of 12
    df['SMA'] = df['Value'].rolling(window=12).mean()
    
    # Calculate the first-order difference
    df['Diff'] = df['Value'].diff()
    
    # Function to format the Y-axis values
    def y_format(value, tick_number):
      return f'{int(round (value)):,}'
    
    # Create the plot
    plt.figure(figsize=(12, 6))
    
    # Plot the time series, SMA, and difference
    plt.plot(df['Month'], df['Value'], marker='', linestyle='-', color='b', label='Value')
    plt.plot(df['Month'], df['SMA'], marker='', linestyle='-', color='r', label='SMA')
    plt.plot(df['Month'], df['Diff'], marker='', linestyle='-', color='g', label='Diff')
    
    # Set the x-axis limits to start from the first date and end at the maximum date in the data
    plt.xlim(pd.to_datetime('01/01/2016', format='%m/%d/%Y'), df['Month'].max())
    
    # Format the x-axis to show dates as MM/DD/YYYY and set the locator for a fixed number of ticks
    ax = plt.gca()
    ax.xaxis.set_major_formatter(mdates.DateFormatter('%m/%d/%Y'))
    ax.xaxis.set_major_locator(MaxNLocator(nbins=12)) # Set the number of ticks to a reasonable value
    
    # Manually set the rotation of date labels to 45 degrees
    plt.xticks(rotation=45)
    
    # Title and labels
    plt.title('Monthly Consumption of Coal for Electricity Generation in the United States from 2016 to 2022')
    plt.xlabel('Month')
    plt.legend()
    
    # Apply the formatter to the Y-axis
    ax.yaxis.set_major_formatter(FuncFormatter(y_format))
    
    plt.tight_layout() # Adjust layout to ensure labels fit well
    plt.show() 
    

La sortie obtenue ressemblera à ceci :

Une capture d'écran d'une sortie Python de graphique linéaire étiquetée Un graphique linéaire intitulé Monthly consumption of coal for electricity generation in the United States from 2016 to 2022. L'axe X comporte les mois de juillet 2016 à janvier 2022. L'axe Y s'étend de -20 000 à 60 000. La ligne bleue représente la consommation réelle de charbon, qui fluctue de manière saisonnière. La ligne rouge représente la moyenne mobile simple (SMA) sur 3 mois de la consommation de charbon, qui lisse les fluctuations saisonnières. La ligne verte représente la différence entre la consommation réelle et la SMA sur 3 mois, mettant en évidence les variations saisonnières. La consommation de charbon montre une tendance générale à la baisse, passant d'environ 80 000 tonnes par mois en 2016 à environ 40 000 tonnes par mois en 2022.

Analyse de la saisonnalité

Une fois que la série temporelle a été corrigée de sa tendance à l'aide de l'une des méthodes déjà abordées (ou d'autres méthodes plus sophistiquées), ce qui reste ne devrait représenter que la saisonnalité (seasonality), ou variation saisonnière, snsn, et le terme d'erreur, εnεn.

zn=sn+εnzn=sn+εn

Comment pourrions-nous analyser et modéliser snsn ? Supposons qu'il n'y ait aucun terme d'erreur (εn=0)(εn=0) et que nous observions donc une série temporelle présentant une variation saisonnière pure, sans aucun autre facteur. Dans ce cas, le composant snsn ressemblerait à un motif répétitif, tel que le motif illustré à la figure 5.17. Comme mentionné dans Composants de l'analyse des séries temporelles, l'intervalle de temps nécessaire pour que le motif s'accomplisse une fois et commence à se répéter est appelé la période. Dans un composant purement saisonnier, nous nous attendrions à ce que sn+P=snsn+P=sn, où PP est la période, pour toutes les valeurs de nn.

Un graphique linéaire. L'axe des X s'étend de 1 à 225. L'axe des Y s'étend de -5 à 5. Une ligne bleue montre des hauts et des bas représentant une variation saisonnière pure. Le même motif se répète après 64 étapes temporelles.
Figure 5.17 Variation saisonnière pure. Le même motif se répète après 64 étapes temporelles, la période est donc de 64.

Bien qu'il soit facile de repérer le motif répétitif dans une série temporelle sans bruit, il n'en va pas de même dans le cas général. Plusieurs outils sont disponibles pour isoler le composant saisonnier d'une série temporelle corrigée de sa tendance.

Identifier la période

Tout d'abord, nous devons identifier la période des données saisonnières. La méthode la plus simple consiste à utiliser les connaissances préalables sur les données de la série temporelle, accompagnées d'une inspection visuelle. Souvent, un motif saisonnier est exactement cela : un motif qui se répète sur une durée d'un an. Ainsi, la période serait de P=1P=1 an (ou 12 mois, 52 semaines, 365 jours, etc., selon les étapes temporelles de votre série temporelle). Par exemple, même sans éliminer la tendance des données, il était facile d'identifier une période de 4 trimestres (1 an) dans les données de l'exemple 5.2.

Si la répétition d'un motif saisonnier n'est pas évidente à partir des données, elle peut être découverte à l'aide de mesures statistiques standard telles que l'autocorrélation. L'autocorrélation (autocorrelation) est la mesure de la corrélation entre une série temporelle et la même série temporelle décalée d'un certain nombre d'étapes temporelles. (La section Analyse de corrélation et de régression linéaire a abordé la corrélation entre deux ensembles de données. L'autocorrélation est la même idée appliquée au même ensemble de données avec une copie décalée de lui-même.) L'amplitude du décalage est appelée le décalage (lag).

La fonction d'autocorrélation (ACF) mesure la corrélation à chaque décalage en commençant par 0 ou 1. Notez que le décalage 0 produit toujours une autocorrélation de 1 puisque la série temporelle est comparée à une copie exacte d'elle-même. Ainsi, nous ne nous intéressons qu'au coefficient de corrélation aux décalages positifs. Cependant, les petits décalages montrent généralement aussi une corrélation élevée avec la série temporelle originale, simplement parce que les données mesurées sur des périodes de temps plus courtes sont généralement similaires les unes aux autres. Ainsi, même si l'ACF montre une corrélation relativement importante à des décalages de 1, 2, 3, etc., il se peut qu'aucun véritable composant saisonnier ne soit présent. Le décalage positif correspondant au premier pic (peak) significatif, ou à une valeur d'autocorrélation beaucoup plus grande que les valeurs précédentes, peut indiquer un composant saisonnier ayant cette période.

Plus loin, nous verrons comment calculer l'ACF d'une série temporelle à l'aide de Python, mais explorons d'abord d'autres sujets concernant les composants saisonniers.

Données désaisonnalisées

Une fois que vous avez déterminé la période du composant saisonnier, vous pouvez ensuite extraire snsn de la série temporelle. Comme d'habitude, il existe plusieurs façons de procéder.

Supposons que vous ayez éliminé la tendance de la série temporelle de sorte que ce qui reste consiste en un composant saisonnier et un terme de bruit :

zn=xn−tn=sn+εnzn=xn−tn=sn+εn

De plus, supposons que la période de snsn soit PP. Bien sûr, avec le terme de bruit toujours présent dans la série temporelle, nous ne pouvons pas nous attendre à ce que l'égalité sn+P=snsn+P=sn soit vérifiée, mais il devrait être vrai que sn+P≈snsn+P≈sn pour tout nn. En d'autres termes, les données devraient avoir approximativement la même allure lorsqu'elles sont décalées de PP étapes temporelles. Notre tâche consiste désormais à isoler une période complète de données qui modélise la variation saisonnière tout au long de la série temporelle. En d'autres termes, nous voulons produire une estimation s^ns^n qui soit exactement périodique (s^n+P=s^ns^n+P=s^n, pour tout nn) et qui modélise le composant saisonnier sous-jacent aussi fidèlement que possible.

Pour tout index donné n<Pn<P, nous nous attendons à ce que les points de données (zn,zn+P,zn+2P,zn+3P,…)(zn,zn+P,zn+2P,zn+3P,…) gravitent autour de la même valeur ou, dans le langage statistique, présentent une variance plutôt faible (bien inférieure à celle de la série temporelle dans son ensemble). Il semble donc raisonnable d'utiliser la moyenne de cette tranche de données pour définir la valeur de s^ns^n. Par souci de simplicité, supposons que la série temporelle compte exactement M·PM·P points de données (si ce n'est pas le cas, les données peuvent être complétées de manière appropriée). L'estimation du composant saisonnier serait alors définie pour 1≤n<P1≤n<P par la formule

s^n=1M(zn+zn+P+zn+2P+zn+3P+…+zn+(M−1)P)s^n=1M(zn+zn+P+zn+2P+zn+3P+…+zn+(M−1)P)

Comme d'habitude, la formule semble plus intimidante que le concept sur lequel elle repose. Comme mentionné précédemment, cela ne représente rien de plus que la moyenne de toutes les valeurs de la série temporelle qui se produisent toutes les PP étapes temporelles.

Une fois que s^ns^n est calculé dans la plage 1≤n<P1≤n<P, étendez-le en répétant les mêmes valeurs dans chaque période jusqu'à ce que vous atteigniez le dernier index de la série originale (n=MP)(n=MP). (Remarque : Le terme de bruit peut maintenant être estimé comme la série des résidus, εn≈sn−s^nεn≈sn−s^n, qui retiendra notre attention dans Méthodes d'évaluation des prévisions.)

Enfin, l'estimation s^ns^n peut ensuite être utilisée conjointement avec la série temporelle originale (xn)(xn) pour lisser la variation saisonnière. Notez que s^ns^n mesure essentiellement les fluctuations des données observées xnxn au-dessus ou en dessous de la tendance. Nous nous attendons à ce que la moyenne de s^ns^n soit proche de zéro sur toute fenêtre de temps. Définissons les données désaisonnalisées comme la série temporelle

xn−s^nxn−s^n

Une série temporelle désaisonnalisée est étroitement liée à la courbe tendance-cycle sous-jacente, tntn, bien qu'elle contienne généralement le bruit et d'autres facteurs aléatoires que tntn n'inclut généralement pas.

Exemple 5.6

Problème

Les données de revenus de Walt’s Water Adventures (voir le tableau 5.2) semblent afficher une saisonnalité de période 4. En utilisant le niveau comme tendance, éliminez la tendance des données, calculez le composant saisonnier s^ns^n et trouvez la série temporelle désaisonnalisée.

Solution

Tout d'abord, nous devons éliminer la tendance des données. Le niveau est la moyenne des 12 observations. À l'aide d'une calculatrice ou d'un logiciel, on trouve que le niveau est de L=2,275.42L=2,275.42. Soustrayez xn−Lxn−L pour éliminer la tendance des données (voir le tableau 5.4). Par exemple, le premier terme des données sans tendance serait z1=x1−L=1,799−2,275.42=−476.42z1=x1−L=1,799−2,275.42=−476.42.

Il y a un total de 12 observations, il y aura donc M=12/4=3M=12/4=3 périodes de taille P=4P=4. En utilisant les valeurs de znzn dans la formule de s^ns^n, nous trouvons :

s ^ 1 = 1 3 ( z 1 + z 5 + z 9 ) = 1 3 ( ( − 476.42 ) + 8.58 + 428.58 ) = − 13.08 s ^ 2 = 1 3 ( z 2 + z 6 + z 10 ) = 1 3 ( 1,028.58 + 1,183.58 + 1,573.58 ) = 1,261.92 s ^ 3 = 1 3 ( z 3 + z 7 + z 11 ) = 1 3 ( ( − 996.42 ) + ( − 311.42 ) + ( − 144.42 ) ) = − 484.08 s ^ 4 = 1 3 ( z 4 + z 8 + z 12 ) = 1 3 ( ( − 1,276.42 ) + ( − 681.42 ) + ( − 336.42 ) ) = − 764.75 s ^ 1 = 1 3 ( z 1 + z 5 + z 9 ) = 1 3 ( ( − 476.42 ) + 8.58 + 428.58 ) = − 13.08 s ^ 2 = 1 3 ( z 2 + z 6 + z 10 ) = 1 3 ( 1,028.58 + 1,183.58 + 1,573.58 ) = 1,261.92 s ^ 3 = 1 3 ( z 3 + z 7 + z 11 ) = 1 3 ( ( − 996.42 ) + ( − 311.42 ) + ( − 144.42 ) ) = − 484.08 s ^ 4 = 1 3 ( z 4 + z 8 + z 12 ) = 1 3 ( ( − 1,276.42 ) + ( − 681.42 ) + ( − 336.42 ) ) = − 764.75

Répétez ensuite ce bloc de 4 valeurs selon les besoins pour obtenir l'ensemble du composant saisonnier. Enfin, la série temporelle désaisonnalisée est la différence entre les données observées et le composant saisonnier (voir le tableau 5.4).

k Trimestre Revenus Sans tendance
zkzk
Comp. sais. s^ks^k Désaisonnalisé xn−s^nxn−s^n
1 Printemps 2021 1799 −­476.42 −­13.08 1812.08
2 Été 2021 3304 1028.58 1261.92 2042.08
3 Automne 2021 1279 −­996.42 −­484.08 1763.08
4 Hiver 2021 999 −­1276.42 ­−764.75 1763.75
5 Printemps 2022 2284 8.58 −­13.08 2297.08
6 Été 2022 3459 1183.58 1261.92 2197.08
7 Automne 2022 1964 ­−311.42 ­−484.08 2448.08
8 Hiver 2022 1594 −­681.42 −­764.75 2358.75
9 Printemps 2023 2704 428.58 −­13.08 2717.08
10 Été 2023 3849 1573.58 1261.92 2587.08
11 Automne 2023 2131 ­−144.42 ­−484.08 2615.08
12 Hiver 2023 1939 ­−336.42 ­−764.75 2703.75
Tableau 5.4 Revenus trimestriels pour les locations de kayaks et de canoës (toutes les colonnes en $). Les colonnes pour les données sans tendance, l'estimation du composant saisonnier et les données désaisonnalisées sont incluses.

La figure 5.18 montre les données ainsi que le composant saisonnier et les données désaisonnalisées.

Un graphique linéaire intitulé Revenus trimestriels pour les locations de kayaks et de canoës. L'axe des X présente des dates allant du printemps 2021 à l'hiver 2023. L'axe des Y s'étend de -1 000 $ à 5 000 $. Une ligne bleue des revenus montre des hauts et des bas de 1 000 $ à 4 000 $ avec des pics en été. Une ligne verte ayant la même forme que la ligne bleue représente le composant saisonnier, de -1 000 $ à 1 000 $. Une ligne orange d'ajustement saisonnier est relativement plate de 2 000 $ à 3 000 $.
Figure 5.18 Revenus trimestriels pour les locations de kayaks et de canoës. Le composant saisonnier et la série temporelle désaisonnalisée sont inclus sur le graphique.

Décomposition d'une série temporelle en composants à l'aide de Python

Il existe une puissante bibliothèque Python appelée statsmodels qui rassemble de nombreuses fonctions statistiques utiles. Nous utiliserons le module STL pour décomposer la série temporelle MonthlyCoalConsumption.xlsx en ses composants. Tout d'abord, nous traçons une ACF (fonction d'autocorrélation) (ACF (autocorrelation function)) pour déterminer la meilleure valeur pour la périodicité.

Code Python

    # Import libraries
    from statsmodels.graphics.tsaplots import plot_acf
    
    # Read the Excel file into a Pandas Dataframe
    df = pd.read_excel('MonthlyCoalConsumption.xlsx')
    
    # Plot the ACF
    plot_acf(df['Value'], lags=20, title='ACF');
    

La sortie résultante ressemblera à ceci :

Tracé ACF avec 21 décalages. L'axe des y s'étend de -1 à 1 et l'axe des x de 0 à 20. Le graphique montre les valeurs d'autocorrélation pour chaque décalage, avec les intervalles de confiance indiqués par des zones ombrées.

Les points situés dans la zone ombrée bleue correspondent à des décalages pour lesquels l'autocorrélation est statistiquement non significative. Les décalages qui montrent la plus grande significativité se situent à 0, 1, 6 et 12. Décalage=0Décalage=0 donne toujours 100 % d'autocorrélation car nous comparons la série non décalée à elle-même. À décalage=1décalage=1, une autocorrélation élevée correspond au fait que des points de données consécutifs sont relativement proches les uns des autres (ce qui est également attendu dans la plupart des ensembles de données). Il convient de noter en particulier les décalages à 6 et 12, correspondant à une possible période saisonnière de 6 ou 12 dans les données. Nous utiliserons la période 12 dans notre décomposition STL.

Code Python

    # Import libraries
    from statsmodels.tsa.seasonal import STL
    import matplotlib.pyplot as plt ## for data visualization
    
    # Perform seasonal decomposition using STL
    stl = STL(df['Value'], period=12)
    result = stl.fit()
    
    # Plot components and format the y-axis labels
    fig = result.plot()
    for ax in fig.axes:
      ax.yaxis.set_major_formatter(FuncFormatter(y_format))
    
    plt.show()
    

La sortie résultante ressemblera à ceci :

 
Un graphique de décomposition de série temporelle étiqueté Value avec quatre sous-graphiques : les données originales sont sur l'axe des X (0 à 75). Sur l'axe des Y se trouvent la tendance (40 000 à 60 000), le composant saisonnier (-10 000 à 10 000) et les résidus (-5 000 à 5 000).

La tendance, la variation saisonnière et les composants résiduels (bruit) sont tous représentés sur des graphiques séparés. Pour les voir tous sur le même ensemble d'axes, nous pouvons utiliser matplotlib (bruit omis).

Code Python

    import matplotlib.pyplot as plt ## for data visualization
    
    # Extract the trend and seasonal components
    trend = result.trend
    seasonal = result.seasonal
    
    # Plot the original data, trend, and seasonally adjusted data
    plt.plot(df['Value'], label='Original Data')
    plt.plot(trend, label='Trend')
    plt.plot(seasonal, label='Seasonal')
    plt.legend()
    
    # Apply the formatter to the Y-axis
    plt.gca().yaxis.set_major_formatter(FuncFormatter(y_format))
    plt.show()
    

La sortie résultante ressemblera à ceci :

Un graphique de série temporelle montrant les données originales, la tendance et les composants saisonniers. L'axe des Y s'étend de 0 à 70 000, l'axe des X de 0 à 80. La ligne de tendance est en pente descendante et le composant saisonnier fluctue autour de zéro.

Moyennes mobiles pondérées et moyennes mobiles exponentielles

Les moyennes mobiles simples ont été abordées en détail au début de cette section. Nous élargissons maintenant la discussion pour inclure des moyennes mobiles pondérées plus sophistiquées et leurs utilisations dans le lissage des données et la prévision. Rappelons d'après notre discussion dans Méthodes de prévision des séries temporelles que les moyennes mobiles pondérées sont des moyennes mobiles dans lesquelles les termes reçoivent des poids selon une formule ou une règle définie.

Supposons qu'une série temporelle (xn)(xn) n'a aucun composant saisonnier significatif (ou que le composant saisonnier a été retiré afin que la série restante soit désaisonnalisée). Ainsi, la série ne comporte que des composants de tendance-cycle et de bruit :

xn=tn+εnxn=tn+εn

Comme nous l'avons déjà mentionné, une moyenne mobile simple (SMA) a pour effet de lisser les données et de fournir une méthode simple pour prédire le terme suivant de la séquence. Pour référence, voici le modèle de prédiction SMA, avec une fenêtre de TT termes :

x^n+1=xn+xn−1+xn−2+…+xn−T+1Tx^n+1=xn+xn−1+xn−2+…+xn−T+1T

Ce modèle peut être considéré comme un modèle de moyenne mobile pondérée (WMA) dans lequel les poids des TT termes les plus récents sont tous égaux à 1T1T, tandis que tous les autres poids sont fixés à 0. Par exemple, dans un modèle SMA avec T=3T=3, les poids seraient 13,13,13,0,0,0,0,…13,13,13,0,0,0,0,…

x^n+1=xn+xn−1+xn−23=13xn+13xn−1+13xn−2+0xn−3+0xn−4+…x^n+1=xn+xn−1+xn−23=13xn+13xn−1+13xn−2+0xn−3+0xn−4+…

Même le modèle naïf, x^n+1=xnx^n+1=xn, compte comme une WMA, avec des poids 1, 0, 0, …

En principe, un modèle de moyenne mobile pondérée peut être construit à l'aide de n'importe quels coefficients, ce qui donne une forme générale pour toute WMA :

x^n+1=anxn+an−1xn−1+an−2xn−2+an−3xn−3+…x^n+1=anxn+an−1xn−1+an−2xn−2+an−3xn−3+…

Bien entendu, si nous voulons que le modèle fonctionne bien pour prévoir de nouvelles valeurs de la série temporelle, les coefficients doivent être choisis judicieusement. En règle générale, les poids doivent être normalisés (normalized), ce qui signifie que leur somme est égale à 1.

an+an−1+an−2+an−3+…=1an+an−1+an−2+an−3+…=1

Cependant, il n'existe aucune exigence stricte imposant que la somme soit égale à 1.

Plutôt que d'attribuer le même poids à un certain nombre de termes précédents comme le fait le modèle SMA, vous pouvez choisir d'accorder un poids plus important aux termes les plus récents. Par exemple, on pourrait utiliser des puissances de 1212 comme poids.

x^n+1=12xn+14xn−1+18xn−2+116xn−3+…x^n+1=12xn+14xn−1+18xn−2+116xn−3+…

Cette méthode permet au terme le plus récent de dominer la somme, et chaque terme successif contribue pour moitié moins à son tour. (Remarque : la suite 1212, 1414, 1818, 116,…116,… serait une suite normalisée si une infinité de termes étaient inclus, mais même un petit nombre fini de termes, comme environ 5, donne une somme très proche de 1.)

Il s'agit d'un exemple de moyenne mobile exponentielle, ou EMA. La formule la plus générale pour le modèle EMA est présentée ci-dessous. (Notez que l'exemple précédent correspond à un modèle EMA avec α=12α=12).

x^n+1=αxn+α(1−α)xn−1+α(1−α)2xn−2+α(1−α)3xn−3+…x^n+1=αxn+α(1−α)xn−1+α(1−α)2xn−2+α(1−α)3xn−3+…

Exemple 5.7

Problème

Utilisez les modèles EMA avec α=12α=12 (de manière équivalente, 0,5) et α=0.7α=0.7 pour les données de l'indice S&P du Tableau 5.1 afin d'estimer la valeur de l'indice S&P à la fin de l'année 2023.

Solution

Tout d'abord, pour α=12α=12, le modèle est :

x ^ n + 1 = 1 2 x n + 1 4 x n − 1 + 1 8 x n − 2 + 1 16 x n − 3 + … x ^ n + 1 = 1 2 x n + 1 4 x n − 1 + 1 8 x n − 2 + 1 16 x n − 3 + …

Injectez maintenant les données (pensez à utiliser le point de données le plus récent en premier et à remonter vers le passé). Huit termes ont été utilisés, car les termes au-delà de ce point sont très proches de 0. Le Tableau 5.2 consigne les résultats.

Pour α=0.7α=0.7, utilisez la formule des poids,

α=0.7α=0.7, α(1−α)=0.7(1−0.7)=0.7(0.3)=0.21α(1−α)=0.7(1−0.7)=0.7(0.3)=0.21, α(1−α)2=0.7(0.3)2=0.063α(1−α)2=0.7(0.3)2=0.063, etc. Cette fois, les coefficients diminuent plus rapidement que dans le cas α=12α=12, de sorte que seuls 5 termes sont significatifs. Le Tableau 5.5 présente les résultats.

Année Index S&P en fin d'année Pondération exponentielle α=12α=12 Pondération exponentielle α=0.7α=0.7
2013 1848.36 ≈0≈0 ≈0≈0
2014 2058.9 ≈0≈0 ≈0≈0
2015 2043.94 1512·2043.94=3.991512·2043.94=3.99 ≈0≈0
2016 2238.83 1256·2238.83=8.751256·2238.83=8.75 ≈0≈0
2017 2673.61 1128·2673.61=20.891128·2673.61=20.89 ≈0≈0
2018 2506.85 164·2506.85=39.17164·2506.85=39.17 0.00567·2506.9=4.260.00567·2506.9=4.26
2019 3230.78 132·3230.78=100.96132·3230.78=100.96 0.00567·3230.78=18.320.00567·3230.78=18.32
2020 3756.07 116·3756.07=234.75116·3756.07=234.75 0.0189·3756.07=70.990.0189·3756.07=70.99
2021 4766.18 18·4766.18=595.7718·4766.18=595.77 0.063·4766.18=300.270.063·4766.18=300.27
2022 3839.5 14·3839.5=959.8814·3839.5=959.88 0.21·3839.5=806.300.21·3839.5=806.30
2023 4769.83 12·4769.83=2384.9212·4769.83=2384.92 0.7·4769.83=3338.880.7·4769.83=3338.88
2024 SOMME=4349SOMME=4349 SOMME=4541SOMME=4541
Tableau 5.5 Modèles EMA (source : adapté de https://www.nasdaq.com/market-activity/index/spx/historical)

Par conséquent, nous trouvons des estimations de 4 349 et 4 541 pour la valeur du S&P à la fin de 2024, au moyen de modèles EMA avec α=12α=12 et α=0.7α=0.7, respectivement. Notez que des valeurs plus élevées de αα mettent l'accent sur les données les plus récentes, tandis que des valeurs plus faibles permettent à davantage de points de données passés d'influencer la moyenne. Si la tendance de la série temporelle subit une plus grande variabilité (due à des facteurs externes sur lesquels nous n'avons aucun contrôle), une EMA avec une valeur de αα relativement élevée serait plus appropriée qu'une autre avec une petite valeur de αα.

Les modèles EMA peuvent également servir de techniques de lissage, isolant le composant de tendance-cycle. Dans ce contexte, il est préférable d'utiliser une forme équivalente du modèle EMA :

x^n+1=αxn+(1−α)x^nx^n+1=αxn+(1−α)x^n

Sous cette forme, nous construisons une série d'estimations (x^n)(x^n) de manière récursive en intégrant les termes de la série temporelle originale un par un. L'idée est que l'estimation suivante, x^n+1x^n+1, est trouvée par la moyenne pondérée du point de données actuel, xnxn, et de l'estimation actuelle, x^nx^n. Notez que nous pouvons poser x^1=x1x^1=x1 puisque nous devons commencer le processus quelque part. On peut montrer mathématiquement que cette procédure est essentiellement la même que le calcul direct de la somme des termes pondérés de manière exponentielle, tout en étant beaucoup plus efficace.

Exemple 5.8

Problème

Utilisez la formule récursive de l'EMA avec α=0.75α=0.75 pour lisser la série temporelle de l'indice S&P (Tableau 5.1), puis utilisez le modèle EMA pour estimer la valeur de l'indice S&P à la fin de 2024. Tracez l'EMA ainsi que la série temporelle originale.

Solution

Avec α=0.75α=0.75, la formule récursive de l'EMA devient : x^n+1=0.75xn+0.25x^nx^n+1=0.75xn+0.25x^n. Le Tableau 5.6 présente les résultats du calcul.

Année Index S&P en fin d'année Estimation EMA
2013 x1=1848.36x1=1848.36 x^1=x1=1848.36x^1=x1=1848.36
2014 x2=2058.9x2=2058.9 x^2=0.75x1+0.25x^1=0.75(1848.36)+0.25(1848.36)=1848.36x^2=0.75x1+0.25x^1=0.75(1848.36)+0.25(1848.36)=1848.36
2015 x3=2043.94x3=2043.94 x^3=0.75x2+0.25x^2=0.75(2058.9)+0.25(1848.36)=2006.27x^3=0.75x2+0.25x^2=0.75(2058.9)+0.25(1848.36)=2006.27
2016 x4=2238.83x4=2238.83 x^4=0.75x3+0.25x^3=0.75(2043.94)+0.25(2006.27)=2034.52x^4=0.75x3+0.25x^3=0.75(2043.94)+0.25(2006.27)=2034.52
2017 x5=2673.61x5=2673.61 x^5=0.75x4+0.25x^4=0.75(2238.83)+0.25(2034.52)=2187.75x^5=0.75x4+0.25x^4=0.75(2238.83)+0.25(2034.52)=2187.75
2018 x6=2506.85x6=2506.85 x^6=0.75x5+0.25x^5=0.75(2673.61)+0.25(2187.75)=2552.15x^6=0.75x5+0.25x^5=0.75(2673.61)+0.25(2187.75)=2552.15
2019 x7=3230.78x7=3230.78 x^7=0.75x6+0.25x^6=0.75(2506.85)+0.25(2552.15)=2518.17x^7=0.75x6+0.25x^6=0.75(2506.85)+0.25(2552.15)=2518.17
2020 x8=3756.07x8=3756.07 x^8=0.75x7+0.25x^7=0.75(3230.78)+0.25(2518.17)=3052.63x^8=0.75x7+0.25x^7=0.75(3230.78)+0.25(2518.17)=3052.63
2021 x9=4766.18x9=4766.18 x^9=0.75x8+0.25x^8=0.75(3756.07)+0.25(3052.63)=3580.21x^9=0.75x8+0.25x^8=0.75(3756.07)+0.25(3052.63)=3580.21
2022 x10=3839.5x10=3839.5 x^10=0.75x9+0.25x^9=0.75(4766.18)+0.25(3580.21)=4469.69x^10=0.75x9+0.25x^9=0.75(4766.18)+0.25(3580.21)=4469.69
2023 x11=4769.83x11=4769.83 x^11=0.75x10+0.25x^10=0.75(3839.5)+0.25(4469.69)=3997.05x^11=0.75x10+0.25x^10=0.75(3839.5)+0.25(4469.69)=3997.05
2024 N/A x^12=0.75x11+0.25x^11=0.75(4769.83)+0.25)3997.05)=4576.63x^12=0.75x11+0.25x^11=0.75(4769.83)+0.25)3997.05)=4576.63
Tableau 5.6 Lissage EMA pour la série temporelle de l'indice S&P (source : adapté de https://www.nasdaq.com/market-activity/index/spx/historical)

Selon ce modèle, l'indice S&P sera d'environ 4577 à la fin de 2024. La Figure 5.19 montre la série temporelle ainsi que le modèle de lissage exponentiel.

Un graphique linéaire intitulé S&P Index at the End of Year 2013-2023. L'axe des X présente les années de 2013 à 2024 et l'axe des Y s'étend de 0 à 6 000. Une ligne bleue représentant le SP 500 montre une tendance générale à la hausse au cours de la dernière décennie. Une ligne orange représentant le modèle de lissage exponentiel suit une trajectoire similaire mais légèrement différée.
Figure 5.19 Modèle de lissage exponentiel pour l'indice S&P (source des données : adapté de S&P 500 [SPX] Historical Data)

Remarque : le lissage EMA peut être réalisé très facilement dans Excel. Saisissez simplement les formules =B2 dans la cellule C2 et =0.75*B2+0.25*C2 dans la cellule C3. Faites ensuite glisser la cellule C3 vers le bas jusqu'à la fin des données pour calculer l'EMA. Vous pouvez également effectuer un lissage EMA en Python à l'aide de la fonction ewm() appliquée à un ensemble de données. Notez que la valeur « span » doit être définie sur 2α−12α−1, comme indiqué dans ce code.

Code Python

    # Import libraries
    import pandas as pd ## for dataset management
    
    # Creating a dictionary with the given data
    data = {
      'Year': [2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023],
      'SP500': [1848.36, 2058.9, 2043.94, 2238.83, 2673.61, 2506.85, 3230.78, 3756.07, 4766.18, 3839.5, 4769.83]
    }
    # Creating DataFrame
    df = pd.DataFrame(data)
    
    alpha = 0.75
    df['ema']=df['SP500'].ewm(span=2/alpha-1, adjust=False).mean()
    
    print(df['ema'])
    

La sortie résultante ressemblera à ceci :

0   1848.360000
1   2006.265000
2   2034.521250
3   2187.752812
4   2552.145703
5   2518.173926
6   3052.628481
7   3580.209620
8   4469.687405
9   3997.046851
10  4576.634213
Name: ema, dtype: float64

Modèle autorégressif intégré à moyenne mobile (ARIMA)

Dans cette section, nous développons un outil très puissant qui combine plusieurs modèles et est capable de capturer la tendance et la saisonnalité. La méthode est appelée moyenne mobile autorégressive intégrée, ou ARIMA en abrégé, et elle se compose de trois composants principaux :

  1. Modèle autorégressif (AR) (Autoregressive (AR) model). Ce composant capture les motifs de la série temporelle qui se répètent, y compris les composants saisonniers ainsi que la corrélation avec les valeurs récentes.
  2. Composante intégrée (I) (Integrative (I) component). Ce composant représente l'opération de différenciation abordée dans la section sur l'élimination de la tendance d'une série temporelle.
  3. Modèle de moyenne mobile (MA). Malgré son nom, ce composant n'est pas identique à la moyenne mobile discutée précédemment, bien qu'il existe un lien mathématique. Au lieu de se concentrer sur les moyennes des points de données existants, les modèles MA intègrent l'influence des erreurs de prévision passées pour prédire la valeur suivante de la série temporelle.

Avant d'entrer dans les spécificités de chaque composant d'ARIMA, nous devons aborder le terme stationnaire, qui fait référence à une série temporelle dans laquelle la variance est relativement constante dans le temps, où aucune tendance générale à la hausse ou à la baisse ne peut être observée et où aucun motif saisonnier n'existe. Le bruit blanc est un exemple de série temporelle stationnaire ; cependant, le terme stationnaire est un peu plus général, car il inclut la possibilité d'un composant cyclique dans les données. Rappelons qu'un composant cyclique (malgré son nom) est une hausse ou une baisse à plus long terme des valeurs d'une série temporelle qui peut se produire de temps à autre, mais dont les occurrences sont imprévisibles.

Les modèles AR et MA fonctionnent mieux sur des séries temporelles stationnaires. Le composante intégrée est l'outil qui permet d'éliminer la tendance des données, transformant une série temporelle non stationnaire en une série stationnaire afin qu'AR et/ou MA puissent être utilisés.

Modèles autorégressifs

Les modèles autorégressifs prennent en compte un nombre fixe de valeurs précédentes de la série temporelle afin de prédire la valeur suivante. De cette manière, les modèles AR ressemblent beaucoup aux modèles WMA présentés précédemment, dans le sens où le terme suivant de la série temporelle dépend d'une somme de termes pondérés des valeurs précédentes ; cependant, dans le modèle AR, les termes utilisés sont les termes du modèle lui-même.

Supposons que nous souhaitions modéliser une série temporelle, (xn)(xn), à l'aide d'un modèle AR. Tout d'abord, nous devons choisir une valeur pp, appelée ordre du modèle, qui spécifie le nombre de termes précédents à inclure dans le modèle. Nous pouvons alors appeler le modèle un modèle AR(p)AR(p). S'il existe un fort composant saisonnier de période pp, il est logique de choisir cette valeur comme ordre.

Un modèle AR(p)AR(p) est une formule récursive de la forme

AR(p)n=w1yn−1+w2yn−2+w3yn−3+…+wpyn−p+εnAR(p)n=w1yn−1+w2yn−2+w3yn−3+…+wpyn−p+εn

Ici, les paramètres ou poids, w1,w2,w3,…wpw1,w2,w3,…wp, sont des constantes qui doivent être choisies de sorte que les valeurs de la série temporelle (yn)(yn) s'ajustent le plus fidèlement possible aux données connues (c'est-à-dire yn≈xnyn≈xn pour toutes les observations connues). Il existe également certaines restrictions sur les valeurs possibles de chaque poids, mais nous n'avons pas besoin d'entrer dans ces détails dans ce manuel car nous nous appuierons sur un logiciel pour effectuer la tâche de recherche des paramètres à notre place.

Composante intégrée

Le « I » d'ARIMA signifie intégratif, ce qui est étroitement lié au mot intégrale en calcul différentiel et intégral. Si vous avez déjà fait du calcul infinitésimal, vous vous souvenez peut-être que l'intégrale est l'inverse d'une dérivée. La dérivée, à son tour, est étroitement liée à l'idée de différenciation dans une série temporelle. Bien entendu, il n'est pas nécessaire de maîtriser le calcul pour comprendre le concept d'un modèle intégratif.

Plutôt que de produire un autre composant de la série temporelle, le composante intégrée d'ARIMA représente la procédure consistant à prendre des différences, Δd(xn)Δd(xn) (jusqu'à un ordre spécifique dd), jusqu'à ce que la série temporelle devienne stationnaire. Souvent, seule la différence de premier ordre est nécessaire, et vous pouvez vérifier la stationnarité visuellement. Une méthode plus sophistiquée, appelée test de Dickey-Fuller augmenté (ADF) (Augmented Dickey-Fuller (ADF) test), établit une statistique de test qui mesure la présence de non-stationnarité dans une série temporelle. À l'aide de l'ADF, une valeur p est calculée. Si la valeur p est inférieure à un seuil défini (tel que p<0.01p<0.01), l'hypothèse nulle de non-stationnarité peut alors être rejetée. Ensuite, nous montrerons comment exécuter le test ADF sur une série temporelle et ses différences Δd(xn)Δd(xn) pour déterminer la meilleure valeur pour dd dans ARIMA.

Les modèles AR et MA peuvent ensuite être élaborés sur la série temporelle stationnaire résultante. L'intégration (qui est l'inverse de la différenciation) reconstruit le modèle afin qu'il puisse finalement être utilisé pour prédire les valeurs de la série temporelle d'origine (xn)(xn).

Modèles de moyenne mobile

Un modèle MA d'ordre qq, ou MA(q)MA(q), prend la forme

MA(q)n=L+εn+b1εn−1+b2εn−2+b3εn−3+…+bqεn−qMA(q)n=L+εn+b1εn−1+b2εn−2+b3εn−3+…+bqεn−q

Ici, les termes εnεn sont des résidus (erreurs de prévision), et LL est le niveau de la série temporelle (valeur moyenne de tous les termes). Là encore, une multitude de paramètres doivent être choisis pour que le modèle ait un sens. Nous compterons en général sur un logiciel pour gérer cela.

Modèle ARIMA en Python

Le modèle ARIMA complet, ARIMA(p,d,q)ARIMA(p,d,q), intègre l'ensemble des trois composants : autorégressif d'ordre pp, intégratif avec une différenciation d'ordre d, et moyenne mobile d'ordre qq. Pour la série temporelle MonthlyCoalConsumption.xlsx, il s'avère que la différence de second ordre est stationnaire, comme le montre une série de tests ADF.

Code Python

    # Import libraries
    import pandas as pd ## for dataset management
    # Import adfuller from the statsmodels library
    from statsmodels.tsa.stattools import adfuller
    
    # Read data
    df = pd.read_excel('MonthlyCoalConsumption.xlsx')
    
    print('d = 0')
    result = adfuller(df['Value'])
    print('ADF Statistic:', result[0])
    print('p-value:', result[1])
    
    ## Get the first difference
    print('\n d = 1')
    df1 = df['Value'].diff().dropna()
    result = adfuller(df1)
    print('ADF Statistic:', result[0])
    print('p-value:', result[1])
    
    ## Get the second difference
    print('\n d = 2')
    df2 = df1.diff().dropna()
    result = adfuller(df2)
    print('ADF Statistic:', result[0])
    print('p-value:', result[1])
    

La sortie résultante ressemblera à ceci :

d = 0
ADF Statistic: -1.174289795062662
p-value: 0.6845566772896323

d = 1
ADF Statistic: -1.7838215415905252
p-value: 0.38852291349101137

d = 2
ADF Statistic: -8.578323839498081
p-value: 7.852009937900099e-14

Ici, une valeur p de 7.852×10−147.852×10−14 indique que la différence de second ordre est stationnaire, nous allons donc fixer d=2d=2 dans le modèle ARIMA. Un graphique ACF de la seconde différence peut être utilisé pour déterminer pp.

Code Python

    # Import libraries
    from statsmodels.graphics.tsaplots import plot_acf
    
    # Plot the ACF of the second difference
    plot_acf(df2, lags=20, title='ACF for d = 2 Difference');
     
Graphique ACF intitulé ACF for d = 2 Difference avec 21 décalages montrant les valeurs d'autocorrélation pour les données différenciées. L'axe des ordonnées s'étend de -1 à 1 et l'axe des abscisses de 0 à 20. Les intervalles de confiance sont indiqués par des zones ombrées.

Nous constatons un pic au décalage 12, correspondant à la variation saisonnière annuelle attendue, nous allons donc fixer p=12p=12 dans le modèle ARIMA. Pour cette série temporelle, les valeurs positives de qq n'ont pas du tout modifié la précision du modèle, nous fixons donc q=0q=0 (composant du modèle MA inutile). Le modèle a été utilisé pour prévoir 24 étapes temporelles (2 ans) dans le futur. Nous utilisons la bibliothèque Python statsmodels.tsa.arima.model pour créer le modèle ARIMA.

Code Python

    # Import ARIMA model from statsmodels.tsa library
    from statsmodels.tsa.arima.model import ARIMA
    import matplotlib.pyplot as plt ## for plotting graphs
    from matplotlib.ticker import MaxNLocator ## for graph formatting
    from matplotlib.ticker import FuncFormatter ## for formatting y-axis
    
    # Fit an ARIMA model
    p = 12; d = 2; q = 0 # ARIMA component orders
    model = ARIMA(df['Value'], order=(p, d, q))
    results = model.fit()
    
    # Make forecasts
    fc = results.forecast(steps=24)
    
    # Plot the results
    plt.figure(figsize=(10, 6))
    
    # Plot original time series
    plt.plot(df['Value'], label='Original Time Series')
    
    # Plot fitted and forecasted values
    plt.plot(results.fittedvalues, color='red', label='Fitted Values')
    plt.plot(fc, color='red', linestyle='dashed', label='Forecasted Values') ## Forecasted values
    
    # Set labels and legend
    plt.xlabel('Months')
    plt.title('Monthly Consumption of Coal for Electricity Generation in the United States from 2016 to 2022')
    plt.legend()
    
    # Function to format the Y-axis values
    def y_format(value, tick_number):
      return f'{value:,.0f}'
    
    # Apply the formatter to the Y-axis
    plt.gca().yaxis.set_major_formatter(FuncFormatter(y_format))
    plt.show() 
    

La sortie résultante ressemblera à ceci :

Graphique de série temporelle intitulé Monthly consumption of coal for electricity generation in the United States from 2016 to 2022. L'axe des ordonnées s'étend de 0 à 100 000, l'axe des abscisses de 0 à 100. Les données d'origine, les valeurs ajustées et les valeurs prévues sont représentées. La ligne bleue représente la consommation réelle de charbon, qui fluctue de manière saisonnière. La ligne rouge représente les valeurs ajustées, qui lissent les fluctuations saisonnières, et la ligne rouge en pointillés représente les valeurs prévues. La consommation de charbon montre une tendance générale à la baisse, passant d'environ 100 000 tonnes par mois en 2016 à environ 20 000 tonnes par mois en 2022.

Ici, la courbe bleue est la série temporelle d'origine et la courbe rouge représente le modèle ARIMA, les valeurs prévues étant indiquées par la partie en pointillés de la courbe. Bien qu'il y ait une erreur considérable près du début de la période temporelle, le modèle semble s'ajuster assez bien aux valeurs connues des données, et nous prévoyons donc que les prévisions futures sont raisonnables.