|
2 weeks ago | |
---|---|---|
.. | ||
solution | 3 weeks ago | |
working | 3 weeks ago | |
README.md | 2 weeks ago | |
assignment.md | 2 weeks ago |
README.md
Idősoros előrejelzés Support Vector Regressor segítségével
Az előző leckében megtanultad, hogyan használhatod az ARIMA modellt idősoros előrejelzések készítésére. Most a Support Vector Regressor modellel fogsz megismerkedni, amely egy regressziós modell folyamatos adatok előrejelzésére.
Előzetes kvíz
Bevezetés
Ebben a leckében felfedezheted, hogyan építhetsz modelleket SVM: Support Vector Machine segítségével regresszióhoz, vagyis SVR: Support Vector Regressor.
SVR az idősoros előrejelzés kontextusában 1
Mielőtt megértenéd az SVR fontosságát az idősoros előrejelzésben, íme néhány fontos fogalom, amelyet ismerned kell:
- Regresszió: Felügyelt tanulási technika, amely folyamatos értékeket jósol meg egy adott bemeneti halmazból. Az ötlet az, hogy egy görbét (vagy egyenes vonalat) illesszünk a jellemzők terébe, amely a legtöbb adatpontot tartalmazza. Kattints ide további információért.
- Support Vector Machine (SVM): Egy felügyelt gépi tanulási modell, amelyet osztályozásra, regresszióra és kiugró értékek detektálására használnak. A modell egy hipersík a jellemzők terében, amely osztályozás esetén határként, regresszió esetén pedig legjobban illeszkedő vonalként működik. Az SVM-ben általában Kernel függvényt használnak az adathalmaz magasabb dimenziójú térbe történő átalakítására, hogy könnyebben elválaszthatóak legyenek. Kattints ide további információért az SVM-ekről.
- Support Vector Regressor (SVR): Az SVM egy típusa, amely megtalálja a legjobban illeszkedő vonalat (ami az SVM esetében egy hipersík), amely a legtöbb adatpontot tartalmazza.
Miért SVR? 1
Az előző leckében megismerkedtél az ARIMA modellel, amely egy nagyon sikeres statisztikai lineáris módszer idősoros adatok előrejelzésére. Azonban sok esetben az idősoros adatok nemlinearitást mutatnak, amelyet a lineáris modellek nem tudnak leképezni. Ilyen esetekben az SVM képessége, hogy figyelembe vegye az adatok nemlinearitását a regressziós feladatok során, sikeressé teszi az SVR-t az idősoros előrejelzésben.
Gyakorlat - SVR modell építése
Az első néhány adat-előkészítési lépés megegyezik az előző ARIMA leckében tanultakkal.
Nyisd meg a /working mappát ebben a leckében, és keresd meg a notebook.ipynb fájlt. 2
-
Futtasd a notebookot, és importáld a szükséges könyvtárakat: 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
-
Töltsd be az adatokat a
/data/energy.csv
fájlból egy Pandas dataframe-be, és nézd meg: 2energy = load_data('../../data')[['load']]
-
Ábrázold az összes elérhető energiaadatot 2012 januárjától 2014 decemberéig: 2
energy.plot(y='load', subplots=True, figsize=(15, 8), fontsize=12) plt.xlabel('timestamp', fontsize=12) plt.ylabel('load', fontsize=12) plt.show()
Most építsük meg az SVR modellünket.
Képzési és tesztelési adathalmazok létrehozása
Most, hogy az adatok betöltve vannak, szétválaszthatod őket képzési és tesztelési halmazokra. Ezután átalakítod az adatokat időlépés-alapú adathalmazzá, amelyre szükség lesz az SVR-hez. A modell képzését a képzési halmazon végzed. Miután a modell befejezte a képzést, kiértékeled a pontosságát a képzési halmazon, a tesztelési halmazon, majd az egész adathalmazon, hogy láthasd az általános teljesítményt. Biztosítanod kell, hogy a tesztelési halmaz egy későbbi időszakot fedjen le, mint a képzési halmaz, hogy elkerüld, hogy a modell információt szerezzen a jövőbeli időszakokból 2 (ezt a helyzetet túltanulásnak nevezzük).
-
Jelölj ki egy két hónapos időszakot 2014. szeptember 1-től október 31-ig a képzési halmaz számára. A tesztelési halmaz a 2014. november 1-től december 31-ig tartó két hónapos időszakot fogja tartalmazni: 2
train_start_dt = '2014-11-01 00:00:00' test_start_dt = '2014-12-30 00:00:00'
-
Vizualizáld a különbségeket: 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()
Adatok előkészítése a képzéshez
Most elő kell készítened az adatokat a képzéshez, szűréssel és skálázással. Szűrd az adathalmazt, hogy csak a szükséges időszakokat és oszlopokat tartalmazza, majd skálázd az adatokat, hogy az értékek a 0 és 1 közötti intervallumba essenek.
-
Szűrd az eredeti adathalmazt, hogy csak az említett időszakokat és a szükséges 'load' oszlopot, valamint a dátumot tartalmazza: 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)
-
Skálázd a képzési adatokat a (0, 1) tartományba: 2
scaler = MinMaxScaler() train['load'] = scaler.fit_transform(train)
-
Most skálázd a tesztelési adatokat: 2
test['load'] = scaler.transform(test)
Adatok létrehozása időlépésekkel 1
Az SVR-hez az input adatokat [batch, timesteps]
formára kell átalakítani. Ezért átalakítod a meglévő train_data
és test_data
adatokat úgy, hogy legyen egy új dimenzió, amely az időlépéseket jelöli.
# Converting to numpy arrays
train_data = train.values
test_data = test.values
Ebben a példában timesteps = 5
értéket veszünk. Tehát a modell bemenete az első 4 időlépés adatai lesznek, a kimenet pedig az 5. időlépés adatai.
timesteps=5
A képzési adatok 2D tensorra való átalakítása beágyazott listakomprehenzióval:
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)
A tesztelési adatok 2D tensorra való átalakítása:
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)
A képzési és tesztelési adatok bemeneteinek és kimeneteinek kiválasztása:
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)
SVR megvalósítása 1
Most itt az ideje, hogy megvalósítsd az SVR-t. További információért erről a megvalósításról, olvasd el ezt a dokumentációt. A mi megvalósításunkban a következő lépéseket követjük:
- Definiáld a modellt az
SVR()
meghívásával, és add meg a modell hiperparamétereit: kernel, gamma, c és epsilon - Készítsd elő a modellt a képzési adatokhoz az
fit()
függvény meghívásával - Végezz előrejelzéseket az
predict()
függvény meghívásával
Most létrehozzuk az SVR modellt. Itt az RBF kernel használatát választjuk, és a hiperparamétereket gamma, C és epsilon értékekre állítjuk: 0.5, 10 és 0.05.
model = SVR(kernel='rbf',gamma=0.5, C=10, epsilon = 0.05)
Modell illesztése a képzési adatokra 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)
Modell előrejelzések készítése 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)
Elkészítetted az SVR-t! Most ki kell értékelni.
Modell kiértékelése 1
A kiértékeléshez először visszaskálázzuk az adatokat az eredeti skálára. Ezután az eredmény ellenőrzéséhez ábrázoljuk az eredeti és előrejelzett idősoros adatokat, valamint kiírjuk a MAPE eredményt.
Az előrejelzett és eredeti kimenet skálázása:
# 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))
Modell teljesítményének ellenőrzése a képzési és tesztelési adatokon 1
Kinyerjük az időbélyegeket az adathalmazból, hogy az x-tengelyen megjelenítsük őket. Ne feledd, hogy az első timesteps-1
értékeket használjuk bemenetként az első kimenethez, így a kimenet időbélyegei ezután kezdődnek.
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
A képzési adatok előrejelzéseinek ábrázolása:
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()
MAPE kiírása a képzési adatokra:
print('MAPE for training data: ', mape(y_train_pred, y_train)*100, '%')
MAPE for training data: 1.7195710200875551 %
A tesztelési adatok előrejelzéseinek ábrázolása:
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()
MAPE kiírása a tesztelési adatokra:
print('MAPE for testing data: ', mape(y_test_pred, y_test)*100, '%')
MAPE for testing data: 1.2623790187854018 %
🏆 Nagyon jó eredményt értél el a tesztelési adathalmazon!
Modell teljesítményének ellenőrzése a teljes adathalmazon 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 %
🏆 Nagyon szép ábrák, amelyek egy jó pontosságú modellt mutatnak. Szép munka!
🚀Kihívás
- Próbáld meg módosítani a hiperparamétereket (gamma, C, epsilon) a modell létrehozásakor, és értékeld ki az adatokat, hogy lásd, melyik hiperparaméter-készlet adja a legjobb eredményeket a tesztelési adatokon. További információért ezekről a hiperparaméterekről olvasd el ezt a dokumentumot.
- Próbálj ki különböző kernel függvényeket a modellhez, és elemezd a teljesítményüket az adathalmazon. Egy hasznos dokumentumot itt találhatsz: kernel függvények.
- Próbálj ki különböző értékeket a
timesteps
paraméterhez, hogy a modell visszatekintve készítsen előrejelzést.
Utólagos kvíz
Áttekintés és önálló tanulás
Ez a lecke az SVR alkalmazását mutatta be idősoros előrejelzéshez. További információért az SVR-ről olvasd el ezt a blogot. Ez a scikit-learn dokumentáció átfogóbb magyarázatot nyújt az SVM-ekről általában, az SVR-ekről, valamint más megvalósítási részletekről, például a különböző kernel függvényekről, amelyek használhatók, és azok paramétereiről.
Feladat
Köszönet
Felelősség kizárása:
Ez a dokumentum az AI fordítási szolgáltatás, a Co-op Translator segítségével lett lefordítva. Bár törekszünk a pontosságra, kérjük, vegye figyelembe, hogy az automatikus fordítások hibákat vagy pontatlanságokat tartalmazhatnak. Az eredeti dokumentum az eredeti nyelvén tekintendő hiteles forrásnak. Kritikus információk esetén javasolt professzionális emberi fordítást igénybe venni. Nem vállalunk felelősséget az ebből a fordításból eredő félreértésekért vagy téves értelmezésekért.
-
A szöveget, kódot és kimenetet ebben a szakaszban @AnirbanMukherjeeXD készítette ↩︎
-
A szöveget, kódot és kimenetet ebben a szakaszban az ARIMA leckéből vettük ↩︎