LSTM预测比特币价格

  |   0 评论   |   0 浏览   |   给我丶鼓励

今天,我们将讨论如何通过分析过去 6 年的定价信息来预测比特币的价格。请注意,我们已经确定我们的分析将仅关注定价信息,而撇开任何可能影响比特币价格的因素,例如新闻,它可以起非常重要的作用。出于这个原因,我说这篇文章和相关项目仅用于教育目的,不应在生产中使用。这是一个过于简单的模型,将帮助我们解释和理解使用 Python 和递归神经网络(RNN)进行的时间序列预测,更准确地说,我们将建立一个 LSTM(长期记忆)模型。


入门概念

什么是 RNN?

循环神经网络(RNN) 是一类神经网络,其中节点之间的连接形成沿着时间序列的有向图的。这使其能够表现出时间动态行为,使其非常适合时间序列分析,语音识别,语法学习,文字构成等。

什么是 LSTM?

**长期记忆(LSTM)**是一种 RNN,它使我们不仅可以处理单个数据点(例如图像),还可以处理整个数据序列(例如语音或视频)。它们是时间序列预测的理想选择,它们是我们今天将要使用的架构类型。

LSTM 电池


数据探索

在做任何事情之前,我们需要收集数据(我已经为您做过)并且我们需要了解数据。让我们首先使用 Python 加载数据集,并进行初步了解:

data = pd.read_csv("data/bitcoin.csv")
data = data.sort_values('Date')
data.head()

比特币数据,来源:coinbase

head() 功能已经为我们提供了有关数据集的列以及这些信息的外观的一些有价值的信息。出于我们的目的,我们对该 Close 列感兴趣,该列包含该特定日期当天结束时的比特币价格。让我们看看是否可以使用我们的数据集构建一个图表,向我们显示比特币随时间的价格。

price = data[['Close']]

plt.figure(figsize = (15,9))
plt.plot(price)
plt.xticks(range(0, data.shape[0],50), data['Date'].loc[::50],rotation=45)
plt.title("Bitcoin Price",fontsize=18, fontweight='bold')
plt.xlabel('Date',fontsize=18)
plt.ylabel('Close Price (USD)',fontsize=18)
plt.show()

2014 年 12 月至 2020 年 6 月的比特币价格

还记得那些日子比特币将近 2 万吗?让我们不要分心,让我们看看我们的 Close 信息是否包含任何空值,空值对我们没有用,如果有空值我们应该加以解决。

price.info()
<class 'pandas.core.frame.DataFrame'>
Int64Index: 2001 entries, 2000 to 0
Data columns (total 1 columns):
 #   Column  Non-Null Count  Dtype  
---  ------  --------------  -----  
 0   Close   2001 non-null   float64
dtypes: float64(1)
memory usage: 31.3 KB

在数据框上使用简单的。info()可为我们提供一些有用的信息,例如条目数和非 null 条目数(在我们的情况下是相同的),因此在此无需进行其他操作。


资料准备

正常化

我们要对数据进行的第一步是将其值标准化。规范化的目标是将数据集中的数字列的值更改为通用标度,而不会扭曲值范围内的差异。

对于我们而言,我们将使用 MinMaxScaler 来自 sklearn

from sklearn.preprocessing import MinMaxScaler
min_max_scaler = MinMaxScaler()

norm_data = min_max_scaler.fit_transform(price.values)

让我们尝试在标准化前后比较我们的值:

Real: [370.], Normalized: [0.01280082]
Real: [426.1], Normalized: [0.01567332]
Real: [8259.99], Normalized: [0.41679416]

数据分割

在此步骤中,我们将实际解决 2 个问题,首先是我们需要将数据集分为训练数据和测试数据。我们将使用训练数据来教我们的模型,而测试数据将被用作比较我们的预测的基准。这一点非常重要,因为我们要确保我们的预测是合理的,但是由于我们可能会面临过度拟合的风险,因此我们无法对训练网络的相同数据进行测试。

此外,我们还将在此为 LSTM 网络准备数据。这种特殊类型的网络要求我们以数据块的形式发送时间序列,将我们将用于训练的“历史”数据与“目标”分开,“历史”数据表明模型在未来需要学习预测的时间。

第二部分的责任将是我们的 univariate_data 职能:

def univariate_data(dataset, start_index, end_index, history_size, target_size):
  data = []
  labels = []

  start_index = start_index + history_size
  if end_index is None:
    end_index = len(dataset) - target_size

  for i in range(start_index, end_index):
    indices = range(i-history_size, i)
    # Reshape data from (history_size,) to (history_size, 1)
    data.append(np.reshape(dataset[indices], (history_size, 1)))
    labels.append(dataset[i+target_size])
  return np.array(data), np.array(labels)

拆分将在这里发生:

past_history = 5
future_target = 0

TRAIN_SPLIT = int(len(norm_data) * 0.8)


x_train, y_train = univariate_data(norm_data,
                                   0,
                                   TRAIN_SPLIT,
                                   past_history,
                                   future_target)

x_test, y_test = univariate_data(norm_data,
                                 TRAIN_SPLIT,
                                 None,
                                 past_history,
                                 future_target)

通过使用 past_history,我们告诉网络,我们需要使用 5 天的数据来学习预测时间序列中的下一个点 future_target


建立模型

下一步是构建我们的模型架构。找到正确的模型是一门艺术,要花很多时间再加上经验才能为每个模型找到正确的层和超参数。

我们不会在每层上都进行详细介绍,因为有足够的复杂性来为每层写一个帖子。但我要强调的是,我们在此构建的模型对于此类问题至少在所使用的层类型方面非常简单且相当标准。

from keras.models import Sequential
from keras.optimizers import Adam
from keras.layers import Dense, LSTM, LeakyReLU, Dropout

num_units = 64
learning_rate = 0.0001
activation_function = 'sigmoid'
adam = Adam(lr=learning_rate)
loss_function = 'mse'
batch_size = 5
num_epochs = 50

# Initialize the RNN
model = Sequential()
model.add(LSTM(units = num_units, activation=activation_function, input_shape=(None, 1)))
model.add(LeakyReLU(alpha=0.5))
model.add(Dropout(0.1))
model.add(Dense(units = 1))

# Compiling the RNN
model.compile(optimizer=adam, loss=loss_function)

让我们看看我们的架构是什么样的:

Model: "sequential_13"
_______________________________________________________________
Layer (type)                 Output Shape              Param #   
===============================================================
lstm_6 (LSTM)                (None, 64)                16896     
_______________________________________________________________
leaky_re_lu_4 (LeakyReLU)    (None, 64)                0         
_______________________________________________________________
dropout_4 (Dropout)          (None, 64)                0         
_______________________________________________________________
dense_6 (Dense)              (None, 1)                 65        
===============================================================
Total params: 16,961
Trainable params: 16,961
Non-trainable params: 0
_______________________________________________________________

训练模型

现在我们已经准备好数据并编译了模型,我们可以开始训练,而使用 Keras 只需一行代码即可:

# Using the training set to train the model
history = model.fit(
    x_train,
    y_train,
    validation_split=0.1,
    batch_size=batch_size,
    epochs=num_epochs,
    shuffle=False
)

在这里找到正确的超参数也是本领域的一部分,但是,将参数 shuffle 设置为至关重要 False。我们的分析完全取决于信息的顺序,如果我们改变顺序,我们的结果将毫无意义。

即使没有 GPU,也可以对这种模型进行培训,数据量非常低,并且网络体系结构非常简单。在更高级的模型上,并且具有更详尽的信息,这些模型可能需要数小时或数天的时间进行训练。

完成培训后,重要的是我们评估培训的结果,我们做得好吗?我们的训练损失和验证损失函数是什么样的?如果某些事情看起来不正确,那么您可能需要回到前面的步骤并使用超参数,甚至可能修改模型架构。

这是一个不错的图表,可用于比较两个功能:

loss = history.history['loss']
val_loss = history.history['val_loss']

epochs = range(len(loss))

plt.figure()

plt.plot(epochs, loss, 'b', label='Training loss')
plt.plot(epochs, val_loss, 'r', label='Validation loss')
plt.title("Training and Validation Loss")
plt.legend()

plt.show()


预测

训练好我们的模型之后,我们可以开始进行一些预测并将这些预测评估到我们的测试数据中,以查看我们的模型做得如何:

original = pd.DataFrame(min_max_scaler.inverse_transform(y_test))
predictions = pd.DataFrame(min_max_scaler.inverse_transform(model.predict(x_test)))

ax = sns.lineplot(x=original.index, y=original[0], label="Test Data", color='royalblue')
ax = sns.lineplot(x=predictions.index, y=predictions[0], label="Prediction", color='tomato')
ax.set_title('Bitcoin price', size = 14, fontweight='bold')
ax.set_xlabel("Days", size = 14)
ax.set_ylabel("Cost (USD)", size = 14)
ax.set_xticklabels('', size=10)

预测与实际比特币价格

该图表对我来说看起来不错,对结果非常满意,您认为呢?


结论

RNN 和 LSTM 是伟大的架构,我们可以用来分析和预测时间序列信息。在本文中,我们将重点更多地放在故事上,而不是实现的技术细节上,但是,如果您对该主题感兴趣,请进行研究,检查代码,使用它,更改层,超参数,尝试不同的事物,使用不同的专栏或规范化方法,阅读更详细的文章以及有关该主题的论文。


标题:LSTM预测比特币价格
作者:给我丶鼓励
地址:https://blog.doiduoyi.com/articles/1591800295915.html

评论

发表评论