Mediile mobile în pandas

sept. 7, 2021
admin

Introducere

O medie mobilă, numită și medie mobilă sau medie de rulare, este utilizată pentru a analiza datele din seriile de timp prin calcularea mediilor diferitelor subseturi ale setului complet de date. Deoarece implică luarea mediei setului de date de-a lungul timpului, se mai numește și medie mobilă (MM) sau medie mobilă.

Există diverse moduri în care poate fi calculată media mobilă, dar unul dintre acestea este de a lua un subset fix dintr-o serie completă de numere. Prima medie mobilă este calculată prin calcularea mediei primului subset fix de numere, iar apoi subsetul este modificat prin trecerea la următorul subset fix (incluzând valoarea viitoare în subgrup, excluzând în același timp numărul anterior din serie).

Media mobilă este utilizată în principal cu date din serii de timp pentru a surprinde fluctuațiile pe termen scurt, concentrându-se în același timp pe tendințele mai lungi.

Câteva exemple de date din serii temporale pot fi prețurile acțiunilor, rapoartele meteo, calitatea aerului, produsul intern brut, ocuparea forței de muncă etc.

În general, media mobilă netezește datele.

Media mobilă este coloana vertebrală a multor algoritmi, iar un astfel de algoritm este Autoregressive Integrated Moving Average Model (ARIMA), care folosește mediile mobile pentru a face predicții ale datelor din seriile de timp.

Există diferite tipuri de medii mobile:

    Simple Moving Average (SMA): Media mobilă simplă (SMA) utilizează o fereastră glisantă pentru a lua media pe un număr stabilit de perioade de timp. Este o medie cu pondere egală a celor n date anterioare.

    Pentru a înțelege mai bine SMA, să luăm un exemplu, o secvență de n valori:

    atunci media mobilă egal ponderată pentru n puncte de date va fi, în esență, media celor M puncte de date anterioare, unde M este dimensiunea ferestrei glisante:

    În mod similar, pentru calcularea valorilor medii mobile succesive, o nouă valoare va fi adăugată la sumă, iar valoarea perioadei de timp anterioare va fi eliminată, deoarece aveți media perioadelor de timp anterioare, astfel încât nu este necesară o însumare completă de fiecare dată:

  • Cumulative Moving Average (CMA): Spre deosebire de media mobilă simplă, care elimină cea mai veche observație pe măsură ce se adaugă una nouă, media mobilă cumulativă ia în considerare toate observațiile anterioare. CMA nu este o tehnică foarte bună pentru analiza tendințelor și pentru netezirea datelor. Motivul este că face o medie a tuturor datelor anterioare până la punctul de date curent, deci o medie cu pondere egală a secvenței de n valori:
    până la momentul actual este dată de:
    În mod similar, pentru a actualiza media cumulativă pentru fiecare valoare nouă care vine se poate calcula folosind formula de mai jos:

  • Exponential Moving Average (EMA): Spre deosebire de SMA și CMA, media mobilă exponențială acordă o pondere mai mare prețurilor recente și, ca urmare, poate fi un model mai bun sau poate surprinde mai bine mișcarea tendinței într-un mod mai rapid. Reacția EMA este direct proporțională cu modelul datelor.

    Din moment ce EMA acordă o pondere mai mare datelor recente decât datelor mai vechi, ele sunt mai receptive la cele mai recente schimbări de preț în comparație cu SMA, ceea ce face ca rezultatele obținute de EMA să fie mai oportune și, prin urmare, EMA este mai preferată decât alte tehnici.

  • Suficient cu teoria, nu? Să trecem la implementarea practică a mediei mobile.

    Implementarea mediei mobile pe date din serii de timp

    Simple Moving Average (SMA)

    În primul rând, haideți să creăm date fictive din serii de timp și să încercăm să implementăm SMA folosind doar Python.

    Să presupunem că există o cerere pentru un produs și că aceasta este observată timp de 12 luni (1 an) și că trebuie să găsiți medii mobile pentru perioadele de fereastră de 3 și 4 luni.

    Modul de import

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

.

.

lună demanda
0 1 290
1 2
1 2 260
2 3 288
3 4 300
4 5 310

Să calculăm SMA pentru o dimensiune a ferestrei de 3, ceea ce înseamnă că veți lua în considerare de fiecare dată trei valori pentru a calcula media mobilă, iar pentru fiecare valoare nouă, cea mai veche valoare va fi ignorată.

Pentru a implementa acest lucru, veți folosi funcția pandas iloc, deoarece coloana demand este cea de care aveți nevoie, veți fixa poziția acesteia în funcția iloc, în timp ce rândul va fi o variabilă i pe care o veți continua să o iterați până când veți ajunge la sfârșitul cadrului de date.

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

.

lună demand 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

Pentru o verificare a corectitudinii, să folosim, de asemenea, funcția pandas încorporată rolling și să vedem dacă aceasta se potrivește cu media mobilă simplă personalizată bazată pe python.

df = df.iloc.rolling(window=3).mean()
df.head()

.

lună demanda SMA_3 pandas_SMA_3
0 1 290 NaN NaN
1 2 260 NaN NaN NaN
2 3 288 279.3 279.333333
3 4 300 282.7 282.666667
4 5 310 299.3 299.33333333

Cool, deci, după cum puteți vedea, mediile mobile personalizate și pandas se potrivesc exact, ceea ce înseamnă că implementarea SMA a fost corectă.

Să calculăm rapid și media mobilă simplă pentru un 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()

.

.

.

lună demanda SMA_3 pandas_SMA_3 SMA_4
0 1 290 NaN NaN NaN
1 2 260 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()

.

.

.

lună demandă 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 NaN
2 3 288 279.3 279.33333333 NaN NaN
3 4 300 282.7 282.666667 284.5 284.5
4 5 310 299.3 299.33333333 289.5 289.5

Acum, veți reprezenta grafic datele mediilor mobile pe care le-ați calculat.

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>

Media mobilă cumulativă

Cred că acum suntem pregătiți să trecem la un set de date reale.

Pentru media mobilă cumulativă, să folosim un air quality dataset care poate fi descărcat de la acest link.

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

Prelucrarea este un pas esențial ori de câte ori se lucrează cu date. Pentru datele numerice, una dintre cele mai frecvente etape de preprocesare este verificarea valorilor NaN (Null). Dacă există valori NaN, le puteți înlocui fie cu 0, fie cu valori medii, fie cu valori precedente sau succesive, fie chiar le puteți elimina. Deși înlocuirea este în mod normal o alegere mai bună decât renunțarea la ele, deoarece acest set de date are puține valori NULL, renunțarea la ele nu va afecta continuitatea seriei.

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

Din rezultatul de mai sus, puteți observa că există în jur de 114 valori NaN pe toate coloanele, însă vă veți da seama că toate se află la sfârșitul seriei de timp, așa că haideți să le renunțăm rapid.

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

Vă veți aplica media mobilă cumulativă pe Temperature column (T), așa că haideți să separăm rapid această coloană din datele complete.

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

T

0

1

2

3

4

4

Acum, veți utiliza metoda pandas expanding pentru a găsi media cumulată a datelor de mai sus. Dacă vă amintiți din introducere, spre deosebire de media mobilă simplă, media mobilă cumulativă ia în considerare toate valorile precedente atunci când calculează media.

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

Datele din seriile temporale sunt reprezentate grafic în funcție de timp, așa că haideți să combinăm coloana de dată și oră și să o convertim într-un obiect datetime. Pentru a realiza acest lucru, veți utiliza modulul datetime din python (Sursa: 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'))

Să schimbăm indicele din dataframe-ul temperature cu datatime.

df_T.index = df.DateTime

Să reprezentăm acum temperatura reală și media mobilă cumulativă în raport cu timpul.

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>

Media mobilă exponențială

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.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! Deci, după cum puteți observa din graficul de mai sus, că Exponential Moving Average (EMA) face o treabă superbă în captarea modelului de date, în timp ce Cumulative Moving Average (CMA) lipsește cu o marjă considerabilă.

Vă mai departe!

Felicitări pentru terminarea tutorialului.

Acest tutorial a fost un bun punct de plecare în ceea ce privește modul în care puteți calcula mediile mobile ale datelor dvs. și să le dați un sens.

Încercați să scrieți codul python al mediilor mobile cumulative și exponențiale fără a utiliza biblioteca pandas. Acest lucru vă va oferi cunoștințe mult mai aprofundate despre modul în care sunt calculate și în ce fel sunt ele diferite una de cealaltă.

Există încă multe de experimentat. Încercați să calculați autocorelația parțială între datele de intrare și media mobilă și încercați să găsiți o relație între cele două.

Dacă doriți să aflați mai multe despre DataFrames în pandas, urmați cursul interactiv Pandas Foundations de la DataCamp.

.

Lasă un răspuns

Adresa ta de email nu va fi publicată.