Moyennes mobiles dans pandas

Sep 7, 2021
admin

Introduction

Une moyenne mobile, également appelée moyenne glissante ou courante, est utilisée pour analyser les données de séries temporelles en calculant les moyennes de différents sous-ensembles de l’ensemble de données complet. Comme elle implique de prendre la moyenne de l’ensemble de données au fil du temps, elle est également appelée moyenne mobile (MM) ou moyenne roulante.

Il existe différentes façons de calculer la moyenne roulante, mais l’une d’entre elles consiste à prendre un sous-ensemble fixe d’une série complète de chiffres. La première moyenne mobile est calculée en faisant la moyenne du premier sous-ensemble fixe de nombres, puis le sous-ensemble est modifié en avançant vers le sous-ensemble fixe suivant (en incluant la valeur future dans le sous-groupe tout en excluant le nombre précédent de la série).

La moyenne mobile est surtout utilisée avec des données de séries chronologiques pour capturer les fluctuations à court terme tout en se concentrant sur les tendances plus longues.

Quelques exemples de données de séries temporelles peuvent être les prix des actions, les rapports météorologiques, la qualité de l’air, le produit intérieur brut, l’emploi, etc.

En général, la moyenne mobile lisse les données.

La moyenne mobile est une colonne vertébrale de nombreux algorithmes, et l’un de ces algorithmes est le modèle de moyenne mobile intégrée autorégressive (ARIMA), qui utilise les moyennes mobiles pour faire des prédictions sur les données de séries chronologiques.

Il existe différents types de moyennes mobiles :

  • Moyenne mobile simple (SMA) : La moyenne mobile simple (SMA) utilise une fenêtre glissante pour prendre la moyenne sur un nombre déterminé de périodes. Il s’agit d’une moyenne équipondérée des n données précédentes.

    Pour mieux comprendre la SMA, prenons un exemple, une séquence de n valeurs :

    alors la moyenne mobile équipondérée pour n points de données sera essentiellement la moyenne des M points de données précédents, où M est la taille de la fenêtre coulissante :

    De même, pour le calcul des valeurs successives de la moyenne mobile, une nouvelle valeur sera ajoutée à la somme, et la valeur de la période précédente sera éliminée, puisque vous avez la moyenne des périodes précédentes, donc la somme complète à chaque fois n’est pas nécessaire :

  • Moyenne mobile cumulative (CMA) : Contrairement à la moyenne mobile simple qui laisse tomber l’observation la plus ancienne au fur et à mesure que la nouvelle s’ajoute, la moyenne mobile cumulative prend en compte toutes les observations antérieures. La CMA n’est pas une très bonne technique pour analyser les tendances et lisser les données. La raison en est qu’elle fait la moyenne de toutes les données précédentes jusqu’au point de données actuel, donc une moyenne également pondérée de la séquence de n valeurs :
    jusqu’au moment actuel est donnée par :
    De même, pour mettre à jour la moyenne cumulative pour chaque nouvelle valeur qui vient peut être calculée en utilisant la formule ci-dessous :

  • Moyenne mobile exponentielle (EMA) : Contrairement à la SMA et la CMA, la moyenne mobile exponentielle donne plus de poids aux prix récents et en conséquence de quoi, elle peut être un meilleur modèle ou mieux capturer le mouvement de la tendance d’une manière plus rapide. La réaction de l’EMA est directement proportionnelle au modèle des données.

    Puisque les EMA donnent un poids plus élevé sur les données récentes que sur les données plus anciennes, elles sont plus réactives aux derniers changements de prix par rapport aux SMA, ce qui rend les résultats des EMA plus opportuns et donc les EMA sont plus préférées aux autres techniques.

  • Assez de théorie, n’est-ce pas ? Sautons à la mise en œuvre pratique de la moyenne mobile.

    Mise en œuvre de la moyenne mobile sur des données de séries temporelles

    Moyenne mobile simple (SMA)

    D’abord, créons des données de séries temporelles fictives et essayons de mettre en œuvre la SMA en utilisant seulement Python.

    Supposons qu’il y a une demande pour un produit et qu’elle est observée pendant 12 mois (1 an), et vous devez trouver des moyennes mobiles pour des périodes de fenêtre de 3 et 4 mois.

    Module d’importation

import pandas as pdimport numpy as np
product = {'month' : ,'demand':}
df = pd.DataFrame(product)
df.head()

.

.

mois demande
0 1 290
1 2 260
2 3 288
3 4 300
4 5 310

Calculons la SMA pour une taille de fenêtre de 3, ce qui signifie que vous allez considérer trois valeurs à chaque fois pour calculer la moyenne mobile, et pour chaque nouvelle valeur, la valeur la plus ancienne sera ignorée.

Pour mettre en œuvre cela, vous utiliserez la fonction pandas iloc, puisque la colonne demand est ce dont vous avez besoin, vous fixerez la position de celle-ci dans la fonction iloc tandis que la ligne sera une variable i que vous continuerez à itérer jusqu’à ce que vous atteigniez la fin de la dataframe.

for i in range(0,df.shape-2): df.loc,'SMA_3'] = np.round(((df.iloc+ df.iloc +df.iloc)/3),1)
df.head()

.

mois demande SMA_3
0 1 290 NaN
1 2 260 NaN
2 3 288 279.3
3 4 300 282.7
4 5 310 299.3

Pour un contrôle de bon sens, utilisons également la fonction pandas intégrée rolling et voyons si elle correspond à notre moyenne mobile simple personnalisée basée sur python.

df = df.iloc.rolling(window=3).mean()
df.head()
mois demande SMA_3 pandas_SMA_3
0 1 290 NaN NaN
1 2 260 NaN NaN
2 3 288 279.3 279.333333
3 4 300 282.7 282.666667
4 5 310 299.3 299.333333

Cool, donc comme vous pouvez le voir, les moyennes mobiles personnalisées et pandas correspondent exactement, ce qui signifie que votre implémentation de la SMA était correcte.

Calculons aussi rapidement la moyenne mobile simple pour une window_size de 4.

for i in range(0,df.shape-3): df.loc,'SMA_4'] = np.round(((df.iloc+ df.iloc +df.iloc+df.iloc)/4),1)
df.head()

.

mois demande SMA_3 pandas_SMA_3 SMA_4
0 1 290 NaN NaN NaN
1 2 260 NaN NaN NaN
2 3 288 279.3 279.333333 NaN
3 4 300 282.7 282.666667 284.5
4 5 310 299.3 299.333333 289.5
df = df.iloc.rolling(window=4).mean()
df.head()

.

mois demande SMA_3 pandas_SMA_3 SMA_4 pandas_SMA_4
0 1 290 NaN NaN NaN
1 2 260 NaN NaN NaN NaN
2 3 288 279.3 279.333333 NaN NaN
3 4 300 282.7 282.666667 284.5 284.5
4 5 310 299.3 299,333333 289,5 289,5

Maintenant, vous allez tracer les données des moyennes mobiles que vous avez calculées.

import matplotlib.pyplot as plt%matplotlib inline
plt.figure(figsize=)plt.grid(True)plt.plot(df,label='data')plt.plot(df,label='SMA 3 Months')plt.plot(df,label='SMA 4 Months')plt.legend(loc=2)
<matplotlib.legend.Legend at 0x11fe15080>

Moyenne mobile cumulative

Je pense que nous sommes maintenant prêts à passer à un ensemble de données réelles.

Pour la moyenne mobile cumulative, utilisons un air quality dataset qui peut être téléchargé à partir de ce lien.

df = pd.read_csv("AirQualityUCI/AirQualityUCI.csv", sep = ";", decimal = ",")df = df.iloc
df.head()
Date Heure CO(GT) PT08.S1(CO) NMHC(GT) C6H6(GT) PT08.S2(NMHC) NOx(GT) PT08.S3(NOx) NO2(GT) PT08.S4(NO2) PT08.S5(O3) T RH
0 10/03/2004 18.00.00 2.6 1360.0 150.0 11.9 1046.0 166.0 1056.0 113.0 1692.0 1268.0 13.6 48.9
1 10/03/2004 19.00.00 2.0 1292.0 112.0 9.4 955.0 103.0 1174.0 92.0 1559.0 972.0 13.3 47.7
2 10/03/2004 20.00.00 2.2 1402.0 88.0 9.0 939.0 131.0 1140.0 114.0 1555.0 1074.0 11.9 54.0
3 10/03/2004 21.00.00 2.2 1376.0 80.0 9.2 948.0 172.0 1092.0 122.0 1584.0 1203.0 11.0 60.0
4 10/03/2004 22.00.00 1.6 1272.0 51.0 6.5 836.0 131.0 1205.0 116.0 1490.0 1110.0 11.2 59.6

Le prétraitement est une étape essentielle dès que l’on travaille avec des données. Pour les données numériques, l’une des étapes de prétraitement les plus courantes consiste à vérifier la présence de valeurs NaN (Null). S’il y a des valeurs NaN, vous pouvez les remplacer par 0 ou par une moyenne ou par des valeurs précédentes ou successives ou même les laisser tomber. Bien que le remplacement soit normalement un meilleur choix que l’abandon, puisque cet ensemble de données a peu de valeurs NULL, l’abandon n’affectera pas la continuité de la série.

df.isna().sum()
Date 114Time 114CO(GT) 114PT08.S1(CO) 114NMHC(GT) 114C6H6(GT) 114PT08.S2(NMHC) 114NOx(GT) 114PT08.S3(NOx) 114NO2(GT) 114PT08.S4(NO2) 114PT08.S5(O3) 114T 114RH 114dtype: int64

D’après la sortie ci-dessus, vous pouvez observer qu’il y a environ 114 valeurs NaN à travers toutes les colonnes, cependant vous comprendrez qu’elles sont toutes à la fin de la série temporelle, donc abandonnons-les rapidement.

df.dropna(inplace=True)
df.isna().sum()
Date 0Time 0CO(GT) 0PT08.S1(CO) 0NMHC(GT) 0C6H6(GT) 0PT08.S2(NMHC) 0NOx(GT) 0PT08.S3(NOx) 0NO2(GT) 0PT08.S4(NO2) 0PT08.S5(O3) 0T 0RH 0dtype: int64

Vous allez appliquer la moyenne mobile cumulative sur le Temperature column (T), donc séparons rapidement cette colonne des données complètes.

df_T = pd.DataFrame(df.iloc)
df_T.head()

T

0

1

2

3

4

Maintenant, vous allez utiliser la méthode pandas expanding pour trouver la moyenne cumulée des données ci-dessus. Si vous vous souvenez de l’introduction, contrairement à la moyenne mobile simple, la moyenne mobile cumulative considère toutes les valeurs précédentes lors du calcul de la moyenne.

df_T = df_T.expanding(min_periods=4).mean()
df_T.head(10)
T CMA_4
0 13.6 NaN
1 13.3 NaN
2 11.9 NaN
3 11.0 12.450000
4 11.2 12.200000
5 11.2 12.033333
6 11.3 11.928571
7 10.7 11.775000
8 10.7 11.655556
9 10.3 11.520000

Les données de séries temporelles sont tracées par rapport à l’heure, alors combinons la colonne de date et d’heure et convertissons-la en un objet datetime. Pour ce faire, vous utiliserez le module datetime de python (Source : Time Series Tutorial).

import datetimedf = (df.Date) + ' ' + (df.Time)df.DateTime = df.DateTime.apply(lambda x: datetime.datetime.strptime(x, '%d/%m/%Y %H.%M.%S'))

Changeons l’indice du dataframe temperature avec datetime.

df_T.index = df.DateTime

Traçons maintenant la température réelle et la moyenne mobile cumulative par rapport au temps.

plt.figure(figsize=)plt.grid(True)plt.plot(df_T,label='temperature')plt.plot(df_T,label='CMA_4')plt.legend(loc=2)
<matplotlib.legend.Legend at 0x1210a2d30>

Moyenne mobile exponentielle

df_T = df_T.iloc.ewm(span=40,adjust=False).mean()
df_T.head()

.

T CMA_4 EMA
DateTime
2004-03-10 18 :00:00 13.6 NaN 13,600000
2004-03-10 19:00:00 13.3 NaN 13.585366
2004-03-10 20:00:00 11.9 NaN 13.503153
2004-03-10 21:00:00 11.0 12.45 13.381048
2004-03-10 22:00:00 11.2 12,20 13,274655
plt.figure(figsize=)plt.grid(True)plt.plot(df_T,label='temperature')plt.plot(df_T,label='CMA_4')plt.plot(df_T,label='EMA')plt.legend(loc=2)
<matplotlib.legend.Legend at 0x14b2a41d0>

Wow ! Donc, comme vous pouvez l’observer dans le graphique ci-dessus, que le Exponential Moving Average (EMA) fait un superbe travail pour capturer le modèle des données tandis que le Cumulative Moving Average (CMA) manque par une marge considérable.

Aller plus loin!

Félicitations pour avoir terminé le tutoriel.

Ce tutoriel était un bon point de départ sur la façon dont vous pouvez calculer les moyennes mobiles de vos données et leur donner un sens.

Essayez d’écrire le code python de la moyenne mobile cumulative et exponentielle sans utiliser la bibliothèque pandas. Cela vous donnera une connaissance beaucoup plus approfondie de la façon dont elles sont calculées et en quoi elles sont différentes les unes des autres.

Il y a encore beaucoup à expérimenter. Essayez de calculer l’auto-corrélation partielle entre les données d’entrée et la moyenne mobile, et essayez de trouver une certaine relation entre les deux.

Si vous souhaitez en savoir plus sur les DataFrames dans pandas, suivez le cours interactif pandas Foundations de DataCamp.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée.