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/bg/7-TimeSeries/3-SVR/README.md

21 KiB

Прогнозиране на времеви серии със Support Vector Regressor

В предишния урок научихте как да използвате модела ARIMA за прогнозиране на времеви серии. Сега ще разгледате модела Support Vector Regressor, който е регресионен модел, използван за прогнозиране на непрекъснати данни.

Тест преди лекцията

Въведение

В този урок ще откриете специфичен начин за изграждане на модели с SVM: Support Vector Machine за регресия, или SVR: Support Vector Regressor.

SVR в контекста на времеви серии 1

Преди да разберете значението на SVR за прогнозиране на времеви серии, ето някои важни концепции, които трябва да знаете:

  • Регресия: Техника за обучение с надзор, която предсказва непрекъснати стойности от даден набор от входни данни. Идеята е да се намери крива (или линия) в пространството на характеристиките, която има максимален брой точки от данни. Кликнете тук за повече информация.
  • Support Vector Machine (SVM): Вид модел за машинно обучение с надзор, използван за класификация, регресия и откриване на аномалии. Моделът представлява хиперплоскост в пространството на характеристиките, която в случай на класификация действа като граница, а в случай на регресия - като линия на най-добро съответствие. В SVM обикновено се използва Kernel функция за трансформиране на набора от данни в пространство с по-голям брой измерения, така че те да бъдат лесно разделими. Кликнете тук за повече информация за SVM.
  • Support Vector Regressor (SVR): Вид SVM, който намира линия на най-добро съответствие (която в случая на SVM е хиперплоскост), която има максимален брой точки от данни.

Защо SVR? 1

В последния урок научихте за ARIMA, който е много успешен статистически линеен метод за прогнозиране на времеви серии. Въпреки това, в много случаи времевите серии имат нелинейност, която не може да бъде моделирана от линейни модели. В такива случаи способността на SVM да отчита нелинейността в данните за задачи по регресия прави SVR успешен в прогнозиране на времеви серии.

Упражнение - изграждане на SVR модел

Първите няколко стъпки за подготовка на данните са същите като тези от предишния урок за ARIMA.

Отворете папката /working в този урок и намерете файла notebook.ipynb. 2

  1. Стартирайте notebook-а и импортирайте необходимите библиотеки: 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
    
  2. Заредете данните от файла /data/energy.csv в Pandas dataframe и разгледайте ги: 2

    energy = load_data('../../data')[['load']]
    
  3. Начертайте всички налични данни за енергия от януари 2012 до декември 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()
    

    пълни данни

    Сега нека изградим нашия SVR модел.

Създаване на тренировъчни и тестови набори от данни

Сега данните ви са заредени, така че можете да ги разделите на тренировъчен и тестов набор. След това ще преформатирате данните, за да създадете набор от данни, базиран на времеви стъпки, който ще бъде необходим за SVR. Ще обучите модела си върху тренировъчния набор. След като моделът приключи обучението, ще оцените неговата точност върху тренировъчния набор, тестовия набор и след това върху целия набор от данни, за да видите цялостното представяне. Трябва да се уверите, че тестовият набор обхваща по-късен период от време спрямо тренировъчния набор, за да гарантирате, че моделът не получава информация от бъдещи времеви периоди 2 (ситуация, известна като Overfitting).

  1. Отделете двумесечен период от 1 септември до 31 октомври 2014 за тренировъчния набор. Тестовият набор ще включва двумесечния период от 1 ноември до 31 декември 2014: 2

    train_start_dt = '2014-11-01 00:00:00'
    test_start_dt = '2014-12-30 00:00:00'
    
  2. Визуализирайте разликите: 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()
    

    тренировъчни и тестови данни

Подготовка на данните за обучение

Сега трябва да подготвите данните за обучение, като извършите филтриране и скалиране на данните. Филтрирайте набора от данни, за да включите само необходимите времеви периоди и колони, и скалирайте, за да гарантирате, че данните са проектирани в интервала 0,1.

  1. Филтрирайте оригиналния набор от данни, за да включите само споменатите времеви периоди за всеки набор и само необходимата колона 'load' плюс датата: 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)
    
  2. Скалирайте тренировъчните данни, за да бъдат в диапазона (0, 1): 2

    scaler = MinMaxScaler()
    train['load'] = scaler.fit_transform(train)
    
  3. Сега скалирайте тестовите данни: 2

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

Създаване на данни с времеви стъпки 1

За SVR трансформирате входните данни, за да бъдат във формата [batch, timesteps]. Така преформатирате съществуващите train_data и test_data, така че да има ново измерение, което се отнася до времевите стъпки.

# Converting to numpy arrays
train_data = train.values
test_data = test.values

За този пример вземаме timesteps = 5. Така входовете към модела са данните за първите 4 времеви стъпки, а изходът ще бъде данните за 5-тата времева стъпка.

timesteps=5

Преобразуване на тренировъчните данни в 2D тензор с помощта на вложени списъчни разбирания:

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)

Преобразуване на тестовите данни в 2D тензор:

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)

Избор на входове и изходи от тренировъчните и тестовите данни:

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 1

Сега е време да имплементирате SVR. За повече информация относно тази имплементация можете да се обърнете към тази документация. За нашата имплементация следваме тези стъпки:

  1. Дефинирайте модела, като извикате SVR() и зададете хиперпараметрите на модела: kernel, gamma, c и epsilon
  2. Подгответе модела за тренировъчните данни, като извикате функцията fit()
  3. Направете прогнози, като извикате функцията predict()

Сега създаваме SVR модел. Тук използваме RBF kernel и задаваме хиперпараметрите gamma, C и epsilon като 0.5, 10 и 0.05 съответно.

model = SVR(kernel='rbf',gamma=0.5, C=10, epsilon = 0.05)

Обучение на модела върху тренировъчни данни 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)

Направете прогнози с модела 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)

Създадохте SVR! Сега трябва да го оцените.

Оценка на модела 1

За оценка първо ще скалираме обратно данните към оригиналната скала. След това, за да проверим представянето, ще начертаем графика на оригиналните и прогнозирани времеви серии и ще отпечатаме резултата от MAPE.

Скалирайте обратно прогнозните и оригиналните изходи:

# 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))

Проверка на представянето на модела върху тренировъчни и тестови данни 1

Извличаме времевите марки от набора от данни, за да ги покажем на x-оста на графиката. Забележете, че използваме първите timesteps-1 стойности като вход за първия изход, така че времевите марки за изхода ще започнат след това.

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

Начертайте прогнозите за тренировъчни данни:

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 за тренировъчни данни

print('MAPE for training data: ', mape(y_train_pred, y_train)*100, '%')
MAPE for training data: 1.7195710200875551 %

Начертайте прогнозите за тестови данни

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 за тестови данни

print('MAPE for testing data: ', mape(y_test_pred, y_test)*100, '%')
MAPE for testing data:  1.2623790187854018 %

🏆 Имате много добър резултат върху тестовия набор от данни!

Проверка на представянето на модела върху целия набор от данни 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 %

🏆 Много хубави графики, показващи модел с добра точност. Браво!


🚀Предизвикателство

  • Опитайте да промените хиперпараметрите (gamma, C, epsilon) при създаването на модела и оценете данните, за да видите кой набор от хиперпараметри дава най-добри резултати върху тестовия набор от данни. За повече информация относно тези хиперпараметри можете да се обърнете към документа тук.
  • Опитайте да използвате различни функции на kernel за модела и анализирайте тяхното представяне върху набора от данни. Полезен документ можете да намерите тук.
  • Опитайте да използвате различни стойности за timesteps, за да накарате модела да се върне назад и да направи прогноза.

Тест след лекцията

Преглед и самостоятелно обучение

Този урок беше за въвеждане на приложението на SVR за прогнозиране на времеви серии. За повече информация относно SVR можете да се обърнете към този блог. Тази документация за scikit-learn предоставя по-изчерпателно обяснение за SVM като цяло, SVRs и също така други детайли за имплементация, като различните функции на kernel, които могат да бъдат използвани, и техните параметри.

Задача

Нов SVR модел

Благодарности


Отказ от отговорност:
Този документ е преведен с помощта на AI услуга за превод Co-op Translator. Въпреки че се стремим към точност, моля, имайте предвид, че автоматизираните преводи може да съдържат грешки или неточности. Оригиналният документ на неговия роден език трябва да се счита за авторитетен източник. За критична информация се препоръчва професионален човешки превод. Ние не носим отговорност за недоразумения или погрешни интерпретации, произтичащи от използването на този превод.


  1. Текстът, кодът и резултатите в този раздел са предоставени от @AnirbanMukherjeeXD ↩︎

  2. Текстът, кодът и резултатите в този раздел са взети от ARIMA ↩︎