Примечание: данный случай используется только для исследовательских целей и не является инвестиционным предложением.
Данные о цене биткоина основаны на временных последовательностях, поэтому предсказания цены на биткоин в основном осуществляются с использованием модели LSTM.
Долгосрочная кратковременная память (LSTM) - это модель глубокого обучения, особенно подходящая для данных временной последовательности (или данных, имеющих временную/пространственную/структурную последовательность, например, фильмы, предложения и т. д.), которая является идеальной моделью прогнозирования ценового движения криптовалюты.
В статье основное внимание уделяется сборке данных с помощью LSTM, чтобы предсказать будущую цену биткойна.
import pandas as pd
import numpy as np
from sklearn.preprocessing import MinMaxScaler, LabelEncoder
from keras.models import Sequential
from keras.layers import LSTM, Dense, Dropout
from matplotlib import pyplot as plt
%matplotlib inline
Загрузка данных
Читать данные о дневном обороте BTC
data = pd.read_csv(filepath_or_buffer="btc_data_day")
В настоящее время данные находятся в 1380 строках, состоящих из столбцов Date, Open, High, Low, Close, Volume (BTC), Volume (Currency) и Weighted Price.
data.info()
Смотрите данные в первых 10 строках.
data.head(10)
Визуализация данных
Используя matplotlib, мы можем изобразить взвешенную цену и посмотреть на распределение и движение данных. На рисунке мы обнаружили часть данных 0, и нам нужно подтвердить, есть ли какие-либо отклонения в данных.
plt.plot(data['Weighted Price'], label='Price')
plt.ylabel('Price')
plt.legend()
plt.show()
Необычная обработка данных
Сначала посмотрим, есть ли в данных данные нана, и мы увидим, что в наших данных нет данных нана.
data.isnull().sum()
Date 0
Open 0
High 0
Low 0
Close 0
Volume (BTC) 0
Volume (Currency) 0
Weighted Price 0
dtype: int64
Если мы посмотрим на данные 0, мы увидим, что в наших данных есть нулевые значения, и мы должны обрабатывать их.
(data == 0).astype(int).any()
Date False
Open True
High True
Low True
Close True
Volume (BTC) True
Volume (Currency) True
Weighted Price True
dtype: bool
data['Weighted Price'].replace(0, np.nan, inplace=True)
data['Weighted Price'].fillna(method='ffill', inplace=True)
data['Open'].replace(0, np.nan, inplace=True)
data['Open'].fillna(method='ffill', inplace=True)
data['High'].replace(0, np.nan, inplace=True)
data['High'].fillna(method='ffill', inplace=True)
data['Low'].replace(0, np.nan, inplace=True)
data['Low'].fillna(method='ffill', inplace=True)
data['Close'].replace(0, np.nan, inplace=True)
data['Close'].fillna(method='ffill', inplace=True)
data['Volume (BTC)'].replace(0, np.nan, inplace=True)
data['Volume (BTC)'].fillna(method='ffill', inplace=True)
data['Volume (Currency)'].replace(0, np.nan, inplace=True)
data['Volume (Currency)'].fillna(method='ffill', inplace=True)
(data == 0).astype(int).any()
Date False
Open False
High False
Low False
Close False
Volume (BTC) False
Volume (Currency) False
Weighted Price False
dtype: bool
И если мы посмотрим на распределение данных и на их движение, то кривая уже очень последовательна.
plt.plot(data['Weighted Price'], label='Price')
plt.ylabel('Price')
plt.legend()
plt.show()
Разделение учебных и тестовых наборов
Упорядочить данные до 0 - 1.
data_set = data.drop('Date', axis=1).values
data_set = data_set.astype('float32')
mms = MinMaxScaler(feature_range=(0, 1))
data_set = mms.fit_transform(data_set)
Разделяем тестовые и тренировочные наборы на 2:8.
ratio = 0.8
train_size = int(len(data_set) * ratio)
test_size = len(data_set) - train_size
train, test = data_set[0:train_size,:], data_set[train_size:len(data_set),:]
Создание тренировочных и тестовых наборов данных в течение одного дня как окна для создания наших тренировочных и тестовых наборов данных.
def create_dataset(data):
window = 1
label_index = 6
x, y = [], []
for i in range(len(data) - window):
x.append(data[i:(i + window), :])
y.append(data[i + window, label_index])
return np.array(x), np.array(y)
train_x, train_y = create_dataset(train)
test_x, test_y = create_dataset(test)
На этот раз мы используем простую модель, которая имеет следующую структуру: 1. LSTM2. Dense.
Здесь необходимо сделать пояснение в отношении формы ввода в LSTM. Вводная величина формы ввода - batch_size, time steps, features. В ней значение time steps - это интервал времени окна при вводе данных, здесь мы используем 1 день в качестве окна времени, и наши данные - это данные дня, поэтому здесь наши время шаги - 1.
Длинная краткосрочная память (англ. Long short-term memory, LSTM) - это особый вид РНН, который используется для решения проблем с исчезновением и взрывом на протяжении длинной последовательности тренировок.
С помощью схемы сетевой структуры LSTM можно увидеть, что LSTM - это небольшая модель, которая содержит три сигмоидных активации, две танх-активации, три умножения и одно добавление.
Состояние клеток
Состояние клетки является ядром ЛСТМ. Он является темной линией, которая находится в верхней части диаграммы, и ниже этой черной линии есть несколько ворот, которые мы рассмотрим позже. Состояние клетки обновляется в зависимости от результатов каждой из ворот.
ЛСТМ-сеть может удалять или добавлять информацию о состоянии клетки через структуру, называемую воротами. Врата могут избирательно решать, какая информация должна проходить через них. Структура дверей - это комбинация сигмоидного слоя и операций с умножением точки.
Забытые двери
Первым шагом LSTM является определение того, какую информацию необходимо избавиться от клетки. Эта часть операции обрабатывается через сигмоидный модуль, называемый дверью забытия.
Мы можем видеть, что запоминающийся вход выводит вектор между 0 и 1 путем просмотра информации $h_{l-1}$ и $x_{t}$, где значение 0 и 1 означает, какая информация в состоянии $C_{t-1}$ сохраняется или отбрасывается. 0 означает, что не сохраняется, а 1 означает, что сохраняется.
Математическое выражение: $f_{t}=\sigma\left(W_{f} \cdot\left[h_{t-1}, x_{t}\right]+b_{f}\right) $
Входные двери
Следующий шаг - это решение, какая новая информация должна быть добавлена к состоянию клетки, и это происходит через входную дверь.
Мы видим, что сообщения $h_{l-1}$ и $x_{t}$ вновь помещаются в запоминающуюся дверь (sigmoid) и в входную дверь (tanh). Так как результат запоминаемой двери равен 0-1, то если запоминающая дверь выводит 0, то результат $C_{i}$ после ввода не будет добавлен в текущее состояние клетки, а если 1, то все будет добавлено в состояние клетки, поэтому роль запоминающей двери здесь заключается в выборочном добавлении результатов запоминающей двери в состояние клетки.
Формула: $C_{t}=f_{t} * C_{t-1} + i_{t} * \tilde{C}_{t}$
Выход
После обновления состояния клетки требуется определить, какие состояния клетки должны быть определены на основе суммы ввода $h_{l-1}$ и $x_{t}$. При этом ввод должен быть выполнен через сигмоидный слой, называемый выходной дверью, а затем через танх-слой.
def create_model():
model = Sequential()
model.add(LSTM(50, input_shape=(train_x.shape[1], train_x.shape[2])))
model.add(Dense(1))
model.compile(loss='mae', optimizer='adam')
model.summary()
return model
model = create_model()
history = model.fit(train_x, train_y, epochs=80, batch_size=64, validation_data=(test_x, test_y), verbose=1, shuffle=False)
plt.plot(history.history['loss'], label='train')
plt.plot(history.history['val_loss'], label='test')
plt.legend()
plt.show()
train_x, train_y = create_dataset(train)
test_x, test_y = create_dataset(test)
predict = model.predict(test_x)
plt.plot(predict, label='predict')
plt.plot(test_y, label='ground true')
plt.legend()
plt.show()
В настоящее время очень сложно предсказать длительный курс биткоина с помощью машинного обучения, и этот материал может быть использован только в качестве учебного примера. Этот случай будет доступен для пользователей, заинтересованных в его прямом опыте.