Персональный блог: ksrgtech.com

Эта статья разделена на 8 частей, как показано ниже:

  1. Постановка задачи
  2. Подготовка к Python-модулю
  3. Подготовка данных
  4. Построение модели
  5. Примерка модели
  6. Предсказание модели
  7. Визуализация результатов
  8. Недостатки этой статьи

И в качестве дополнения читатели, которые хотят знать, как именно работает LSTM, могут заглянуть в блог colah:
Оригинал на английском языке:
http://colah.github .io/posts/2015-08-Understanding-LSTMs/
Версия на китайском языке:
https://www.jianshu.com/p/95d5c461924c

Давайте начнем!!

1. Постановка проблемы

Что такое Билибили? Вы можете видеть это как китайскую версию Youtube, но больше связанную с ACG (аниме, комиксы и игры). Он стартовал в 2009 году и сейчас является очень многообещающей и быстрорастущей платформой с более чем 170 миллионами пользователей.

В этой статье мы применим расширение рекуррентной нейронной сети (RNN), называемое долговременной кратковременной памятью (LSTM), к биржевым данным Bilibili (NASDAQ: BILI). Мы будем использовать 80% данных для обучения модели, а остальные данные будем использовать для прогнозирования и проверки.

Предсказать точные цены на акции невозможно. Алгоритмы нейронных сетей могут помочь только в изучении общего тренда акций, поэтому

2. Подготовка к модулю Python

Если вы не установили некоторые модули, такие как pandas_datareader, вы можете ввести следующий код в командном окне, чтобы загрузить его.

pip install pandas_datareader

Почти каждый модуль или пакет Python загружается таким образом.

pip install [Module Name]

Затем загрузите все модули, которые мы будем использовать в этой статье.

#For loding data
from pandas_datareader import data as pdr 
#For data preprocessing
import math 
from sklearn.preprocessing import MinMaxScaler 
import numpy as np 
#For model building
from keras.models 
import Sequential 
from keras.layers import Dense, Dropout, LSTM, TimeDistributed 
#For data visualization
import missingno as msno 
import matplotlib.pyplot as plt 
import seaborn as sns 
sns.set(color_codes='Ture')

3. Подготовка данных

3.1 Импорт данных

#The data is obtained from Yahoo Finance
#Bilibili ticker symbol: BILI
df=pdr.get_data_yahoo('BILI',start='2018-03-28',end='2020-08-18') 
#View the data 
df

Вывод:

Данные имеют 603 строки и 6 столбцов. То есть размер выборки – 603, а номер признака – 6.
В этой статье мы будем использовать только столбец Закрыть.

3.2 Обработка пропущенных значений

Далее нам нужно проверить пропущенные значения. Если есть пропущенные значения, нам нужно выполнить соответствующую обработку, в зависимости от того, в каком месте они находятся, удалить или заполнить.

#Visualize missing values
msno.matrix(df)

Вывод:

Как видно из рисунка слева, эти данные полные, пропущенных значений нет, можно переходить к следующим шагам.

3.3 Разделить обучающий и тестовый наборы

Мы возьмем первые 80 % данных в качестве обучающего набора для обучения модели, а последние 20 % данных — в качестве тестового набора для проверки прогностических свойств модели. способность.

#Arrange the dataframe in descending order by index
data = df.sort_index(ascending=True, axis=0)
#We will only be using the Close column
dataset=data[['Close']].values
#Take 80% of the data as the training set
training_data_len=math.ceil(len(dataset)*.8)
train_data=dataset[0:training_data_len,:]
#Take the remaining data as the test set
#When making predictions, the first data of the remaining data requires the data of the previous 60 days to predict, so this goes back 60 days
test_data = dataset[training_data_len-60:,:]

3.4 Нормализация данных

На этом этапе данные будут сопоставлены с интервалом [0,1]. Цель состоит в том, чтобы улучшить скорость сходимости модели и повысить ее точность.
Используемый здесь метод называется min-max. нормализация или нормализация 0–1.

#Feature scaling
scaler=MinMaxScaler(feature_range=(0,1))
scaled_train=scaler.fit_transform(train_data)
scaled_test=scaler.fit_transform(test_data)

3.5 Реконструкция данных

Цель этого раздела — сделать так, чтобы данные соответствовали входным требованиям алгоритма. Есть три шага.

1. Разделите набор данных на две части x и y, используйте x для предсказания y.

Для простоты описания изображения, если мы возьмем 3 дня в качестве временного шага, мы будем использовать данные за предыдущие три дня (большой оранжевый прямоугольник, большой зеленый прямоугольник, x) для прогнозирования данных четвертый день (маленький оранжевый прямоугольник, маленький зеленый прямоугольник, у). В этом блоге фактические временные шаги равны 60, то есть данные за первые 60 дней используются для прогнозирования данных за 61-й день.

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

3. Преобразование двумерных данных в трехмерные.
Для ввода LSTM требуется трехмерный массив (выборки, временные интервалы, признаки), которые соответственно относятся к размеру выборки, временным шагам и номеру признака.
x_train и x_test будет использоваться в качестве входных данных LSTM, а пока это пока двумерные данные (выборки, timsteps=60), нам нужно добавить к этим двум измерениям еще одно, а так как для анализа мы берем только цену закрытия , затем установите свойство=1.

#Reconstruction of training set
#1 separate x and y
x_train=[]
y_train=[]
for i in range(60,len(scaled_train)):
     x_train.append(scaled_train[i-60:i,0])
     y_train.append(scaled_train[i,0])
#2 Convert list type data into array
x_train,y_train=np.array(x_train),np.array(y_train)
#3 Turn 2D data into 3D data
x_train=np.reshape(x_train,(x_train.shape[0],x_train.shape[1],1))
#Test set reconstruction
#1 separate x and y
x_test = []
y_test = dataset[training_data_len:,:]
for i in range(60,len(scaled_test)):
     x_test.append(scaled_test[i-60:i,0])
#2 Convert list type data into array
x_test = np.array(x_test)
#3 Turn 2D data into 3D data
x_test = np.reshape(x_test, (x_test.shape[0],x_test.shape[1],1))

4. Построение модели

#Initialize model
model = Sequential()
#LSTM layer
model.add(LSTM(units=50, return_sequences=True,input_shape=(x_train.shape[1],1)))
#Dropout layer
model.add(Dropout(.2))
#LSTM layer
model.add(LSTM(units=50, return_sequences=False))
#Dropout layer
model.add(Dropout(.2))
#Fully connected layer
model.add(Dense(units=1))
#Model compilation
model.compile(optimizer='adam', loss='mean_squared_error')

🔸 Инициализируйте нейронную сеть: Sequential()

🔸 Слой LSTM: LSTM()
Как правило, двухслойный LSTM может хорошо соответствовать данным. Многослойный LSTM улучшит соответствие модели, но также усложнит ее и усложнит обучение.

Параметр units=50 означает, что слой имеет 50 LSTM-нейронов, а выход этого слоя — 50-мерный вектор.
Параметр input_shape требует от нас для ввода двумерного массива, включая временные интервалы и функции.
Параметр return_sequences используется для указания, следует ли возвращать массив, содержащий временные интервалы.

  • True возвращает трехмерный массив (размер пакета, временные интервалы, количество единиц).
  • False возвращает двумерный массив (размер пакета, количество единиц).

🔸 Слой исключения для предотвращения переобучения: Dropout()
Функция Dropout(0.2) означает, что 20 % данных случайным образом удаляются из выходных данных предыдущий слой

🔸 Полносвязный слой нейронной сети: Dense()
Также называется плотно связанным слоем, это означает, что каждый узел этого слоя связан со всеми узлами предыдущего слоя. Параметр unites=1 означает, что в этом слое есть один нейрон.

🔸 Компиляция нейронной сети: compile()
Используйте Adam для оптимизации, используя MSE (среднеквадратическую ошибку) в качестве функции потерь.

Структура общей нейронной сети представлена ​​на рисунке:

#Model structure
model.summary()

Вывод:

Мы можем видеть форму выходных данных каждого слоя и количество параметров в каждом слое.

5. Примерка модели

Используйте данные обучающего набора x_train, y_train для обучения модели. Эта статья не включает этапы настройки параметров. Здесь я просто случайным образом задаю два значения 25 и 10 параметрам batch_size и epochs.

  • batch_size: если набор данных слишком велик, нецелесообразно вводить его все за один раз, один из способов — разделить полные данные на несколько входных данных, размер выборки одного входного параметра называется batch_size.
  • эпохи: полные данные проходят через нейронную сеть один раз, называемую эпохой.

Фактически, эти два значения имеют большое влияние на то, насколько хорошо мы можем подобрать модель.

6. Предсказание модели

После обучения модели с помощью обучающего набора используйте тестовый набор для прогнозирования;
Поскольку x_test уже был нормализован ранее, нам нужно использовать функцию inverse_transform(), чтобы обратить его.

#prediction
predictions = model.predict(x_test)
#Reverse the scaling
predictions = scaler.inverse_transform(predictions)

7. Визуализация результатов

#Create a dataframe for plotting
train = data[:training_data_len]
valid = data[training_data_len:]
#Add a new column to valid, and assign predictions to the new column
valid['Predictions'] = predictions
#Start plotting
#set figure size
plt.figure(figsize=(16,8))
#set title
plt.title('Model')
#set x-axis name
plt.xlabel('Date', fontsize=18)
#set y-axis name
plt.ylabel('Close Price USD ($)', fontsize=18)
#Draw the line chart for training set
plt.plot(train['Close'])
#Draw the line graph of the true value and the predicted value separately
plt.plot(valid[['Close','Predictions']])
#Display legend
plt.legend(['Train','Val','Predictions'], loc='lower right')
plt.show()

Вывод:

Из рисунка видно, что алгоритм LSTM действительно может довольно точно предсказать тренд акций.

8. Ошибкиэтой статьи

  • В этой статье для прогнозирования используется только один метод LSTM. На самом деле существует множество других методов, таких как традиционный ARIMA, и методы машинного обучения, такие как k ближайших соседей.
  • В этой статье не рассматривается параметр настройки. Существует множество способов настройки параметров. Помимо ручной настройки параметров, вы можете использовать некоторые алгоритмы, такие как поиск по сетке, случайный поиск и байесовские методы.
  • После прогнозирования значения, когда мы хотим предсказать следующее значение, данные за предыдущие 60 дней (которые используются для прогнозирования этого «следующего значения») должны включать наше прогнозируемое значение, и в этой статье используются все реальные данные, чтобы сделать предсказание вместо предсказанных данных.
  • …(Если вы найдете больше недостатков в этой статье, пожалуйста, оставьте комментарии~~

Спасибо за ваше время~🌸