15 KiB
Tidsserieprognoser med Support Vector Regressor
I forrige leksjon lærte du hvordan du bruker ARIMA-modellen til å lage tidsserieprediksjoner. Nå skal vi se på Support Vector Regressor-modellen, som er en regresjonsmodell brukt til å forutsi kontinuerlige data.
Quiz før leksjonen
Introduksjon
I denne leksjonen vil du oppdage en spesifikk måte å bygge modeller med SVM: Support Vector Machine for regresjon, eller SVR: Support Vector Regressor.
SVR i konteksten av tidsserier 1
Før du forstår viktigheten av SVR i tidsserieprediksjon, er det noen viktige konsepter du bør kjenne til:
- Regresjon: En overvåket læringsteknikk for å forutsi kontinuerlige verdier basert på et gitt sett med input. Ideen er å tilpasse en kurve (eller linje) i funksjonsrommet som har flest mulig datapunkter. Klikk her for mer informasjon.
- Support Vector Machine (SVM): En type overvåket maskinlæringsmodell brukt til klassifisering, regresjon og deteksjon av avvik. Modellen er et hyperplan i funksjonsrommet, som i tilfelle klassifisering fungerer som en grense, og i tilfelle regresjon fungerer som den beste tilpassede linjen. I SVM brukes vanligvis en Kernel-funksjon for å transformere datasettet til et rom med høyere dimensjoner, slik at de blir lettere separerbare. Klikk her for mer informasjon om SVM.
- Support Vector Regressor (SVR): En type SVM som finner den beste tilpassede linjen (som i tilfelle SVM er et hyperplan) som har flest mulig datapunkter.
Hvorfor SVR? 1
I forrige leksjon lærte du om ARIMA, som er en svært vellykket statistisk lineær metode for å forutsi tidsseriedata. Men i mange tilfeller har tidsseriedata ikke-linearitet, som ikke kan modelleres av lineære metoder. I slike tilfeller gjør SVMs evne til å ta hensyn til ikke-linearitet i dataene for regresjonsoppgaver SVR vellykket i tidsserieprognoser.
Øvelse - bygg en SVR-modell
De første stegene for datapreparering er de samme som i forrige leksjon om ARIMA.
Åpne /working-mappen i denne leksjonen og finn notebook.ipynb-filen.2
-
Kjør notebooken og importer de nødvendige bibliotekene: 2
import sys sys.path.append('../../')
import os import warnings import matplotlib.pyplot as plt import numpy as np import pandas as pd import datetime as dt import math from sklearn.svm import SVR from sklearn.preprocessing import MinMaxScaler from common.utils import load_data, mape
-
Last inn dataene fra
/data/energy.csv
-filen til en Pandas-datastruktur og se på dem: 2energy = load_data('../../data')[['load']]
-
Plott alle tilgjengelige energidata fra januar 2012 til desember 2014: 2
energy.plot(y='load', subplots=True, figsize=(15, 8), fontsize=12) plt.xlabel('timestamp', fontsize=12) plt.ylabel('load', fontsize=12) plt.show()
Nå skal vi bygge vår SVR-modell.
Opprett trenings- og testdatasett
Nå er dataene dine lastet inn, så du kan dele dem opp i trenings- og testsett. Deretter vil du omforme dataene for å lage et tidsstegbasert datasett som vil være nødvendig for SVR. Du vil trene modellen på treningssettet. Etter at modellen er ferdig trent, vil du evaluere dens nøyaktighet på treningssettet, testsettet og deretter hele datasettet for å se den generelle ytelsen. Du må sørge for at testsettet dekker en senere tidsperiode enn treningssettet for å sikre at modellen ikke får informasjon fra fremtidige tidsperioder 2 (en situasjon kjent som Overfitting).
-
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: 2
train_start_dt = '2014-11-01 00:00:00' test_start_dt = '2014-12-30 00:00:00'
-
Visualiser forskjellene: 2
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()
Forbered dataene for trening
Nå må du forberede dataene for trening ved å filtrere og skalere dataene dine. Filtrer datasettet for kun å inkludere de tidsperiodene og kolonnene du trenger, og skaler for å sikre at dataene projiseres i intervallet 0,1.
-
Filtrer det originale datasettet for kun å inkludere de nevnte tidsperiodene per sett og kun inkludere den nødvendige kolonnen 'load' pluss datoen: 2
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)
Training data shape: (1416, 1) Test data shape: (48, 1)
-
Skaler treningsdataene til å være i området (0, 1): 2
scaler = MinMaxScaler() train['load'] = scaler.fit_transform(train)
-
Nå skalerer du testdataene: 2
test['load'] = scaler.transform(test)
Opprett data med tidssteg 1
For SVR transformerer du inputdataene til formen [batch, timesteps]
. Så du omformer de eksisterende train_data
og test_data
slik at det er en ny dimensjon som refererer til tidsstegene.
# Converting to numpy arrays
train_data = train.values
test_data = test.values
For dette eksempelet tar vi timesteps = 5
. Så input til modellen er dataene for de første 4 tidsstegene, og output vil være dataene for det 5. tidssteget.
timesteps=5
Konverter treningsdata til 2D tensor ved hjelp av nested list comprehension:
train_data_timesteps=np.array([[j for j in train_data[i:i+timesteps]] for i in range(0,len(train_data)-timesteps+1)])[:,:,0]
train_data_timesteps.shape
(1412, 5)
Konverter testdata til 2D tensor:
test_data_timesteps=np.array([[j for j in test_data[i:i+timesteps]] for i in range(0,len(test_data)-timesteps+1)])[:,:,0]
test_data_timesteps.shape
(44, 5)
Velg input og output fra trenings- og testdata:
x_train, y_train = train_data_timesteps[:,:timesteps-1],train_data_timesteps[:,[timesteps-1]]
x_test, y_test = test_data_timesteps[:,:timesteps-1],test_data_timesteps[:,[timesteps-1]]
print(x_train.shape, y_train.shape)
print(x_test.shape, y_test.shape)
(1412, 4) (1412, 1)
(44, 4) (44, 1)
Implementer SVR 1
Nå er det på tide å implementere SVR. For å lese mer om denne implementeringen, kan du referere til denne dokumentasjonen. For vår implementering følger vi disse stegene:
- Definer modellen ved å kalle
SVR()
og sende inn modellens hyperparametere: kernel, gamma, c og epsilon - Forbered modellen for treningsdataene ved å kalle funksjonen
fit()
- Lag prediksjoner ved å kalle funksjonen
predict()
Nå oppretter vi en SVR-modell. Her bruker vi RBF-kjernen, og setter hyperparameterne gamma, C og epsilon til henholdsvis 0.5, 10 og 0.05.
model = SVR(kernel='rbf',gamma=0.5, C=10, epsilon = 0.05)
Tren modellen på treningsdata 1
model.fit(x_train, y_train[:,0])
SVR(C=10, cache_size=200, coef0=0.0, degree=3, epsilon=0.05, gamma=0.5,
kernel='rbf', max_iter=-1, shrinking=True, tol=0.001, verbose=False)
Lag modellprediksjoner 1
y_train_pred = model.predict(x_train).reshape(-1,1)
y_test_pred = model.predict(x_test).reshape(-1,1)
print(y_train_pred.shape, y_test_pred.shape)
(1412, 1) (44, 1)
Du har bygget din SVR! Nå må vi evaluere den.
Evaluer modellen din 1
For evaluering skal vi først skalere dataene tilbake til vår originale skala. Deretter, for å sjekke ytelsen, skal vi plotte den originale og predikerte tidsserien, og også skrive ut MAPE-resultatet.
Skaler den predikerte og originale outputen:
# Scaling the predictions
y_train_pred = scaler.inverse_transform(y_train_pred)
y_test_pred = scaler.inverse_transform(y_test_pred)
print(len(y_train_pred), len(y_test_pred))
# Scaling the original values
y_train = scaler.inverse_transform(y_train)
y_test = scaler.inverse_transform(y_test)
print(len(y_train), len(y_test))
Sjekk modellens ytelse på trenings- og testdata 1
Vi henter tidsstemplene fra datasettet for å vise på x-aksen i vårt plot. Merk at vi bruker de første timesteps-1
verdiene som input for den første outputen, så tidsstemplene for outputen vil starte etter det.
train_timestamps = energy[(energy.index < test_start_dt) & (energy.index >= train_start_dt)].index[timesteps-1:]
test_timestamps = energy[test_start_dt:].index[timesteps-1:]
print(len(train_timestamps), len(test_timestamps))
1412 44
Plot prediksjonene for treningsdata:
plt.figure(figsize=(25,6))
plt.plot(train_timestamps, y_train, color = 'red', linewidth=2.0, alpha = 0.6)
plt.plot(train_timestamps, y_train_pred, color = 'blue', linewidth=0.8)
plt.legend(['Actual','Predicted'])
plt.xlabel('Timestamp')
plt.title("Training data prediction")
plt.show()
Skriv ut MAPE for treningsdata
print('MAPE for training data: ', mape(y_train_pred, y_train)*100, '%')
MAPE for training data: 1.7195710200875551 %
Plot prediksjonene for testdata
plt.figure(figsize=(10,3))
plt.plot(test_timestamps, y_test, color = 'red', linewidth=2.0, alpha = 0.6)
plt.plot(test_timestamps, y_test_pred, color = 'blue', linewidth=0.8)
plt.legend(['Actual','Predicted'])
plt.xlabel('Timestamp')
plt.show()
Skriv ut MAPE for testdata
print('MAPE for testing data: ', mape(y_test_pred, y_test)*100, '%')
MAPE for testing data: 1.2623790187854018 %
🏆 Du har et veldig godt resultat på testdatasettet!
Sjekk modellens ytelse på hele datasettet 1
# Extracting load values as numpy array
data = energy.copy().values
# Scaling
data = scaler.transform(data)
# Transforming to 2D tensor as per model input requirement
data_timesteps=np.array([[j for j in data[i:i+timesteps]] for i in range(0,len(data)-timesteps+1)])[:,:,0]
print("Tensor shape: ", data_timesteps.shape)
# Selecting inputs and outputs from data
X, Y = data_timesteps[:,:timesteps-1],data_timesteps[:,[timesteps-1]]
print("X shape: ", X.shape,"\nY shape: ", Y.shape)
Tensor shape: (26300, 5)
X shape: (26300, 4)
Y shape: (26300, 1)
# Make model predictions
Y_pred = model.predict(X).reshape(-1,1)
# Inverse scale and reshape
Y_pred = scaler.inverse_transform(Y_pred)
Y = scaler.inverse_transform(Y)
plt.figure(figsize=(30,8))
plt.plot(Y, color = 'red', linewidth=2.0, alpha = 0.6)
plt.plot(Y_pred, color = 'blue', linewidth=0.8)
plt.legend(['Actual','Predicted'])
plt.xlabel('Timestamp')
plt.show()
print('MAPE: ', mape(Y_pred, Y)*100, '%')
MAPE: 2.0572089029888656 %
🏆 Veldig fine plott som viser en modell med god nøyaktighet. Bra jobbet!
🚀Utfordring
- Prøv å justere hyperparameterne (gamma, C, epsilon) mens du oppretter modellen og evaluer på dataene for å se hvilke sett med hyperparametere som gir de beste resultatene på testdataene. For å lære mer om disse hyperparameterne, kan du referere til dokumentet her.
- Prøv å bruke forskjellige kjernefunksjoner for modellen og analyser deres ytelse på datasettet. Et nyttig dokument kan finnes her.
- Prøv å bruke forskjellige verdier for
timesteps
for modellen for å se tilbake og lage prediksjoner.
Quiz etter leksjonen
Gjennomgang & Selvstudie
Denne leksjonen var en introduksjon til bruken av SVR for tidsserieprognoser. For å lese mer om SVR, kan du referere til denne bloggen. Denne dokumentasjonen på scikit-learn gir en mer omfattende forklaring om SVM generelt, SVR og også andre implementeringsdetaljer som de forskjellige kjernefunksjonene som kan brukes, og deres parametere.
Oppgave
Krediteringer
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.
-
Teksten, koden og outputen i denne seksjonen ble bidratt av @AnirbanMukherjeeXD ↩︎
-
Teksten, koden og outputen i denne seksjonen ble hentet fra ARIMA ↩︎