Nachiketa Hebbar

Follow

18 sep, 2020 – 8 min read

Tidsserieresultat är en av de mest efterfrågade teknikerna inom datavetenskap, vare sig det gäller aktiehandel, prognoser för företagsförsäljning eller väderprognoser. Det är helt klart en mycket praktisk färdighet att ha och jag kommer att utrusta dig med just det i slutet av den här artikeln.

I den här handledningen kommer vi att bygga en ARIMA-modell (oroa dig inte om du inte vet exakt hur det fungerar ännu) för att förutsäga de framtida temperaturvärdena i en viss stad med hjälp av Python. GitHub-länken för koden och datamängden finns i slutet av den här bloggen. Jag har också bifogat min YouTube-video i slutet, om du är intresserad av en videoförklaring. Så utan att slösa någon tid låt oss börja.

Det första steget i alla tidsserier är att läsa dina data och se hur de ser ut. Följande kodutdrag visar hur man gör det.

Koden är ganska okomplicerad. Vi läser data med hjälp av pd.read_csv och skriver parse_date=True, ser till att pandas förstår att det handlar om datumvärden och inte strängvärden.

Nästan släpper vi alla saknade värden och skriver ut formen på data. df.head() skriver ut de första 5 raderna i datasetet. Här är utdata som du bör se för detta:

Plottar ut dina data

Nästa steg är att plotta ut dina data. Detta ger dig en uppfattning om huruvida data är stationära eller inte. För dem som inte vet vad stationäritet innebär, låt mig ge dig en sammanfattning av det. Även om jag har gjort flera videoklipp om detta ämne, går det i stort sett ut på följande:

Alla tidsseriedata som måste modelleras måste vara stationära. Stationär innebär att dess statistiska egenskaper är mer eller mindre konstanta med tiden. Det låter vettigt, eller hur? Hur ska man annars kunna göra förutsägelser om de statistiska egenskaperna varierar med tiden? Det här är följande egenskaper som en stationär modell kommer att ha:

  1. Konstant medelvärde
  2. Konstant varians(Det kan förekomma variationer, men variationerna bör inte vara oregelbundna)
  3. Ingen säsongsmässighet(Inga upprepande mönster i datamängden)

Det första steget är alltså att kontrollera om det finns stationäritet. Om din datamängd inte är stationär måste du konvertera den till en stationär serie. Innan du börjar oroa dig för allt detta ska du slappna av! Vi har ett fast enkelt test för att kontrollera stationäritet som heter ADF(Augmented Dickey Fuller Test). Men innan vi visar det, låt oss först plotta data.

Då jag bara är intresserad av att förutsäga medeltemperaturen, är det den enda kolumnen jag kommer att plotta.

df.plot(figsize=(12,5))

Kontroll av stationaritet

Redan från början kan vi se att den verkar ha något av ett konstant medelvärde runt 45. Och fluktuationerna verkar också vara mer eller mindre likadana. Men för att vara säkra på om data är stationära eller inte kör vi ett fast statistiskt test med följande kod:

Du får utdata enligt följande:

Du behöver inte oroa dig för all den komplexa statistiken. För att tolka testresultaten behöver du bara titta på p-värdet. Och du använder följande enkla metod:

If p< 0,05 ; Data är stationära

if p>0,05; Data är inte stationära

Det är ingen fast regel, men en stationär data bör ha ett litet p-värde. Ett större p-värde kan tyda på förekomst av vissa trender(varierande medelvärde) eller säsongsvariationer också.

Finally, Decide your ARIMA Model

Nu även om jag har gjort flera YouTube-videor om detta ämne, om du inte helt förstår vad en ARIMA-modell är, låt mig presentera en enkel översikt:

ARIMA består av 3 termer(Auto-Regression + Integrated+Moving-Average)

  1. Auto-Regression:

Detta innebär i princip att du använder de tidigare värdena i tidsserien för att förutsäga framtiden. Hur många tidigare värden du använder bestämmer ordningen på AR-modellen. Så här ser en AR(1)-modell ut:

Y(t)= Some_Constant*Y(t-1)+ Another_Constant +Error(t)

Simpelt nog, eller hur?

2. Integrerat:

Har du kommit ihåg vårt föredrag om stationaritet och att det är extremt viktigt? Tja, om din datamängd inte är stationär måste du oftast utföra någon form av differensoperation för att göra den stationär. Om du gör en differens med föregående värde är dess ordning 1 och så vidare. Här är ett exempel på det:

Forgïc min dåliga teckning. Men som du kan se var serien Y(t) inte stationär, eftersom den hade en ökande trend som resulterade i ett varierande medelvärde. Vi subtraherar den helt enkelt från tidigare värden och voila! Den blir stationär. Beroende på dina data kan du behöva upprepa differentieringen för att få en differentiering av andra ordningen , tredje ordningen och så vidare.

3. Glidande medelvärde:

Detta innebär i princip att du använder tidigare fel för att göra den framtida förutsägelsen. Det är också logiskt, eller hur? Genom att se hur fel du hade i din förutsägelse tar du hänsyn till det för att göra en bättre förutsägelse. Och precis som i en AR-modell bestämmer antalet tidigare fel (även kallat antal eftersläpningar) du använder modellens ordning.

Här ser ekvationen för MA(1)-ordningen ut:
Y(t)= Mean + Some_Constant*Error(t-1) +Error(t)

Så vår huvuduppgift är att bestämma ordningen för AR-, I- och MA-delarna, som doneras av(p,d,q) respektive.

Och innan du börjar oroa dig, låt mig berätta att allt kommer att göras automatiskt. pmdarima-biblioteket kommer till vår undsättning! Det gör jobbet med att räkna ut ordningen för ARIMA helt av sig självt. Så här ser kodutdraget ut:

from pmdarima import auto_arima
stepwise_fit = auto_arima(df, trace=True,
suppress_warnings=True)

(Se till att installera pmdarima-biblioteket först med pip install pmdarima)

Koden är ganska självförklarande. Vi levererar helt enkelt våra data till funktionen auto_arima. Funktionen använder i princip något som kallas AIC-poäng för att bedöma hur bra en viss ordningsmodell är. Den försöker helt enkelt minimera AIC-poängen, och så här ser resultatet ut:

Modellprestanda för olika kombinationer av ordrar

Vi ser att den bästa ARIMA-modellen tycks vara av ordningen (1,0,5) med minsta AIC-poäng=8294.785. Med denna kunskap kan vi äntligen fortsätta att träna och anpassa modellen för att börja göra förutsägelser!

Split Your Dataset

Innan vi faktiskt tränar modellen måste vi dela upp datamängden i en tränings- och en testsektion. Vi gör detta eftersom vi först tränar modellen på data och håller testsektionen dold för modellen. När modellen är klar ber vi den göra förutsägelser på testdata och ser hur bra den presterar.

Följande kodutdrag illustrerar hur man gör det:

print(df.shape)
train=df.iloc
test=df.iloc
print(train.shape,test.shape)

Så som du säkert kan se reserverar vi de sista 30 dagarna av data som testsektionen. Du kan se formerna för de faktiska data och test- och träningssektionerna i resultatet.

Form för tränings- och träningssektionerna

Äntligen kommer vi till de saftiga sakerna!

Overraskande nog är skapandet av ARIMA-modellen faktiskt ett av de enklaste stegen när du väl har gjort alla förutsättningarna. Det är så enkelt som visas i kodutdraget nedan:

from statsmodels.tsa.arima_model import ARIMA
model=ARIMA(train,order=(1,0,5))
model=model.fit()
model.summary()

Som du kan se anropar vi helt enkelt ARIMA-funktionen, förser den med vår datamängd och nämner ordningen för den ARIMA-modell vi vill ha. Du kommer också att kunna se en sammanfattning av modellen i din utdata.

Modellsammanfattning

Du kan se en hel del information om din modell här borta. Du kommer också att kunna se koefficienterna för varje AR- och MA-term. Dessa är inget annat än värdet av de variabler som du såg i den tidigare AR/MA-modellens ekvation och som var märkta som ”Some_Constant”. Generellt sett innebär en högre storlek på denna variabel att den har en större inverkan på resultatet.

Kontrollera hur bra din modell är

Här kommer våra testdata in i bilden. Vi gör först en förutsägelse för temperaturen på testdata. Sedan plottar vi ut för att se hur våra förutsägelser jämfördes med de faktiska data.

För att faktiskt göra förutsägelser måste vi använda funktionen model.predict och tala om för den vilket start- och slutindex vi vill göra förutsägelserna.

Då vi vill börja göra förutsägelser där träningsdatan slutar , är det vad jag har skrivit i startvariabeln. Vi vill sluta göra förutsägelser när datamängden slutar, vilket förklarar slutvariabeln. Om du vill göra framtida förutsägelser också kan du bara ändra detta i start- och slutvariabeln till de index du vill ha. Din utdataplott bör se ut så här:

Testvärden vs. förutsägelser Plott

Som du kan se så matchar förutsägelserna ganska bra den faktiska trenden, även om det finns en viss acceptabel fördröjning.

Kontrollera din noggrannhetsmätning

För att faktiskt fastställa hur bra eller dålig din modell är hittar vi det genomsnittliga kvadratiska felet för den. Följande kodutdrag visar detta:

Först kontrollerar vi datamängdens medelvärde som visar sig vara 45. Och det kvadratiska medelvärdesfelet för just den här modellen bör ligga på cirka 2,3. Du bör också tänka på att din rotmedelkvadratfel bör vara mycket mindre än testuppsättningens medelvärde. I det här fallet kan vi se att det genomsnittliga felet kommer att bli ungefär 2,3/45 *100=5,1 % av det faktiska värdet.

Så med det är din ARIMA-modell redo att användas! I framtida bloggar kommer jag att prata om olika modeller och hur du kan öka modellens noggrannhet ytterligare.

Om du är intresserad av videoförklaringen av samma sak, gå över till min YouTube-kanal för mer sådant innehåll! Du hittar GitHub-länken för koden och datamängden här: https://github.com/nachi-hebbar/ARIMA-Temperature_Forecasting

Följ gärna med mig på LinkedIn också!