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.
393 lines
15 KiB
393 lines
15 KiB
<!--
|
|
CO_OP_TRANSLATOR_METADATA:
|
|
{
|
|
"original_hash": "482bccabe1df958496ea71a3667995cd",
|
|
"translation_date": "2025-09-05T21:24:09+00:00",
|
|
"source_file": "7-TimeSeries/3-SVR/README.md",
|
|
"language_code": "no"
|
|
}
|
|
-->
|
|
# 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](https://ff-quizzes.netlify.app/en/ml/)
|
|
|
|
## Introduksjon
|
|
|
|
I denne leksjonen vil du oppdage en spesifikk måte å bygge modeller med [**SVM**: **S**upport **V**ector **M**achine](https://en.wikipedia.org/wiki/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](https://en.wikipedia.org/wiki/Regression_analysis) 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](https://en.wikipedia.org/wiki/Support-vector_machine) 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](https://github.com/microsoft/ML-For-Beginners/tree/main/7-TimeSeries/2-ARIMA).
|
|
|
|
Åpne [_/working_](https://github.com/microsoft/ML-For-Beginners/tree/main/7-TimeSeries/3-SVR/working)-mappen i denne leksjonen og finn [_notebook.ipynb_](https://github.com/microsoft/ML-For-Beginners/blob/main/7-TimeSeries/3-SVR/working/notebook.ipynb)-filen.[^2]
|
|
|
|
1. Kjør notebooken og importer de nødvendige bibliotekene: [^2]
|
|
|
|
```python
|
|
import sys
|
|
sys.path.append('../../')
|
|
```
|
|
|
|
```python
|
|
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
|
|
```
|
|
|
|
2. Last inn dataene fra `/data/energy.csv`-filen til en Pandas-datastruktur og se på dem: [^2]
|
|
|
|
```python
|
|
energy = load_data('../../data')[['load']]
|
|
```
|
|
|
|
3. Plott alle tilgjengelige energidata fra januar 2012 til desember 2014: [^2]
|
|
|
|
```python
|
|
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*).
|
|
|
|
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: [^2]
|
|
|
|
```python
|
|
train_start_dt = '2014-11-01 00:00:00'
|
|
test_start_dt = '2014-12-30 00:00:00'
|
|
```
|
|
|
|
2. Visualiser forskjellene: [^2]
|
|
|
|
```python
|
|
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.
|
|
|
|
1. Filtrer det originale datasettet for kun å inkludere de nevnte tidsperiodene per sett og kun inkludere den nødvendige kolonnen 'load' pluss datoen: [^2]
|
|
|
|
```python
|
|
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)
|
|
```
|
|
|
|
```output
|
|
Training data shape: (1416, 1)
|
|
Test data shape: (48, 1)
|
|
```
|
|
|
|
2. Skaler treningsdataene til å være i området (0, 1): [^2]
|
|
|
|
```python
|
|
scaler = MinMaxScaler()
|
|
train['load'] = scaler.fit_transform(train)
|
|
```
|
|
|
|
4. Nå skalerer du testdataene: [^2]
|
|
|
|
```python
|
|
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.
|
|
|
|
```python
|
|
# 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.
|
|
|
|
```python
|
|
timesteps=5
|
|
```
|
|
|
|
Konverter treningsdata til 2D tensor ved hjelp av nested list comprehension:
|
|
|
|
```python
|
|
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
|
|
```
|
|
|
|
```output
|
|
(1412, 5)
|
|
```
|
|
|
|
Konverter testdata til 2D tensor:
|
|
|
|
```python
|
|
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
|
|
```
|
|
|
|
```output
|
|
(44, 5)
|
|
```
|
|
|
|
Velg input og output fra trenings- og testdata:
|
|
|
|
```python
|
|
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)
|
|
```
|
|
|
|
```output
|
|
(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](https://scikit-learn.org/stable/modules/generated/sklearn.svm.SVR.html). For vår implementering følger vi disse stegene:
|
|
|
|
1. Definer modellen ved å kalle `SVR()` og sende inn modellens hyperparametere: kernel, gamma, c og epsilon
|
|
2. Forbered modellen for treningsdataene ved å kalle funksjonen `fit()`
|
|
3. Lag prediksjoner ved å kalle funksjonen `predict()`
|
|
|
|
Nå oppretter vi en SVR-modell. Her bruker vi [RBF-kjernen](https://scikit-learn.org/stable/modules/svm.html#parameters-of-the-rbf-kernel), og setter hyperparameterne gamma, C og epsilon til henholdsvis 0.5, 10 og 0.05.
|
|
|
|
```python
|
|
model = SVR(kernel='rbf',gamma=0.5, C=10, epsilon = 0.05)
|
|
```
|
|
|
|
#### Tren modellen på treningsdata [^1]
|
|
|
|
```python
|
|
model.fit(x_train, y_train[:,0])
|
|
```
|
|
|
|
```output
|
|
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]
|
|
|
|
```python
|
|
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)
|
|
```
|
|
|
|
```output
|
|
(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:
|
|
|
|
```python
|
|
# 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))
|
|
```
|
|
|
|
```python
|
|
# 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.
|
|
|
|
```python
|
|
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))
|
|
```
|
|
|
|
```output
|
|
1412 44
|
|
```
|
|
|
|
Plot prediksjonene for treningsdata:
|
|
|
|
```python
|
|
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
|
|
|
|
```python
|
|
print('MAPE for training data: ', mape(y_train_pred, y_train)*100, '%')
|
|
```
|
|
|
|
```output
|
|
MAPE for training data: 1.7195710200875551 %
|
|
```
|
|
|
|
Plot prediksjonene for testdata
|
|
|
|
```python
|
|
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
|
|
|
|
```python
|
|
print('MAPE for testing data: ', mape(y_test_pred, y_test)*100, '%')
|
|
```
|
|
|
|
```output
|
|
MAPE for testing data: 1.2623790187854018 %
|
|
```
|
|
|
|
🏆 Du har et veldig godt resultat på testdatasettet!
|
|
|
|
### Sjekk modellens ytelse på hele datasettet [^1]
|
|
|
|
```python
|
|
# 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)
|
|
```
|
|
|
|
```output
|
|
Tensor shape: (26300, 5)
|
|
X shape: (26300, 4)
|
|
Y shape: (26300, 1)
|
|
```
|
|
|
|
```python
|
|
# 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)
|
|
```
|
|
|
|
```python
|
|
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()
|
|
```
|
|
|
|

|
|
|
|
```python
|
|
print('MAPE: ', mape(Y_pred, Y)*100, '%')
|
|
```
|
|
|
|
```output
|
|
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](https://scikit-learn.org/stable/modules/svm.html#parameters-of-the-rbf-kernel).
|
|
- Prøv å bruke forskjellige kjernefunksjoner for modellen og analyser deres ytelse på datasettet. Et nyttig dokument kan finnes [her](https://scikit-learn.org/stable/modules/svm.html#kernel-functions).
|
|
- Prøv å bruke forskjellige verdier for `timesteps` for modellen for å se tilbake og lage prediksjoner.
|
|
|
|
## [Quiz etter leksjonen](https://ff-quizzes.netlify.app/en/ml/)
|
|
|
|
## Gjennomgang & Selvstudie
|
|
|
|
Denne leksjonen var en introduksjon til bruken av SVR for tidsserieprognoser. For å lese mer om SVR, kan du referere til [denne bloggen](https://www.analyticsvidhya.com/blog/2020/03/support-vector-regression-tutorial-for-machine-learning/). Denne [dokumentasjonen på scikit-learn](https://scikit-learn.org/stable/modules/svm.html) gir en mer omfattende forklaring om SVM generelt, [SVR](https://scikit-learn.org/stable/modules/svm.html#regression) og også andre implementeringsdetaljer som de forskjellige [kjernefunksjonene](https://scikit-learn.org/stable/modules/svm.html#kernel-functions) som kan brukes, og deres parametere.
|
|
|
|
## Oppgave
|
|
|
|
[En ny SVR-modell](assignment.md)
|
|
|
|
## Krediteringer
|
|
|
|
[^1]: Teksten, koden og outputen i denne seksjonen ble bidratt av [@AnirbanMukherjeeXD](https://github.com/AnirbanMukherjeeXD)
|
|
[^2]: Teksten, koden og outputen i denne seksjonen ble hentet fra [ARIMA](https://github.com/microsoft/ML-For-Beginners/tree/main/7-TimeSeries/2-ARIMA)
|
|
|
|
---
|
|
|
|
**Ansvarsfraskrivelse**:
|
|
Dette dokumentet er oversatt ved hjelp av AI-oversettelsestjenesten [Co-op Translator](https://github.com/Azure/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. |