You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
ML-For-Beginners/translations/no/7-TimeSeries/2-ARIMA
leestott 98900475bd
🌐 Update translations via Co-op Translator
3 weeks ago
..
solution 🌐 Update translations via Co-op Translator 3 weeks ago
working 🌐 Update translations via Co-op Translator 3 weeks ago
README.md 🌐 Update translations via Co-op Translator 3 weeks ago
assignment.md 🌐 Update translations via Co-op Translator 3 weeks ago

README.md

Tidsserieprognoser med ARIMA

I forrige leksjon lærte du litt om tidsserieprognoser og lastet inn et datasett som viser svingninger i elektrisk belastning over en tidsperiode.

Introduksjon til ARIMA

🎥 Klikk på bildet ovenfor for en video: En kort introduksjon til ARIMA-modeller. Eksempelet er gjort i R, men konseptene er universelle.

Quiz før leksjonen

Introduksjon

I denne leksjonen vil du oppdage en spesifikk måte å bygge modeller på med ARIMA: AutoRegressive Integrated Moving Average. ARIMA-modeller er spesielt godt egnet til å tilpasse data som viser ikke-stasjonaritet.

Generelle konsepter

For å kunne jobbe med ARIMA, er det noen konsepter du må kjenne til:

  • 🎓 Stasjonaritet. Fra et statistisk perspektiv refererer stasjonaritet til data der distribusjonen ikke endres når den forskyves i tid. Ikke-stasjonære data viser derimot svingninger på grunn av trender som må transformeres for å kunne analyseres. Sesongvariasjoner, for eksempel, kan introdusere svingninger i data og kan elimineres ved en prosess kalt 'sesongdifferensiering'.

  • 🎓 Differensiering. Differensiering av data, igjen fra et statistisk perspektiv, refererer til prosessen med å transformere ikke-stasjonære data for å gjøre dem stasjonære ved å fjerne deres ikke-konstante trend. "Differensiering fjerner endringene i nivået til en tidsserie, eliminerer trend og sesongvariasjoner og stabiliserer dermed gjennomsnittet av tidsserien." Paper av Shixiong et al

ARIMA i konteksten av tidsserier

La oss pakke ut delene av ARIMA for bedre å forstå hvordan det hjelper oss med å modellere tidsserier og lage prognoser basert på dem.

  • AR - for AutoRegressiv. Autoregressive modeller, som navnet antyder, ser 'tilbake' i tid for å analysere tidligere verdier i dataene dine og gjøre antakelser om dem. Disse tidligere verdiene kalles 'lags'. Et eksempel kan være data som viser månedlige salg av blyanter. Hver måneds salgssum vil bli betraktet som en 'utviklende variabel' i datasettet. Denne modellen bygges ved at "den utviklende variabelen av interesse regresseres på sine egne forsinkede (dvs. tidligere) verdier." wikipedia

  • I - for Integrert. I motsetning til de lignende 'ARMA'-modellene, refererer 'I' i ARIMA til dens integrerte aspekt. Dataene blir 'integrert' når differensieringstrinn brukes for å eliminere ikke-stasjonaritet.

  • MA - for Glidende Gjennomsnitt. Det glidende gjennomsnittet i denne modellen refererer til utgangsvariabelen som bestemmes ved å observere nåværende og tidligere verdier av lags.

Kort oppsummert: ARIMA brukes til å lage en modell som passer så tett som mulig til den spesielle formen for tidsseriedata.

Øvelse - bygg en ARIMA-modell

Åpne /working-mappen i denne leksjonen og finn filen notebook.ipynb.

  1. Kjør notebooken for å laste inn Python-biblioteket statsmodels; du trenger dette for ARIMA-modeller.

  2. Last inn nødvendige biblioteker.

  3. Deretter laster du inn flere biblioteker som er nyttige for å plotte data:

    import os
    import warnings
    import matplotlib.pyplot as plt
    import numpy as np
    import pandas as pd
    import datetime as dt
    import math
    
    from pandas.plotting import autocorrelation_plot
    from statsmodels.tsa.statespace.sarimax import SARIMAX
    from sklearn.preprocessing import MinMaxScaler
    from common.utils import load_data, mape
    from IPython.display import Image
    
    %matplotlib inline
    pd.options.display.float_format = '{:,.2f}'.format
    np.set_printoptions(precision=2)
    warnings.filterwarnings("ignore") # specify to ignore warning messages
    
  4. Last inn data fra /data/energy.csv-filen til en Pandas dataframe og ta en titt:

    energy = load_data('./data')[['load']]
    energy.head(10)
    
  5. Plot all tilgjengelig energidata fra januar 2012 til desember 2014. Det bør ikke være noen overraskelser, da vi så disse dataene i forrige leksjon:

    energy.plot(y='load', subplots=True, figsize=(15, 8), fontsize=12)
    plt.xlabel('timestamp', fontsize=12)
    plt.ylabel('load', fontsize=12)
    plt.show()
    

    Nå, la oss bygge en modell!

Opprett trenings- og testdatasett

Nå er dataene dine lastet inn, så du kan dele dem opp i trenings- og testsett. Du vil trene modellen din på treningssettet. Som vanlig, etter at modellen er ferdig trent, vil du evaluere nøyaktigheten ved hjelp av testsettet. Du må sørge for at testsettet dekker en senere tidsperiode enn treningssettet for å sikre at modellen ikke får informasjon fra fremtidige tidsperioder.

  1. Tildel en to-måneders periode fra 1. september til 31. oktober 2014 til treningssettet. Testsettet vil inkludere to-måneders perioden fra 1. november til 31. desember 2014:

    train_start_dt = '2014-11-01 00:00:00'
    test_start_dt = '2014-12-30 00:00:00'
    

    Siden disse dataene reflekterer det daglige energiforbruket, er det et sterkt sesongmønster, men forbruket er mest likt forbruket i mer nylige dager.

  2. Visualiser forskjellene:

    energy[(energy.index < test_start_dt) & (energy.index >= train_start_dt)][['load']].rename(columns={'load':'train'}) \
        .join(energy[test_start_dt:][['load']].rename(columns={'load':'test'}), how='outer') \
        .plot(y=['train', 'test'], figsize=(15, 8), fontsize=12)
    plt.xlabel('timestamp', fontsize=12)
    plt.ylabel('load', fontsize=12)
    plt.show()
    

    trenings- og testdata

    Derfor bør det være tilstrekkelig å bruke et relativt lite tidsvindu for å trene dataene.

    Merk: Siden funksjonen vi bruker for å tilpasse ARIMA-modellen bruker in-sample validering under tilpasning, vil vi utelate valideringsdata.

Forbered dataene for trening

Nå må du forberede dataene for trening ved å filtrere og skalere dem. Filtrer datasettet ditt for kun å inkludere de nødvendige tidsperiodene og kolonnene, og skaler dataene for å sikre at de projiseres i intervallet 0,1.

  1. Filtrer det originale datasettet for kun å inkludere de nevnte tidsperiodene per sett og kun inkludere den nødvendige kolonnen 'load' pluss datoen:

    train = energy.copy()[(energy.index >= train_start_dt) & (energy.index < test_start_dt)][['load']]
    test = energy.copy()[energy.index >= test_start_dt][['load']]
    
    print('Training data shape: ', train.shape)
    print('Test data shape: ', test.shape)
    

    Du kan se formen på dataene:

    Training data shape:  (1416, 1)
    Test data shape:  (48, 1)
    
  2. Skaler dataene til å være i området (0, 1).

    scaler = MinMaxScaler()
    train['load'] = scaler.fit_transform(train)
    train.head(10)
    
  3. Visualiser de originale vs. skalerte dataene:

    energy[(energy.index >= train_start_dt) & (energy.index < test_start_dt)][['load']].rename(columns={'load':'original load'}).plot.hist(bins=100, fontsize=12)
    train.rename(columns={'load':'scaled load'}).plot.hist(bins=100, fontsize=12)
    plt.show()
    

    original

    De originale dataene

    skalert

    De skalerte dataene

  4. Nå som du har kalibrert de skalerte dataene, kan du skalere testdataene:

    test['load'] = scaler.transform(test)
    test.head()
    

Implementer ARIMA

Det er på tide å implementere ARIMA! Du vil nå bruke statsmodels-biblioteket som du installerte tidligere.

Nå må du følge flere trinn:

  1. Definer modellen ved å kalle SARIMAX() og sende inn modellparametrene: p, d og q-parametere, samt P, D og Q-parametere.
  2. Forbered modellen for treningsdataene ved å kalle fit()-funksjonen.
  3. Lag prognoser ved å kalle forecast()-funksjonen og spesifisere antall steg (horisonten) som skal prognoseres.

🎓 Hva er alle disse parameterne til? I en ARIMA-modell er det 3 parametere som brukes for å modellere de viktigste aspektene ved en tidsserie: sesongvariasjon, trend og støy. Disse parameterne er:

p: parameteren knyttet til den autoregressive delen av modellen, som inkorporerer tidligere verdier.
d: parameteren knyttet til den integrerte delen av modellen, som påvirker mengden differensiering (🎓 husk differensiering 👆?) som skal brukes på en tidsserie.
q: parameteren knyttet til den glidende gjennomsnittsdelen av modellen.

Merk: Hvis dataene dine har en sesongmessig komponent - som disse dataene har - bruker vi en sesongmessig ARIMA-modell (SARIMA). I så fall må du bruke et annet sett med parametere: P, D og Q, som beskriver de samme assosiasjonene som p, d og q, men tilsvarer de sesongmessige komponentene i modellen.

  1. Start med å sette din foretrukne horisontverdi. La oss prøve 3 timer:

    # Specify the number of steps to forecast ahead
    HORIZON = 3
    print('Forecasting horizon:', HORIZON, 'hours')
    

    Å velge de beste verdiene for en ARIMA-modells parametere kan være utfordrende, da det er noe subjektivt og tidkrevende. Du kan vurdere å bruke en auto_arima()-funksjon fra pyramid-biblioteket.

  2. For nå, prøv noen manuelle valg for å finne en god modell.

    order = (4, 1, 0)
    seasonal_order = (1, 1, 0, 24)
    
    model = SARIMAX(endog=train, order=order, seasonal_order=seasonal_order)
    results = model.fit()
    
    print(results.summary())
    

    En tabell med resultater blir skrevet ut.

Du har bygget din første modell! Nå må vi finne en måte å evaluere den på.

Evaluer modellen din

For å evaluere modellen din kan du utføre den såkalte walk forward-valideringen. I praksis blir tidsseriemodeller re-trent hver gang nye data blir tilgjengelige. Dette lar modellen lage den beste prognosen ved hvert tidssteg.

Start ved begynnelsen av tidsserien med denne teknikken, tren modellen på treningsdatasettet. Deretter lager du en prognose for neste tidssteg. Prognosen evalueres mot den kjente verdien. Treningssettet utvides deretter til å inkludere den kjente verdien, og prosessen gjentas.

Merk: Du bør holde treningssettets vindu fast for mer effektiv trening, slik at hver gang du legger til en ny observasjon i treningssettet, fjerner du observasjonen fra begynnelsen av settet.

Denne prosessen gir en mer robust estimering av hvordan modellen vil prestere i praksis. Imidlertid kommer det med beregningskostnaden ved å lage så mange modeller. Dette er akseptabelt hvis dataene er små eller hvis modellen er enkel, men kan være et problem i stor skala.

Walk-forward validering er gullstandarden for evaluering av tidsseriemodeller og anbefales for dine egne prosjekter.

  1. Først, opprett et testdatapunkt for hvert HORIZON-steg.

    test_shifted = test.copy()
    
    for t in range(1, HORIZON+1):
        test_shifted['load+'+str(t)] = test_shifted['load'].shift(-t, freq='H')
    
    test_shifted = test_shifted.dropna(how='any')
    test_shifted.head(5)
    
    load load+1 load+2
    2014-12-30 00:00:00 0.33 0.29 0.27
    2014-12-30 01:00:00 0.29 0.27 0.27
    2014-12-30 02:00:00 0.27 0.27 0.30
    2014-12-30 03:00:00 0.27 0.30 0.41
    2014-12-30 04:00:00 0.30 0.41 0.57

    Dataene forskyves horisontalt i henhold til horisontpunktet.

  2. Lag prognoser for testdataene dine ved hjelp av denne glidende vindustilnærmingen i en løkke på størrelse med testdatasettets lengde:

    %%time
    training_window = 720 # dedicate 30 days (720 hours) for training
    
    train_ts = train['load']
    test_ts = test_shifted
    
    history = [x for x in train_ts]
    history = history[(-training_window):]
    
    predictions = list()
    
    order = (2, 1, 0)
    seasonal_order = (1, 1, 0, 24)
    
    for t in range(test_ts.shape[0]):
        model = SARIMAX(endog=history, order=order, seasonal_order=seasonal_order)
        model_fit = model.fit()
        yhat = model_fit.forecast(steps = HORIZON)
        predictions.append(yhat)
        obs = list(test_ts.iloc[t])
        # move the training window
        history.append(obs[0])
        history.pop(0)
        print(test_ts.index[t])
        print(t+1, ': predicted =', yhat, 'expected =', obs)
    

    Du kan se treningen foregå:

    2014-12-30 00:00:00
    1 : predicted = [0.32 0.29 0.28] expected = [0.32945389435989236, 0.2900626678603402, 0.2739480752014323]
    
    2014-12-30 01:00:00
    2 : predicted = [0.3  0.29 0.3 ] expected = [0.2900626678603402, 0.2739480752014323, 0.26812891674127126]
    
    2014-12-30 02:00:00
    3 : predicted = [0.27 0.28 0.32] expected = [0.2739480752014323, 0.26812891674127126, 0.3025962399283795]
    
  3. Sammenlign prognosene med den faktiske belastningen:

    eval_df = pd.DataFrame(predictions, columns=['t+'+str(t) for t in range(1, HORIZON+1)])
    eval_df['timestamp'] = test.index[0:len(test.index)-HORIZON+1]
    eval_df = pd.melt(eval_df, id_vars='timestamp', value_name='prediction', var_name='h')
    eval_df['actual'] = np.array(np.transpose(test_ts)).ravel()
    eval_df[['prediction', 'actual']] = scaler.inverse_transform(eval_df[['prediction', 'actual']])
    eval_df.head()
    

    Output

    timestamp h prediction actual
    0 2014-12-30 00:00:00 t+1 3,008.74 3,023.00
    1 2014-12-30 01:00:00 t+1 2,955.53 2,935.00
    2 2014-12-30 02:00:00 t+1 2,900.17 2,899.00
    3 2014-12-30 03:00:00 t+1 2,917.69 2,886.00
    4 2014-12-30 04:00:00 t+1 2,946.99 2,963.00

    Observer prognosen for timebaserte data sammenlignet med den faktiske belastningen. Hvor nøyaktig er dette?

Sjekk modellens nøyaktighet

Sjekk nøyaktigheten til modellen din ved å teste dens gjennomsnittlige absolutte prosentvise feil (MAPE) over alle prognosene.

🧮 Vis meg matematikken

MAPE

MAPE brukes for å vise prediksjonsnøyaktighet som et forhold definert av formelen ovenfor. Forskjellen mellom faktisk og forutsagt deles på det faktiske.

"Den absolutte verdien i denne beregningen summeres for hvert prognosert tidspunkt og deles på antall tilpassede punkter n." wikipedia

  1. Uttrykk ligningen i kode:

    if(HORIZON > 1):
        eval_df['APE'] = (eval_df['prediction'] - eval_df['actual']).abs() / eval_df['actual']
        print(eval_df.groupby('h')['APE'].mean())
    
  2. Beregn MAPE for ett steg:

    print('One step forecast MAPE: ', (mape(eval_df[eval_df['h'] == 't+1']['prediction'], eval_df[eval_df['h'] == 't+1']['actual']))*100, '%')
    

    MAPE for ett steg: 0.5570581332313952 %

  3. Skriv ut MAPE for flertrinnsprognosen:

    print('Multi-step forecast MAPE: ', mape(eval_df['prediction'], eval_df['actual'])*100, '%')
    
    Multi-step forecast MAPE:  1.1460048657704118 %
    

    Et lavt tall er best: husk at en prognose med en MAPE på 10 er feil med 10%.

  4. Men som alltid, det er enklere å se denne typen nøyaktighetsmåling visuelt, så la oss plotte det:

     if(HORIZON == 1):
        ## Plotting single step forecast
        eval_df.plot(x='timestamp', y=['actual', 'prediction'], style=['r', 'b'], figsize=(15, 8))
    
    else:
        ## Plotting multi step forecast
        plot_df = eval_df[(eval_df.h=='t+1')][['timestamp', 'actual']]
        for t in range(1, HORIZON+1):
            plot_df['t+'+str(t)] = eval_df[(eval_df.h=='t+'+str(t))]['prediction'].values
    
        fig = plt.figure(figsize=(15, 8))
        ax = plt.plot(plot_df['timestamp'], plot_df['actual'], color='red', linewidth=4.0)
        ax = fig.add_subplot(111)
        for t in range(1, HORIZON+1):
            x = plot_df['timestamp'][(t-1):]
            y = plot_df['t+'+str(t)][0:len(x)]
            ax.plot(x, y, color='blue', linewidth=4*math.pow(.9,t), alpha=math.pow(0.8,t))
    
        ax.legend(loc='best')
    
    plt.xlabel('timestamp', fontsize=12)
    plt.ylabel('load', fontsize=12)
    plt.show()
    

    en tidsseriemodell

🏆 Et veldig fint plot som viser en modell med god nøyaktighet. Bra jobbet!


🚀Utfordring

Utforsk måter å teste nøyaktigheten til en tidsseriemodell. Vi berører MAPE i denne leksjonen, men finnes det andre metoder du kan bruke? Undersøk dem og kommenter dem. Et nyttig dokument kan finnes her

Quiz etter leksjonen

Gjennomgang & Selvstudium

Denne leksjonen berører kun det grunnleggende innen tidsserieprognoser med ARIMA. Ta deg tid til å utdype kunnskapen din ved å utforske dette repositoriet og dets ulike modelltyper for å lære andre måter å bygge tidsseriemodeller på.

Oppgave

En ny ARIMA-modell


Ansvarsfraskrivelse:
Dette dokumentet er oversatt ved hjelp av AI-oversettelsestjenesten Co-op Translator. Selv om vi tilstreber nøyaktighet, vennligst vær oppmerksom på at automatiske oversettelser kan inneholde feil eller unøyaktigheter. Det originale dokumentet på sitt opprinnelige språk bør anses som den autoritative kilden. For kritisk informasjon anbefales profesjonell menneskelig oversettelse. Vi er ikke ansvarlige for eventuelle misforståelser eller feiltolkninger som oppstår ved bruk av denne oversettelsen.