Краткое изложение того, как сети RNN-LSTM можно использовать для точного прогнозирования цены биткойнов (BTC).
В последние пару лет RNN были довольно популярны и стали предпочтительным выбором нейронных сетей, когда речь шла о задачах, связанных с последовательными данными. Например, прогнозирование курса акций, прогнозирование слов и многое другое.
В этом блоге я реализовал модель RNN-LSTM для прогнозирования и фиксации движения биткойнов (BTC) с начала 2022 года.
Данные обучения для этой модели можно найти по этой ссылке. Все кредиты пользователю, который собрал данные вместе.
Импорт библиотек
Как видно из приведенного ниже фрагмента кода, для создания этой модели использовалась платформа машинного обучения Pytorch. Также можно использовать TensorFlow, но я лично считаю, что Pytorch предлагает гораздо более интуитивно понятный управление моделью и перемещением данных.
import pandas as pd import numpy as np import matplotlib.pyplot as plt import torch import torch.nn as nn import torch.optim as optim
Извлечение годовых данных
Данные обучения были разделены на отдельные кадры данных на ежегодной основе. Причина такого подхода заключается в том, что модель может быстро выявить основные движения и явления, влияющие на цену, используя недавние наборы данных о ценах, а не большие наборы данных, что вносит много «шума» в модель. рассматривать.
data_2021=data.loc[data['Date'].str[:4]=="2021"] data_2020=data.loc[data['Date'].str[:4]=="2020"] data_2022=data.loc[data['Date'].str[:4]=="2022"]
Этот блог будет посвящен только использованию данных 2021 года для целей моделирования. Аналогичный подход можно использовать и для других лет.
Для моделирования и прогнозирования использовалась только цена Close.
Данные за 2021 год использовались для обучения модели и прогнозирования цен на 2022 год (~2 месяца)
train=data_2021['Close'].values test=data_2022['Close'].values
Масштабирование функций
Масштабирование признаков является важным шагом в обучении моделей RNN-LSTM, поскольку обучающие данные (Цена закрытия) могут варьироваться в различных пределах и, следовательно, должны быть приведены к общему масштабу, который может интерпретировать модель.
Для вышеуказанной цели использовался класс MinMaxScaler из пакета sklearn.
in_scaler=MinMaxScaler(feature_range=(-1,1)) train=in_scaler.fit_transform(train.reshape(-1,1)) test=in_scaler.transform(test.reshape(-1,1))
Создание окон
Уникальной особенностью RNN является то, что он предсказывает предстоящие значения, обрабатывая определенное количество значений перед ним. Количество значений, предварительно обработанных моделью для прогнозирования следующего значения, называется размером окна/длиной последовательности. См. диаграмму ниже —
А ниже код (размер окна = 9)
ws=9 #window size = 9 def data_loader(train, test): train_seq=[] train_tar=[] test_seq=[] test_tar=[] for i in range(len(train)-ws): train_seq.append(train[i:i+ws]) train_tar.append(train[i+ws:i+ws+1]) for i in range(len(test)-ws): test_seq.append(test[i:i+ws]) test_tar.append(test[i+ws:i+ws+1]) return [train_seq, train_tar, test_seq, test_tar] train_seq,train_tar, test_seq, test_tar=data_loader(train, test) ''' Converting the arrays to Tensors ''' train_seq=torch.Tensor(np.array(train_seq)) train_tar=torch.Tensor(np.array(train_tar)) test_seq=torch.Tensor(np.array(test_seq)) test_tar=torch.Tensor(np.array(test_tar))
Архитектура модели LSTM
''' Defining hyperparameters ''' input_size=1 hidden_dim1=1500 num_layers=2 output_size=1 ''' Defining the class ''' class LSTM(nn.Module): def __init__(self, input_size, hidden_dim1, num_layers, output_size): super(LSTM, self).__init__() self.hidden_dim1=hidden_dim1 self.num_layers=num_layers self.lstm1=nn.LSTM(input_size, hidden_dim1, num_layers, batch_first=True) self.l1=nn.Linear(hidden_dim1, output_size) self.relu=nn.ReLU() def forward(self, x): h0=torch.zeros(self.num_layers, x.size(0), self.hidden_dim1).requires_grad_() #hidden_state c0=torch.zeros(self.num_layers, x.size(0), self.hidden_dim1).requires_grad_() #hidden_cell lstm_out1,(hn,cn)=self.lstm1(x,(h0.detach(), c0.detach())) output=self.l1(lstm_out1[:,-1,:]) return output model=LSTM(input_size=input_size, hidden_dim1=hidden_dim1, num_layers=num_layers,output_size=output_size) criterion=nn.MSELoss() optimizer=optim.Adam(model.parameters(), lr=0.001)
MSELoss — это функция потерь для расчета потерь для каждой итерации во время обучения.
Адам используется в качестве функции оптимизатора для минимизации потерь во время обучения.
Обучение
Модель была обучена на 300 эпохах с MSELoss в качестве функции потерь и Адамом в качестве оптимизатора.
epochs=300 e_loss=[] for epoch in range(epochs): y_pred=model(train_seq) loss=criterion(y_pred, train_tar) optimizer.zero_grad() loss.backward() optimizer.step() e_loss.append(loss.item()) print('Epoch [{}/{}] Loss: {}'.format(epoch+1, epochs, loss.item()))
Тестирование
Модель была протестирована на 41 значении, все из которых соответствуют 1 января 2022 года. Ниже приведен график сравнения фактических и прогнозируемых цен.
Metricwise: оценка R2 составила 0,7551.
Заключение
Хотя модель может показаться не совсем точной (низкий показатель R2), она все же может отражать тенденцию постоянно растущего волатильного актива, что, я считаю, имеет гораздо большее значение, чем первое.
Поскольку я только новичок в сетях RNN-LSTM и, возможно, мне нужно сделать гораздо больше домашней работы, прежде чем пытаться настроить модель, я ценю ваш интерес к чтению этого моего блога. Спасибо!
Счастливый мл.