16313

Нейросеть для предсказания цены биткоина своими руками

Разбираем с небольшой проект для сбора и анализа данных из социальных сетей с целью предсказать поведение цены биткоина в реальном времени.

Код, о котором пойдет речь продолжает 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 базу данных.

Автор отмечает, что поскольку модель вышла перегруженной (она хорошо работает с обучающей выборкой, но не очень – с тестовыми данными), не стоит рассматривать ее как инструмент для помощи в торговле. Однако этот код остается хорошим пособием по применению нейросетей и может помочь в изучении их работы.

Вас также могут заинтересовать другие статьи по теме:

РУБРИКИ В СТАТЬЕ

Комментарии

BUG
LIVE