Нейросеть для предсказания цены биткоина своими руками
Разбираем с небольшой проект для сбора и анализа данных из социальных сетей с целью предсказать поведение цены биткоина в реальном времени.
Код, о котором пойдет речь продолжает Youtube-видео об автоматическом прогнозировании цены на биткоин.
Проект позволяет предсказать цену криптовалюты и использует данные социальных сетей Reddit и Twitter для машинного обучения. Мы собираемся использовать технику, называемую анализом настроений, чтобы найти эмоции, стоящие за пользователями, и попытаться выяснить, коррелирует ли цена с тем, как люди относятся к популярной криптовалюте. Мы будем использовать API CoinDesk для извлечения данных о ценах биткоина и python для программирования приложения.
По словам автора, данная сборка готова к работе на платформе Google Cloud.
Сбор данных для оценки биткоина
Чтобы собирать данные для аналитики в фоновом режиме, необходимо запустить программы Continuous_Stream_Data.py и Continuous_Stream_Sentiment.py. Эти скрипты позволят осуществлять сбор и предварительную обработку входных данных, а после сохранять все в файлы live_tweet.csv и live_bitcoin.csv.
Ядро движка
Основой для обработки данных будет нейросеть, построенная по модели LSTM (Long short-term memory). Основные параметры (подключаемые модули, данные для соединения с базой данных и аккаунтом в Twilio) устанавливаются в файле engine.py.
Подключаемые пакеты, в том числе для создания и тренировки модели нейросети:
from math import sqrt from numpy import concatenate from matplotlib import pyplot import pandas as pd from datetime import datetime from sklearn.preprocessing import MinMaxScaler from sklearn.preprocessing import LabelEncoder from sklearn.metrics import mean_squared_error from keras.models import Sequential from keras.layers import Dense from keras.layers import LSTM import numpy as np import datetime from pytz import timezone est = timezone('US/Eastern')
Подключение аккаунта Twilio:
from twilio.rest import Client # ID аккаунта из twilio.com/console account_sid = "*******" # Токен из панели управления Twilio auth_token = "*******" client = Client(account_sid, auth_token)
Сервис Twillio предоставляет различные API, например, для обработки смс и голосовых сообщений. В данном случае он используется для аутентификации и отправки сообщений.
Дальше ядро загружает данные для тренировки сети и передает их экземпляру библиотеки Keras, на основе которой строится модель:
data = pd.read_csv("merged_data.csv") datag = data[['Price','Sentiment']].groupby(data['Time']).mean() from sklearn.preprocessing import MinMaxScaler values = datag['Price'].values.reshape(-1,1) sentiment = datag['Sentiment'].values.reshape(-1,1) values = values.astype('float32') sentiment = sentiment.astype('float32') scaler = MinMaxScaler(feature_range=(0, 1)) scaled = scaler.fit_transform(values) train_size = int(len(scaled) * 0.7) test_size = len(scaled) - train_size train, test = scaled[0:train_size,:], scaled[train_size:len(scaled),:] print(len(train), len(test)) split = train_size def create_dataset(dataset, look_back, sentiment, sent=False): dataX, dataY = [], [] for i in range(len(dataset) - look_back): if i >= look_back: a = dataset[i-look_back:i+1, 0] a = a.tolist() if(sent==True): a.append(sentiment[i].tolist()[0]) dataX.append(a) dataY.append(dataset[i + look_back, 0]) #print(len(dataY)) return np.array(dataX), np.array(dataY) look_back = 2 trainX, trainY = create_dataset(train, look_back, sentiment[0:train_size],sent=True) testX, testY = create_dataset(test, look_back, sentiment[train_size:len(scaled)], sent=True) trainX = np.reshape(trainX, (trainX.shape[0], 1, trainX.shape[1])) testX = np.reshape(testX, (testX.shape[0], 1, testX.shape[1])) model = Sequential() model.add(LSTM(100, input_shape=(trainX.shape[1], trainX.shape[2]), return_sequences=True)) model.add(LSTM(100)) model.add(Dense(1)) model.compile(loss='mae', optimizer='adam') history = model.fit(trainX, trainY, epochs=300, batch_size=100, validation_data=(testX, testY), verbose=0, shuffle=False) yhat = model.predict(testX) yhat_inverse_sent = scaler.inverse_transform(yhat.reshape(-1, 1)) testY_inverse_sent = scaler.inverse_transform(testY.reshape(-1, 1)) rmse_sent = sqrt(mean_squared_error(testY_inverse_sent, yhat_inverse_sent)) print('Test RMSE: %.3f' % rmse_sent)
Подключение базы данных:
import MySQLdb #Enter the values for you database connection dsn_database = "bitcoin" # название базы данных dsn_hostname = "173.194.231.244" # имя хоста, напрмер localhost dsn_port = 3306 # порт хоста dsn_uid = "demo" # имя пользователя БД dsn_pwd = "qwerty@123" # пароль от базы данных conn = MySQLdb.connect(host=dsn_hostname, port=dsn_port, user=dsn_uid, passwd=dsn_pwd, db=dsn_database) cursor=conn.cursor()
Ядро обрабатывает данные базы и csv-файлов для подготовки статистики и расчета советов:
import queue import time import queue import matplotlib.pyplot as plt true_q = queue.Queue() pred_q = queue.Queue() ''' fig = plt.figure() ax = fig.add_subplot(111) fig.show() fig.canvas.draw() plt.ion() ''' def process_data(in_data): out_data = [] for line in in_data: out_data.append(float(line.split(',')[0])) return np.array(out_data).reshape(-1,1) prev = 15000 threshold = 0.05 while True: btc = open('live_bitcoin.csv','r') sent = open('live_tweet.csv','r') bit_data = btc.readlines() sent_data = sent.readlines() bit_data = process_data(bit_data[len(bit_data)-5:]) sent_data = process_data(sent_data[len(sent_data)-5:]) live = scaler.transform(bit_data) testX, testY = create_dataset(live, 2, sent_data, sent=True) testX = np.reshape(testX, (testX.shape[0], 1, testX.shape[1])) yhat = model.predict(testX) yhat_inverse = scaler.inverse_transform(yhat.reshape(-1, 1)) true_q.put(bit_data[4]) pred_q.put(yhat_inverse[0]) val = 100*((yhat_inverse[0][0] - prev)/prev)
Если текущее значение оказывается больше или меньше порогового, сформируется соответствующее сообщение:
if val > threshold: decision = 'Buy!!!' message = client.messages.create(to="+15184234418", from_="+15188883052", body=decision+' - Price of Bitcoin is expected to rise.') elif val <-threshold: decision = 'Sell!!!' message = client.messages.create(to="+15184234418", from_="+15188883052", body=decision+' - Price of Bitcoin is expected to drop.') else: decision = ''
Данные о решении записываются в базу:
prev = yhat_inverse[0][0] input_string = "INSERT INTO live_data values ({},{},{},'{}', '{}');".format(yhat_inverse[0][0],bit_data[0][0],sent_data[4][0], datetime.datetime.now(tz=est).strftime('%Y-%m-%d %H:%M:%S'),decision) cursor.execute(input_string) conn.commit() time.sleep(60)
Здесь можно посмотреть код ядра целиком.
Пример содержания live_bitcoin:
15078.2,12753300000.0,252259597803,16730087.0,16730087.0,-1.7,-6.13,35.79,14579.62,14598.6, 14589.11,17-12-09-15-25 15078.2,12753300000.0,252259597803,16730087.0,16730087.0,-1.7,-6.13,35.79,14579.62,14598.6, 14589.11,17-12-09-15-26 15078.2,12753300000.0,252259597803,16730087.0,16730087.0,-1.7,-6.13,35.79,14599.06,14608.1, 14603.58,17-12-09-15-26 15078.2,12753300000.0,252259597803,16730087.0,16730087.0,-1.7,-6.13,35.79,14579.62,14598.6, 14589.11,17-12-09-15-26
И live_tweet:
0.0475357211354,17-12-12-21-35 0.0471845801768,17-12-12-21-36 0.0471845801768,17-12-12-21-37 0.0471845801768,17-12-12-21-38
Нейросеть выдает значение будущей цены биткоина с временной меткой. Вычисления делаются на основе порогового значения, установленного в коде движка. Полученная информация о времени, предсказанной и текущей цене, а также рекомендуемом действии (покупка/продажа) записывается в MySQL базу данных.
Автор отмечает, что поскольку модель вышла перегруженной (она хорошо работает с обучающей выборкой, но не очень – с тестовыми данными), не стоит рассматривать ее как инструмент для помощи в торговле. Однако этот код остается хорошим пособием по применению нейросетей и может помочь в изучении их работы.
Вас также могут заинтересовать другие статьи по теме:
- Реализуем свой Bitcoin на языке программирования Python
- Что такое Биткоин и разбираемся, как он работает
- Нейронная сеть на Python в 15 строк кода для диагностики диабета