Персональный блог: ksrgtech.com
Эта статья разделена на 8 частей, как показано ниже:
- Постановка задачи
- Подготовка к Python-модулю
- Подготовка данных
- Построение модели
- Примерка модели
- Предсказание модели
- Визуализация результатов
- Недостатки этой статьи
И в качестве дополнения читатели, которые хотят знать, как именно работает 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 дней (которые используются для прогнозирования этого «следующего значения») должны включать наше прогнозируемое значение, и в этой статье используются все реальные данные, чтобы сделать предсказание вместо предсказанных данных.
- …(Если вы найдете больше недостатков в этой статье, пожалуйста, оставьте комментарии~~