Mozgóátlagok a pandasban

szept 7, 2021
admin

Bevezetés

A mozgóátlagot, más néven gördülő vagy futó átlagot az idősoros adatok elemzésére használják a teljes adathalmaz különböző részhalmazainak átlagainak kiszámításával. Mivel az adathalmaz időbeli átlagát veszi, mozgó átlagnak (MM) vagy gördülő átlagnak is nevezik.

A gördülő átlag számításának különböző módjai vannak, de az egyik ilyen mód az, hogy a teljes számsorozatból egy rögzített részhalmazt veszünk. Az első mozgóátlagot a számok első rögzített részhalmazának átlagolásával számítják ki, majd a részhalmazt a következő rögzített részhalmazra való előrehaladással módosítják (a részhalmazba a jövőbeli értéket is bevonják, miközben az előző számot kizárják a sorozatból).

A mozgóátlagot leginkább idősoros adatoknál használják a rövid távú ingadozások megragadására, miközben a hosszabb trendekre összpontosítanak.

Az idősoros adatokra néhány példa lehet a részvényárfolyamok, az időjárás-jelentések, a levegő minősége, a bruttó hazai termék, a foglalkoztatás stb.

A mozgóátlag általában kisimítja az adatokat.

A mozgóátlag számos algoritmus gerincét képezi, és az egyik ilyen algoritmus az Autoregresszív Integrált Mozgóátlag Modell (ARIMA), amely mozgóátlagokat használ az idősoros adatok előrejelzéséhez.

A mozgóátlagoknak különböző típusai vannak:

  • Simple Moving Average (SMA): Az egyszerű mozgóátlag (SMA) egy csúszó ablakot használ az átlagoláshoz egy meghatározott számú időszakon keresztül. Ez az előző n adat egyenletesen súlyozott átlaga.

    Az SMA további megértéséhez vegyünk egy példát, egy n értékből álló sorozatot:

    akkor az n adatpontra vonatkozó egyenletesen súlyozott gördülő átlag lényegében az előző M adatpont átlaga lesz, ahol M a csúszóablak mérete:

    Hasonlóképpen, az egymást követő gördülő átlagértékek kiszámításához egy új értéket adunk hozzá az összeghez, és az előző időszaki értéket elhagyjuk, mivel az előző időszakok átlagát kapjuk, így nem szükséges minden alkalommal teljes összegzés:

  • Kumulatív mozgóátlag (CMA): Az egyszerű mozgóátlaggal ellentétben, amely a legrégebbi megfigyelést elhagyja, amikor az új megfigyelés hozzáadódik, a kumulatív mozgóátlag az összes korábbi megfigyelést figyelembe veszi. A CMA nem túl jó technika a trendek elemzésére és az adatok kisimítására. Ennek oka, hogy az összes korábbi adatot átlagolja az aktuális adatpontig, tehát az n értékek sorozatának egyformán súlyozott átlaga:
    az aktuális időpontig a következő:
    Hasonlóképpen, a kumulatív átlag frissítése minden újonnan érkező értékre az alábbi képlettel számítható ki:

  • Exponenciális mozgóátlag (EMA): Az SMA-tól és a CMA-tól eltérően az exponenciális mozgóátlag nagyobb súlyt ad a legutóbbi áraknak, és ennek eredményeképpen jobb modell lehet, vagy jobban megragadhatja a trend mozgását gyorsabb módon. Az EMA reakciója közvetlenül arányos az adatok mintázatával.

    Mivel az EMA nagyobb súlyt ad a friss adatoknak, mint a régebbi adatoknak, az SMA-khoz képest jobban reagálnak a legújabb árváltozásokra, ami miatt az EMA-kból származó eredmények időszerűbbek, és ezért az EMA-t jobban preferálják más technikákkal szemben.

  • Elég az elméletből, igaz? Ugorjunk a mozgóátlag gyakorlati megvalósítására.

    Mozgóátlagok megvalósítása idősoros adatokon

    Simple Moving Average (SMA)

    Először is hozzunk létre dummy idősoros adatokat, és próbáljuk meg az SMA megvalósítását csak Python segítségével.

    Tegyük fel, hogy van egy termék iránti kereslet, és azt 12 hónapon keresztül (1 év) figyeljük, és mozgóátlagokat kell találnunk 3 és 4 hónapos ablakperiódusokra.

    Import modul

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

.

hónap kereslet
0 1 290
1 2 260
2 3 288
3 4 300
4 5 310

Kalkuláljuk ki az SMA-t 3 ablakméretre, ami azt jelenti, hogy minden alkalommal három értéket veszünk figyelembe a mozgóátlag kiszámításához, és minden új értéknél a legrégebbi értéket figyelmen kívül hagyjuk.

A megvalósításhoz a pandas iloc függvényt fogja használni, mivel a demand oszlop az, amire szüksége van, ennek a pozícióját a iloc függvényben fogja rögzíteni, míg a sor egy i változó lesz, amelyet addig fog iterálni, amíg el nem éri az adatkeret végét.

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

.

hónap igény 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

A józansági ellenőrzéshez használjuk a pandas beépített rolling függvényt is, és nézzük meg, hogy egyezik-e az egyéni python alapú egyszerű mozgóátlagunkkal.

df = df.iloc.rolling(window=3).mean()
df.head()
hónap kereslet 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

Klassz, tehát mint láthatod, az egyéni és a pandas mozgóátlagok pontosan egyeznek, ami azt jelenti, hogy az SMA implementációd helyes volt.

Legyen gyorsan kiszámolva az egyszerű mozgóátlag is egy window_size 4-es értékhez.

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()

.

hónap kereslet SMA_3 pandasz_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()

.

hónap kereslet SMA_3 pandas_SMA_3 SMA_4 pandas_SMA_4
0 1 290 NaN NaN 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

Most a kiszámított mozgóátlagok adatait ábrázolja.

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>

Kumulatív mozgóátlag

Úgy gondolom, most már készen állunk arra, hogy áttérjünk egy valós adatsorra.

A kumulatív mozgóátlaghoz használjunk egy air quality dataset, amely letölthető erről a linkről.

df = pd.read_csv("AirQualityUCI/AirQualityUCI.csv", sep = ";", decimal = ",")df = df.iloc
df.head()
Date Time 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

Az előfeldolgozás elengedhetetlen lépés, amikor adatokkal dolgozunk. Numerikus adatok esetében az egyik leggyakoribb előfeldolgozási lépés a NaN (Null) értékek ellenőrzése. Ha vannak NaN értékek, akkor azokat vagy 0-val vagy átlaggal, vagy az előző vagy az azt követő értékekkel helyettesíthetjük, vagy akár el is hagyhatjuk őket. Bár a helyettesítés általában jobb választás, mint az elhagyásuk, mivel ez az adatkészlet kevés NULL értéket tartalmaz, az elhagyásuk nem befolyásolja a sorozat folytonosságát.

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

A fenti kimenetből megfigyelhetjük, hogy minden oszlopban körülbelül 114 NaN érték van, azonban ki fogjuk találni, hogy ezek mind az idősor végén vannak, ezért gyorsan hagyjuk el őket.

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

A Temperature column (T) értékre kumulatív mozgóátlagot fogunk alkalmazni, ezért gyorsan válasszuk ki ezt az oszlopot a teljes adatból.

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

T

0

1

2

3

4

Most, a pandas expanding módszerrel meg fogod találni a fenti adatok kumulatív átlagát. Ha emlékszik a bevezetőből, az egyszerű mozgóátlaggal ellentétben a kumulatív mozgóátlag az összes előző értéket figyelembe veszi az átlag kiszámításakor.

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

Az idősoros adatokat az idő függvényében ábrázoljuk, ezért egyesítsük a dátum és az idő oszlopot és alakítsuk át datetime objektummá. Ehhez használjuk a python datetime modulját (Forrás: 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'))

Változtassuk meg a temperature adatkeret indexét datetime-ra.

df_T.index = df.DateTime

Most ábrázoljuk az aktuális hőmérsékletet és a kumulatív mozgóátlagot az idő függvényében.

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>

Exponenciális mozgóátlag

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! A fenti grafikonon tehát megfigyelhetjük, hogy a Exponential Moving Average (EMA) kiválóan érzékeli az adatok mintázatát, míg a Cumulative Moving Average (CMA) jelentős mértékben elmarad tőle.

Gyerünk tovább!

Gratulálunk a bemutató befejezéséhez.

Ez a bemutató jó kiindulópont volt ahhoz, hogyan lehet kiszámítani az adatok mozgóátlagait és értelmet adni nekik.

Kipróbálja megírni a kumulatív és exponenciális mozgóátlag python kódját a pandas könyvtár használata nélkül. Így sokkal mélyebb ismereteket szerezhetsz arról, hogyan számítják ki őket, és miben különböznek egymástól.

Még mindig van mit kísérletezni. Próbálja meg kiszámítani a részleges autokorrelációt a bemeneti adatok és a mozgóátlag között, és próbáljon meg valamilyen kapcsolatot találni a kettő között.

Ha többet szeretne megtudni a pandas DataFrames-ről, vegyen részt a DataCamp pandas Foundations interaktív kurzusán.

Még többet szeretne megtudni a pandas DataFrames-ről a pandasban?

Vélemény, hozzászólás?

Az e-mail-címet nem tesszük közzé.