А в качестве бонуса стать богатым! Шучу, бро.
В этом посте мы построим модель LSTM для прогнозирования цен на акции Apple, используя Tensorflow!
Прогнозирование цен на акции — очень интересная область машинного обучения. Лично у меня всегда есть интерес к приложениям в этой области.
Машинное обучение стало очень полезным для прогнозирования фондового рынка за последние годы, и сегодня многие инвестиционные компании используют машинное обучение для принятия решений в Фондовый рынок.
И, вопреки тому, что многие думают, нам не нужна потрясающая Модель машинного обучения, чтобы действительно зарабатывать деньги.
Предупреждение. Этот пост имеет целью только исследовать и показать, как модели машинного обучения работают на фондовом рынке, это не рекомендации по инвестициям! Фондовый рынок меняется быстро и не рекомендуется новичкам без опыта!
Теперь мы можем продолжить!
Как работает LSTM?
По сути, модели LSTM могут хранить информацию с течением времени. Это очень полезно, когда мы хотим работать с временными рядами или последовательными данными.
Модели LSTM очень похожи на человеческий мозг. Когда кто-то говорит тебе:
"Марк и Джейн играют в футбол на улице"
Вы уже знаете, что такое футбол, кто такие Марк и Джейн и что такое улица, поэтому вам будет легче обрабатывать и понимать информацию.
Предположим, вы ничего не знали, это было бы очень сложно и, возможно, вы не поняли бы информацию с первого раза.
LSTM работает так: после сохранения информации они могут решать более сложные проблемы, где важна предыдущая информация.
Применив это к проблеме этого поста, когда мы хотим спрогнозировать цену, нам понадобится предыдущая информация. Вот почему LSTM очень полезен!
Другая важная особенность LSTM заключается в том, что мы можем решить, какая информация будет храниться, а какую можно отбросить. Мы делаем это с помощью вентилей, и это помогает нам избежать таких проблем, как Проблема исчезающего градиента.
На изображении ниже у нас есть архитектура ячейки LSTM и ее функции:
По сути, в этих функциях происходит магия забывания, обновления и сохранения информации.
Если вы хотите узнать больше о LSTM, я рекомендую прочитать это.
Теперь давайте перейдем к нашей проблеме!
Понимание проблемы
Как вы могли видеть ранее, прогнозирование цены акций связано с использованием последовательных данных, где прошлые данные имеют значение и влияют непосредственно на наши прогнозы.
Это пример последовательных данных о ценах на акции:
Что мы хотим сделать, так это: дать нашей модели историю цен на акции Apple, он будет работать с этими данными, чтобы выявить закономерности и сделать много вычислений, чтобы потом дать нам прогнозы!
И почему я выбрал акции Apple?
Итак, сначала нам нужно загрузить наши данные. Для этого проекта я использовал набор данных, экспортированный напрямую из NASDAQ, вы можете скачать эти данные здесь.
Мы используем нейронные сети, поэтому чем больше данных, тем лучше, я использовал цены за последние 5 лет, они нам пригодятся.
После загрузки данных мы хотим сделать худшую часть любого специалиста по данным или инженеру по машинному обучению — адаптации!
Уже отформатированные данные находятся в репозитории этого поста, в конце этого поста.
Но сначала адаптируйте наши Данные, нам нужно посмотреть, что мы будем адаптировать и форматировать. Если мы посмотрим на данные, это выглядит так:
Теперь мы хотим знать, есть ли в нашем наборе данных нулевые значения. Хороший способ сделать это — использовать heatmap() от Seaborn для его визуализации.
Но, как вы могли видеть ранее, в нашем столбце «Дата» используется «/», и это может помешать нашей работе, поэтому нам нужно отформатировать его!
На самом деле, в нашей модели мы просто хотим использовать столбец «Открыть», но было бы неплохо отформатировать столбцы «Дата», чтобы мы могли использовать их позже в другом проекте с теми же данными.
Чтобы отформатировать наш столбец «Дата», мы можем использовать to_datetime() от Pandas:
data[‘Date’] = pd.to_datetime(data.Date)
Теперь наш столбец «Дата» имеет формат «Дата-время»!
Теперь нам нужно отформатировать наши цены, они в формате String. Это легко сделать, мы можем использовать replace() из класса String.
data[‘Open’] = data[‘Open’].replace({‘\$’:’’}, regex=True).astype(float) data[‘High’] = data[‘High’].replace({‘\$’: ‘’}, regex=True).astype(float) data[‘Close/Last’] = data[‘Close/Last’].replace({‘\$’: ‘’}, regex=True).astype(float) data[‘Low’] = data[‘Low’].replace({‘\$’: ‘’}, regex=True).astype(float)
И последнее, что нужно изменить в наших данных, это удалить пробел в имени столбцов, мы можем сделать это с помощью rename() от Pandas.
data.rename(columns={‘ Close/Last’: ‘Close/Last’, ‘ Volume’: ‘Volume’, ‘ Open’: ‘Open’, ‘ High’: ‘High’, ‘ Low’: ‘Low’}, inplace=True)
Теперь наш набор данных отформатирован и готов к разделению.
В нашем наборе данных 1258, мы хотим использовать 1000 строк для поезда и 258 для теста:
# Split into train and test: data_to_train = data[:1000] data_to_test = data[1000:]
Теперь мы можем сохранить 2 CSV-файла, Train и Test.
data_to_train.to_csv(‘train_data.csv’) data_to_test.to_csv(‘test_data.csv’)
Пришло время заняться машинным обучением, детка!
Создание нашей модели
Эта архитектура была основана на Модели Деррика Мвити, которую я тестировал, и результаты были слишком хорошими!
Мы хотим использовать столбец «Открыть» в нашей модели, поэтому мы можем использовать iloc для получения его значений.
training_set = train_data.iloc[: , 3:4].values
И мы хотим определить переменную как real_stock_price для хранения наших реальных данных для последующего сравнения с прогнозами нашей модели!
real_stock_price = test_data.iloc[: , 3:4].values
После получения значений из столбца «Открыть» нам нужно их масштабировать. Благодаря этому наша Модель работает лучше!
Чтобы масштабировать значения, мы можем использовать sklearn!
# Normalizing data, scale between 0 and 1: from sklearn.preprocessing import MinMaxScaler sc = MinMaxScaler(feature_range=(0, 1)) training_data_scaled = sc.fit_transform(training_set)
После масштабирования данных обучения нам нужно отформатировать их в 3D-массив для ввода в нашу модель LSTM. Мы делаем это, создавая 60 меток времени.
X_train = [] y_train = [] for i in range(60, 1000): X_train.append(training_data_scaled[i-60:i, 0]) y_train.append(training_data_scaled[i, 0]) X_train, y_train = np.array(X_train), np.array(y_train)
После этого наши данные готовы для ввода в нашу модель!
Наша Модель будет использовать следующую архитектуру:
# Building Model: model = tf.keras.models.Sequential() model.add(tf.keras.layers.LSTM(units=50, return_sequences=True, input_shape=(X_train.shape[1], 1))) model.add(tf.keras.layers.Dropout(0.2)) model.add(tf.keras.layers.LSTM(units=50, return_sequences=True)) model.add(tf.keras.layers.Dropout(0.2)) model.add(tf.keras.layers.LSTM(units=50, return_sequences=True)) model.add(tf.keras.layers.Dropout(0.2)) model.add(tf.keras.layers.LSTM(units=50)) model.add(tf.keras.layers.Dropout(0.2)) model.add(tf.keras.layers.Dense(units=1)) model.summary()
Мы используем слои Dropout, чтобы избежать проблем переобучения, и, кроме того, мы используем параметр return_sequences, чтобы определить, будет ли слой возвращать последовательность, совместимую с LSTM. Мы используем “return_sequences=True”, когда у нас есть слой LSTM после!
После сборки нашей модели мы хотим скомпилировать ее с помощью:
Теперь пришло время подогнать нашу модель!
modelo = model.fit(X_train, y_train, epochs=100, batch_size=32)
После обучения нашей модели мы можем построить график потери, чтобы визуализировать, насколько она хороша:
Составление прогнозов
Чтобы делать прогнозы, нам нужно использовать наш тестовый набор данных и отформатировать его, как мы делали это раньше в наборе данных поезда.
dataset_total = pd.concat([train_data[‘Open’], test_data[‘Open’]], axis=0) inputs = dataset_total[len(dataset_total) — len(test_data) — 60:].values inputs = inputs.reshape(-1,1) inputs = sc.transform(inputs) X_test = [] for i in range(60, 259): X_test.append(inputs[i-60:i, 0]) X_test = np.array(X_test) X_test = np.reshape(X_test, (X_test.shape[0], X_test.shape[1], 1))
После форматирования тестовых данных мы можем делать прогнозы в нашем X_test.
predicted_stock_price = model.predict(X_test)
Но перед построением наших прогнозов нам нужно сделать inverse_transform()в массиве прогнозов, потому что мы делаем прогнозы с использованием шкалы, поэтому наши прогнозы находятся в диапазоне от 0 до 1.
predicted_stock_price = model.predict(X_test)
Теперь пришло время построить прогнозы и посмотреть, как наша модель работает по сравнению с реальными ценами на акции.
Как видите, наша модель показала себя слишком хорошо!
Вы можете использовать тот же подход из этой статьи в любом прогнозировании цен, давайте делать деньги, детка!
Вы можете получить доступ к репозиторию этого сообщения в здесь.
На данный момент это все!
Увидимся в следующий раз!
Мои социальные сети:
Linkedin:https://www.linkedin.com/in/gabriel-mayer-779b5a162/
GitHub: https://github.com/gabrielmayers
Instagram: https://www.instagram.com/gabrielmayerl/
использованная литература
[1] Деррик Мвити, Данные и записная книжка для учебного пособия по прогнозированию цен на акции (2018), Github