计算机系统应用教程网站

网站首页 > 技术文章 正文

用长期短期记忆(LSTM)预测以太坊价格模型

btikc 2024-10-15 08:54:37 技术文章 4 ℃ 0 评论

在本文中,我们将探索如何使用长期短期记忆(LSTM)网络来预测以太坊价格。通过将结果与支持向量机(SVM)获得的结果进行比较,我们将观察到,不需要特征工程,它们的预测比更传统的机器学习方法更精确。本文的重点不在于LSTM的理论方面,而在于它们的实际应用。我们将在Python中实现LSTM和SVM训练代码。

什么是LSTM网络?

LSTM是一种特殊的递归神经网络(RNN)。RNN是一种用于序列分析任务的神经网络。序列可以由不同种类的对象组成 - 例如视频图像,后续时间步中音频文件的特征或文本。当使用RNN时,我们考虑到这些序列的对象彼此依赖:如果您看到跳跃者的图像,您可能不知道此人是否正在向上或向下移动。当您看到由后续图像组成的视频时,您将能够立即观察到这一点。与其他神经网络体系结构不同,RNN能够坚持有关发生的事情的信息。

然而,vanilla RNN的一个缺点是他们似乎无法学习长期的依赖关系。想象一下,你想要预测文本作者的性别。一些文本可能会在开头提到作者的姓名,这可能是作者性别的最佳预测指标。尽管如此,在处理了全文后,RNN通常会忘记这样的信息。LSTM通过引入门控制哪些信息在输入序列的每个步骤中被遗忘,从而进一步将RNN带入一个级别,并能够更加可靠地处理这些情况。

有趣的是,LSTM网络在1997年提出,因此并不比1995年提出的SVM早得多,但像许多深度学习方法一样,它们自从近来才被大量使用。这个事实有以下几个原因:首先,深度学习方法通常依赖于大量的数据,在过去的二十年中,可用数据的数量一直在大幅增长。其次,他们往往需要更多的计算能力 - 另一个有大量改进的领域。最后,没有高度可用的深度学习框架,应用深度学习比现在更具挑战性。

使用Python预测以太坊(ETH)价格

任何机器学习项目中的第一步 - 也是最具挑战性的 - 是收集培训数据。在我们的案例中,幸运的是,poloniex提供了一个API,使我们能够以30分钟为间隔(甚至更小的间隔)获得美元的ETH价值。拥有这样细致的数据对于我们的目的非常有利,因为它使我们能够访问许多培训对象,而深度学习算法通常需要大量的培训数据才能很好地执行。

因此,我们现在可以开始机器学习中的典型工作流程:对数据进行预处理,将其分解为一些数据,用于评估我们的训练模型,进行训练,最后分析模型的性能。

预处理数据

在从poloniex API下载数据并将其保存到JSON文件后,我计算了后续收盘价的变化。这些变化的序列将成为我们LSTM的输入。这样,所有的训练序列将由相似范围内的双值组成。与直接使用收盘价格相比,这种方法的一个优势是,网络在用于预测时不太可能遵守之前从未见过的价值(因为ETH价格未来可能比今天高得多) 。在这样的情况下,机器学习模型通常表现得相当差。同样,对于LSTM要预测的值,我在输入序列结束时间之后的一小时内接受了ETH价格的变化。

with open("poloniex.json") as f:

data = json.load(f)

closing = [d["close"] for d in data]

zipped = zip(closing[0:-1], closing[1:])

changes = [d1 / d0 - 1 for d0, d1 in zipped]

length = 40

step = 3

sequences = []

results = []

for i in range(0, len(changes) - length - 2, step):

sequences.append(changes[i: i + length])

results.append(closing[i + length + 2] / closing[i] - 1)

sequences = [[[v] for v in sequence] for sequence in sequences]

从上面的代码可以看出,作为输入序列的长度,我选择了一个40的值 - 即LSTM将有任务观察以太坊价格的最后40个变化,并让他们预测下一个小时的变化。

分割训练数据

我选择保留最后30%的训练对象来评估LSTM的表现。通过使用比训练数据晚观察到的验证数据,我们避免了众所周知的look-ahead bias。

n_valid = int(0.3 * len(sequences))

x_train = np.array(sequences[:-n_valid])

y_train = np.array(results[:-n_valid])

x_valid = np.array(sequences[-n_valid:])

y_valid = np.array(results[-n_valid:])

设计和训练LSTM

如前所述,使用keras设计LSTM就像构建Lego模型一样简单,只需几行代码即可完成。我首先尝试了使用堆叠LSTM,但是由于我注意到这并未提高性能,因此我决定仅使用单个keras LSTM层,然后使用单个密度单元进行tanh激活。tanh激活层输出的值在[-1,1]的范围内,这非常适合我们的任务。

model = Sequential()

model.add(LSTM(32, input_shape=(length, 1), return_sequences=False))

#model.add(Dropout(0.4))

#model.add(LSTM(16))

model.add(Dense(1))

model.add(Activation('tanh'))

optimizer = RMSprop(lr=0.005, clipvalue=1.)

model.compile(loss='mean_absolute_error', optimizer=optimizer)

model.fit(x_train, y_train,

batch_size=32,

epochs=65,

validation_data=[x_valid, y_valid]

)

在网络优化器中使用梯度裁剪有助于消除梯度问题,这可以在相对经常使用LSTM时观察到。应该指出的是,上述没有梯度限幅模型的模型的训练性能是相似的,但这可能是由于上述体系结构比许多其他LSTM体系结构更简单。培训只花了几分钟在我的CPU上。

评估训练有素的LSTM

将保留数据与相应预测结果进行比较时的平均绝对误差约为0.015。这比在每个时间点预测训练数据中观察到的平均变化(0.007)的朴素模型的值要好得多 - 该模型的平均绝对误差为0.044。

训练支持向量机用于预测ETH价格

为了能够将LSTM的结果放入上下文中,我还训练了一个SVM来执行相同的任务。与LSTM不同,SVM没有明确地将输入解释为序列数据,这使其处于劣势。因此,在训练SVM时,我不得不将数据转换为大小为40的矢量,包括任何时间步长的最新价格变化。之后,我按照通常的方法使用网格搜索来优化SVM的参数。

parameters = [{'kernel': ['rbf'], 'gamma': [1e-2, 1e-3, 1e-4, 1e-5],

'C': [0.1, 1, 10, 100]}]

gs = GridSearchCV(SVR(), parameters, cv=5, verbose=5)

x_train_svm = [[x[0] for x in series] for series in x_train]

x_valid_svm = [[x[0] for x in series] for series in x_valid]

gs.fit(x_train_svm, y_train)

clf = gs.best_estimator_

predictions = clf.predict(x_valid_svm)

print(mean_absolute_error(y_valid, predictions))

SVM在保持数据上的平均绝对误差为0.021,优于朴素模型的误差,但似乎明显高于LSTM的误差。

我们可以看到,如果有足够的训练数据可用,LSTMs更适合于序列预测任务,而不是更传统的方法。而且,在使用keras时,构建LSTM体系结构的难度远不如人们所担心的那么大。

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表