3 min read

Prophet

Prophet

Prophet – это библиотека для создания Моделей (Model) Машинного обучения (Machine Learning) на базе Scikit-learn. Ее характерная особенность – это использование временных рядов для предсказания целевой переменной. Тренировочный Датасет (Dataset) подготавливается таким образом, чтобы входными данными был временной ряд и исторические значения целевой переменной:

Давайте попробуем предсказать стоимость акции компании "Магнит" (тикер $MGNT.ME). Для этого экспортируем csv-файл со вкладки "Исторические данные" (Historical Data) на finance.yahoo.com со всей историей наблюдений. Для этого в настройке "Временной интервал" (Time Period) установим 'Max'.

Создадим ноутбук на colab.research.google.com и импортируем для начала необходимые библиотеки. Мы используем классический набор из NumPy, Pandas и Matplotlib для подготовки данных и их визуализации. Pylab позволит нам тонко настроить внешний вид конечного графика, а MinMaxScaler – произвести Нормализацию (Normalization) данных. Класс add_changepoints_to_plot – это специальная надстройка, позволяющая добавить так называемые точки разворота:

Точки разворота (Pivot Points) показывают, когда стоимость акции сменила тенденцию
import numpy as np
import pandas as pd
import pylab
import matplotlib.pyplot as plt

from fbprophet import Prophet
from fbprophet.plot import add_changepoints_to_plot

# Для нормализации данных
from sklearn.preprocessing import MinMaxScaler 

Зададим графику "опрятный" внешний вид:

plt.rcParams["figure.figsize"] = (7.5, 5) # Размер полотна в дюймах
pylab.rc('figure', figsize = (10, 7))

plt.style.use('seaborn') # Предустановленная цветовая палитра

# Универсальные переменные для стилизации графика
MEDIUM_SIZE = 12
BIGGER_SIZE = 16

# Размер шрифта
plt.rc('axes', titlesize = BIGGER_SIZE)     # Оси
plt.rc('axes', labelsize = BIGGER_SIZE)     # Ярлыки x и y
plt.rc('xtick', labelsize = MEDIUM_SIZE)    # Отметки оси x
plt.rc('ytick', labelsize = MEDIUM_SIZE)    # Отметки оси y
plt.rc('figure', titlesize = BIGGER_SIZE)   # Заголовок

Препроцессинг

Прежде чем отправлять модель обучаться, мы произведем препроцессинг и слегка преобразуем датасет. Для простоты воспроизведения кода загрузим датасет на Dropbox и разрешим его скачивание, задав параметр 'dl=1' в конце ссылки.

training_dataset = pd.read_csv(
    'https://www.dropbox.com/s/4qoitqcxmxo1n8x/MGNT.ME.csv?dl=1')

training_dataset.head()

Наши данные выглядят следующим образом:

# .iloc() выбирает все ряды (':') столбцов 
# с индексами c 1-го по 2-й [1:2] и копируем выбранные значения
# в новый объект training_data
training_data = training_dataset.iloc[:, 1:2].values

# Приведем все значения к диапазону от 0 до 1 (нормализация)
sc = MinMaxScaler(feature_range = (0, 1))  

# Загрузим данные в модель
training_data = sc.fit_transform(training_data)

# Выполним масштабирование
X_train = []
y_train = []

# Отсечем первые 60 наблюдений, чтобы исключить период роста
for i in range(60, len(training_data)):
    X_train.append(training_data[i-60:i, 0])
    y_train.append(training_data[i, 0])

# Преобразуем результат в ряд NumPy для точности
X_train = np.array(X_train)
y_train = np.array(y_train)    

# Зададим явные измерения тренировочных данных для Prophet
X_train = X_train.reshape((len(training_data)-60), 60, 1)

Прогнозирование

stock = pd.read_csv(
'https://www.dropbox.com/s/4qoitqcxmxo1n8x/MGNT.ME.csv?dl=1',
                    header = 0,         # Индекс заголовка – ноль
                    index_col = 0,      # Считывание с нулевого столбца
                    parse_dates = True) # Обнаружить временные метки
					
stock.head()

Prophet работает с двумя столбцами, один из которых – временная метка, потому вторым мы выберем "Стоимость акции на момент открытия биржи" (Open):

stock = stock["Open"]

Произведем переиндексацию согласно требованиям этой библиотеки Facebook:

data_train = stock.reset_index() # Теперь индекс – порядковые номера

# Столбцы называем "Штамп даты" (datestamp) и "Целевая переменная" (y)
data_train.columns = ['ds', 'y'] 

Скормим модели тренировочные данные и запросим предсказание на 2020-2021 гг. включительно:

model = Prophet()     # Инициализация Prophet()
model.fit(data_train) # Загрузка данных в модель

# Предсказание на 730 дней вперед
future = model.make_future_dataframe(periods = 730) 
predict = model.predict(future)

Визуализируем результат с помощью Matplotlib:

Скачать ноутбук, исполняемый без дополнительной настройки на момент написания статьи, можно по ссылке.

Фото: @svfedo