Średnie ruchome w pandach

wrz 7, 2021
admin

Wprowadzenie

Średnia ruchoma, zwana również średnią kroczącą lub bieżącą, jest używana do analizy danych szeregu czasowego przez obliczanie średnich z różnych podzbiorów kompletnego zbioru danych. Ponieważ obejmuje to biorąc średnią zbioru danych w czasie, jest również nazywany średnią ruchomą (MM) lub rolling mean.

Są różne sposoby, w jaki średnia krocząca może być obliczona, ale jeden taki sposób jest wziąć stały podzbiór z pełnej serii liczb. Pierwsza średnia krocząca jest obliczana przez uśrednienie pierwszego ustalonego podzbioru liczb, a następnie podzbiór jest zmieniany przez przejście do następnego ustalonego podzbioru (włączając przyszłą wartość do podgrupy przy jednoczesnym wykluczeniu poprzedniej liczby z serii).

Średnia krocząca jest najczęściej używana z danymi szeregów czasowych w celu uchwycenia krótkoterminowych wahań przy jednoczesnym skupieniu się na dłuższych trendach.

Kilka przykładów danych szeregów czasowych mogą być ceny akcji, raporty pogodowe, jakość powietrza, produkt krajowy brutto, zatrudnienie, itp.

Ogólnie, średnia ruchoma wygładza dane.

Średnia ruchoma jest podstawą wielu algorytmów, a jednym z takich algorytmów jest Autoregressive Integrated Moving Average Model (ARIMA), który wykorzystuje średnie ruchome do prognozowania danych szeregów czasowych.

Są różne rodzaje średnich ruchomych:

  • Simple Moving Average (SMA): Simple Moving Average (SMA) wykorzystuje przesuwane okno, aby wziąć średnią z ustalonej liczby okresów czasu. Jest to równo ważona średnia z poprzednich n danych.

    Aby zrozumieć SMA dalej, weźmy przykład, sekwencję n wartości:

    to równo ważona średnia krocząca dla n punktów danych będzie zasadniczo średnią poprzednich M punktów danych, gdzie M jest rozmiarem okna przesuwnego:

    Podobnie, przy obliczaniu kolejnych wartości średniej kroczącej, nowa wartość zostanie dodana do sumy, a wartość z poprzedniego okresu czasu zostanie pominięta, ponieważ mamy średnią z poprzednich okresów czasu, więc pełne sumowanie za każdym razem nie jest wymagane:

  • Skumulowana średnia krocząca (CMA): W przeciwieństwie do prostej średniej kroczącej, która porzuca najstarszą obserwację w miarę dodawania nowej, kumulatywna średnia krocząca uwzględnia wszystkie wcześniejsze obserwacje. CMA nie jest bardzo dobrą techniką do analizy trendów i wygładzania danych. Powodem jest to, że uśrednia ona wszystkie poprzednie dane aż do bieżącego punktu danych, a więc równo ważoną średnią z ciągu n wartości:
    do chwili obecnej dana jest przez:
    Analogicznie, aby zaktualizować średnią skumulowaną dla każdej nowej wartości, która nadejdzie można obliczyć za pomocą poniższego wzoru:

  • Wykładnicza średnia krocząca (EMA): W przeciwieństwie do SMA i CMA, wykładnicza średnia krocząca daje większą wagę do ostatnich cen, w wyniku czego może być lepszym modelem lub lepiej uchwycić ruch trendu w szybszy sposób. Reakcja EMA jest wprost proporcjonalna do wzorca danych.

    Ponieważ EMA nadają większą wagę ostatnim danym niż starszym, są one bardziej wrażliwe na najnowsze zmiany cen w porównaniu do SMA, co sprawia, że wyniki z EMA są bardziej na czasie i dlatego EMA jest bardziej preferowana niż inne techniki.

  • Dość teorii, prawda? Przejdźmy do praktycznej implementacji średniej kroczącej.

    Implementing Moving Average on Time Series Data

    Simple Moving Average (SMA)

    Po pierwsze, stwórzmy fikcyjne dane szeregu czasowego i spróbujmy zaimplementować SMA używając tylko Pythona.

    Załóżmy, że istnieje popyt na produkt i jest on obserwowany przez 12 miesięcy (1 rok), i trzeba znaleźć średnie kroczące dla 3 i 4 miesięcznych okresów okna.

    Moduł importu

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

.

.

miesiąc demand
0 1 290
1 2 260
2 3 288
3 4 300
4 5 310

Obliczmy SMA dla okna o rozmiarze 3, co oznacza, że za każdym razem do obliczenia średniej kroczącej będą brane pod uwagę trzy wartości, a dla każdej nowej wartości najstarsza wartość będzie ignorowana.

Aby to zaimplementować, użyjesz funkcji pandas iloc, ponieważ kolumna demand jest tym, czego potrzebujesz, ustalisz jej pozycję w funkcji iloc, podczas gdy wiersz będzie zmienną i, którą będziesz iterował, dopóki nie osiągniesz końca ramki danych.

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

.

month 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

Dla sprawdzenia poprawności, użyjmy również pandas wbudowanej rolling funkcji i zobaczmy, czy pasuje ona do naszej niestandardowej prostej średniej kroczącej opartej na Pythonie.

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

.

month demand 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, więc jak widzisz, niestandardowe i pandasowe średnie kroczące pasują dokładnie, co oznacza, że twoja implementacja SMA była poprawna.

Obliczmy też szybko prostą średnią kroczącą dla window_size równej 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()

.

.

miesiąc popyt 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()

.

.

.

miesiąc popyt SMA_3 pandas_SMA_3 SMA_4 pandas_SMA_4
0 1 290 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

Teraz wykreślisz dane obliczonych średnich ruchomych.

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>

Skumulowana średnia krocząca

Sądzę, że teraz jesteśmy gotowi, aby przejść do prawdziwego zbioru danych.

Dla skumulowanej średniej kroczącej użyjmy modelu air quality dataset, który można pobrać z tego linku.

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

Preprocessing jest niezbędnym krokiem podczas pracy z danymi. W przypadku danych liczbowych jednym z najczęstszych kroków przetwarzania wstępnego jest sprawdzenie, czy nie występują wartości NaN (Null). Jeśli są jakieś NaN wartości, możesz zastąpić je albo 0 lub średnią lub poprzedzającymi lub następującymi wartościami lub nawet je porzucić. Chociaż zastąpienie jest zwykle lepszym wyborem niż upuszczenie ich, ponieważ ten zbiór danych ma niewiele wartości NULL, upuszczenie ich nie wpłynie na ciągłość serii.

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

Z powyższego wyjścia można zauważyć, że istnieje około 114 wartości NaN we wszystkich kolumnach, jednak dowiesz się, że wszystkie są na końcu serii czasowej, więc szybko je upuśćmy.

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

Będziesz stosować skumulowaną średnią kroczącą na Temperature column (T), więc szybko oddzielmy tę kolumnę od pełnych danych.

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

T

0

1

2

3

4

Teraz, użyjemy metody pandas expanding do znalezienia średniej skumulowanej z powyższych danych. Jeśli pamiętasz ze wstępu, w przeciwieństwie do prostej średniej ruchomej, skumulowana średnia ruchoma uwzględnia wszystkie poprzednie wartości podczas obliczania średniej.

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

Dane szeregu czasowego są wykreślane względem czasu, dlatego połączmy kolumnę daty i czasu i przekształćmy je w obiekt datetime. Aby to osiągnąć, użyjemy modułu datetime z pythona (Źródło: 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'))

Zmieńmy indeks ramki danych temperature z datetime.

df_T.index = df.DateTime

Wykreślmy teraz temperaturę rzeczywistą i skumulowaną średnią ruchomą wrt. czasu.

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>

Exponential Moving Average

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! Jak więc można zauważyć na powyższym wykresie, Exponential Moving Average (EMA) wykonuje doskonałą pracę w przechwytywaniu wzorca danych, podczas gdy Cumulative Moving Average (CMA) brakuje mu znacznego marginesu.

Dalej!

Gratuluję ukończenia samouczka.

Ten samouczek był dobrym punktem wyjścia do tego, jak możesz obliczyć średnie ruchome dla swoich danych i nadać im sens.

Spróbuj napisać kod pythona kumulatywnej i wykładniczej średniej ruchomej bez użycia biblioteki pandas. To da ci znacznie bardziej dogłębną wiedzę o tym, jak są one obliczane i w jaki sposób różnią się od siebie.

Wciąż jest wiele do eksperymentowania. Spróbuj obliczyć częściową autokorelację między danymi wejściowymi a średnią ruchomą i spróbuj znaleźć jakąś zależność między nimi.

Jeśli chciałbyś dowiedzieć się więcej o DataFrames w pandas, weź udział w interaktywnym kursie DataCamp’s pandas Foundations.

.

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany.