如何使用LSTM预测比特币的价格?分步指南

2021年11月28日05:24:10 发表评论 1,393 次浏览

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

如何使用LSTM预测比特币的价格?下面开始从最基本的谈起——

可以在此处找到本文的所有Python预测比特币价格示例代码 。


介绍性概念

什么是RNN?

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

什么是 LSTM?

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

LSTM单元
LSTM单元

数据探索

如何使用LSTM预测比特币的价格?在我们做任何事情之前,我们需要收集数据(我已经为你做过)并且我们需要了解数据。我们先用Python加载数据集,先看看:

data = pd.read_csv("data/bitcoin.csv")
data = data.sort_values('Date')
data.head()
比特币数据,来源:coinbase
比特币数据,来源:coinbase

Python预测比特币价格示例解析:该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月比特币价格
2014年12月至2020年6月比特币价格

还记得那些日子比特币将近 20k 吗?让我们不要分心,让我们看看我们的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() 在我们的数据帧上为我们提供了一些有用的信息,比如条目的数量和非空条目的数量,在我们的例子中是相同的,所以这里不需要做其他事情。


数据准备

正常化

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

对于我们而言,我们将使用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


Python如何预测比特币价格:构建模型

下一步是构建我们的模型架构。找到合适的模型是一门艺术,需要多次尝试和经验才能为每个模型找到合适的层和超参数。

Python预测比特币价格示例:我们不会深入到每一层的细节,有足够的复杂性来为每一层写一篇文章。但我要强调的是,我们在这里构建的模型对于这类问题来说是相当简单和非常标准的,至少在使用的层类型方面是这样。

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
_______________________________________________________________

训练模型

如何使用LSTM预测比特币的价格?现在我们已经准备好数据,并且编译了我们的模型,我们可以开始训练,使用 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()
训练和验证损失
训练和验证损失

我的结果可能并不理想,但对于我们的目的来说已经足够了。有一篇有趣的文章解释了你可以在此图表中直观地看到的一些问题,我建议你看一看:https://machinelearningmastery.com/diagnose-overfit-underfitting-lstm-models/


预测

Python如何预测比特币价格?现在训练好我们的模型后,我们可以开始进行一些预测并评估这些预测到我们的测试数据,以了解我们的模型表现如何:

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)
预测与实际比特币价格
Python预测比特币价格示例:预测与实际比特币价格

那个图表对我来说看起来很不错,对结果很满意,你觉得如何?


结论

如何使用LSTM预测比特币的价格?RNN 和 LSTM 是我们可以用来分析和预测时间序列信息的出色架构。在这篇文章中,我们更多地关注故事而不是实现的技术细节,但是如果你对该主题感兴趣,请进行研究,查看Python预测比特币价格示例代码 ,使用它,更改层,超参数,尝试不同的东西,使用不同的列,或规范化方法,阅读更详细的文章,以及关于该主题的论文。

木子山

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: