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/ru/7-TimeSeries/3-SVR
leestott c7a68c1882
🌐 Update translations via Co-op Translator
1 year ago
..
solution 🌐 Update translations via Co-op Translator 1 year ago
working 🌐 Update translations via Co-op Translator 1 year ago
README.md 🌐 Update translations via Co-op Translator 1 year ago
assignment.md 🌐 Update translations via Co-op Translator 1 year ago

README.md

Прогнозирование временных рядов с использованием регрессора опорных векторов

В предыдущем уроке вы узнали, как использовать модель ARIMA для прогнозирования временных рядов. Теперь вы познакомитесь с моделью регрессора опорных векторов (Support Vector Regressor), которая используется для прогнозирования непрерывных данных.

Тест перед лекцией

Введение

В этом уроке вы узнаете, как строить модели с использованием SVM: Support Vector Machine для регрессии, или SVR: Support Vector Regressor.

SVR в контексте временных рядов 1

Прежде чем понять важность SVR в прогнозировании временных рядов, необходимо ознакомиться с некоторыми ключевыми понятиями:

  • Регрессия: Метод обучения с учителем для прогнозирования непрерывных значений на основе заданного набора входных данных. Идея заключается в том, чтобы построить кривую (или линию) в пространстве признаков, которая охватывает максимальное количество точек данных. Подробнее здесь.
  • Опорные векторы (SVM): Тип модели машинного обучения с учителем, используемой для классификации, регрессии и обнаружения выбросов. Модель представляет собой гиперплоскость в пространстве признаков, которая в случае классификации действует как граница, а в случае регрессии — как линия наилучшего соответствия. В SVM обычно используется функция ядра для преобразования набора данных в пространство с большим количеством измерений, чтобы они могли быть легко разделены. Подробнее здесь.
  • Регрессор опорных векторов (SVR): Тип SVM, который находит линию наилучшего соответствия (в случае SVM это гиперплоскость), охватывающую максимальное количество точек данных.

Почему SVR? 1

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

Упражнение — создание модели SVR

Первые несколько шагов подготовки данных такие же, как в предыдущем уроке о ARIMA.

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

  1. Запустите ноутбук и импортируйте необходимые библиотеки: 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 (ситуация, известная как переобучение).

  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) при создании модели и оцените данные, чтобы увидеть, какой набор гиперпараметров дает лучшие результаты на тестовом наборе данных. Подробнее о гиперпараметрах можно узнать здесь.
  • Попробуйте использовать разные функции ядра для модели и проанализируйте их производительность на наборе данных. Полезный документ можно найти здесь.
  • Попробуйте использовать разные значения timesteps для модели, чтобы она могла учитывать больше временных шагов для прогнозирования.

Тест после лекции

Обзор и самостоятельное изучение

Этот урок был посвящен введению в применение SVR для прогнозирования временных рядов. Чтобы узнать больше о SVR, вы можете обратиться к этому блогу. Эта документация scikit-learn предоставляет более подробное объяснение о SVM в целом, SVR, а также другие детали реализации, такие как различные функции ядра, которые можно использовать, и их параметры.

Задание

Новая модель SVR

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


Отказ от ответственности:
Этот документ был переведен с помощью сервиса автоматического перевода Co-op Translator. Хотя мы стремимся к точности, пожалуйста, имейте в виду, что автоматические переводы могут содержать ошибки или неточности. Оригинальный документ на его исходном языке следует считать авторитетным источником. Для получения критически важной информации рекомендуется профессиональный перевод человеком. Мы не несем ответственности за любые недоразумения или неправильные интерпретации, возникшие в результате использования данного перевода.


  1. Текст, код и результаты в этом разделе были предоставлены @AnirbanMukherjeeXD ↩︎

  2. Текст, код и результаты в этом разделе были взяты из ARIMA ↩︎