尝试使用TensorFlow预测财务时间序列数据


10

我是ML和TensorFlow的新手(大约几个小时前开始),我正尝试使用它来预测时间序列中的下几个数据点。我正在接受输入,并使用它来执行此操作:

/----------- x ------------\
.-------------------------------.
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
'-------------------------------'
     \----------- y ------------/

我以为我在做的是将x用作输入数据,将y用作该输入的期望输出,因此,给定0-6时,我可以得到1-7(尤其是7)。但是,当我使用x作为输入运行图时,得到的预测看起来更像x而不是y

这是代码(基于本文本文):

import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plot
import pandas as pd
import csv

def load_data_points(filename):
    print("Opening CSV file")
    with open(filename) as csvfile:
        print("Creating CSV reader")
        reader = csv.reader(csvfile)
        print("Reading CSV")
        return [[[float(p)] for p in row] for row in reader]

flatten = lambda l: [item for sublist in l for item in sublist]

data_points = load_data_points('dataset.csv')

print("Loaded")

prediction_size = 10
num_test_rows = 1
num_data_rows = len(data_points) - num_test_rows
row_size = len(data_points[0]) - prediction_size

# Training data
data_rows = data_points[:-num_test_rows]
x_data_points = np.array([row[:-prediction_size] for row in data_rows]).reshape([-1, row_size, 1])
y_data_points = np.array([row[prediction_size:] for row in data_rows]).reshape([-1, row_size, 1])

# Test data
test_rows = data_points[-num_test_rows:]
x_test_points = np.array([[data_points[0][:-prediction_size]]]).reshape([-1, row_size, 1])
y_test_points = np.array([[data_points[0][prediction_size:]]]).reshape([-1, row_size, 1])

tf.reset_default_graph()

num_hidden = 100

x = tf.placeholder(tf.float32, [None, row_size, 1])
y = tf.placeholder(tf.float32, [None, row_size, 1])

basic_cell = tf.contrib.rnn.BasicRNNCell(num_units=num_hidden, activation=tf.nn.relu)
rnn_outputs, _ = tf.nn.dynamic_rnn(basic_cell, x, dtype=tf.float32)

learning_rate = 0.001

stacked_rnn_outputs = tf.reshape(rnn_outputs, [-1, num_hidden])
stacked_outputs = tf.layers.dense(stacked_rnn_outputs, 1)
outputs = tf.reshape(stacked_outputs, [-1, row_size, 1])

loss = tf.reduce_sum(tf.square(outputs - y))
optimizer = tf.train.AdamOptimizer(learning_rate)
training_op = optimizer.minimize(loss)

init = tf.global_variables_initializer()

iterations = 1000

with tf.Session() as sess:
    init.run()
    for ep in range(iterations):
        sess.run(training_op, feed_dict={x: x_data_points, y: y_data_points})
        if ep % 100 == 0:
            mse = loss.eval(feed_dict={x: x_data_points, y: y_data_points})
            print(ep, "\tMSE:", mse)

    y_pred = sess.run(stacked_outputs, feed_dict={x: x_test_points})

    plot.rcParams["figure.figsize"] = (20, 10)

    plot.title("Actual vs Predicted")
    plot.plot(pd.Series(np.ravel(x_test_points)), 'g:', markersize=2, label="X")
    plot.plot(pd.Series(np.ravel(y_test_points)), 'b--', markersize=2, label="Y")
    plot.plot(pd.Series(np.ravel(y_pred)), 'r-', markersize=2, label="Predicted")
    plot.legend(loc='upper left')
    plot.xlabel("Time periods")
    plot.tick_params(
        axis='y',
        which='both',
        left='off',
        right='off',
        labelleft='off')
    plot.show()

下图中显示的结果是跟随x的预测,而不是像y那样向左移动(并包括右边的预测点)。显然,人们希望红线尽可能接近蓝线。

图形

我不知道我在做什么,所以请ELI5。

哦,我的数据点也很小(0.0001的量级)。如果我不乘以1000000,则结果是如此之小,以至于红线几乎位于图表底部。为什么?我猜这是因为健身函数中的平方。数据在使用前是否应该标准化?0-1?如果我使用:

normalized_points = [(p - min_point) / (max_point - min_point) for p in data_points]

我的预测随着进展而更加剧烈地波动: 波动的

编辑:我很愚蠢,只给一个例子供学习,而不是500,不是吗?所以我应该给它多个500点样本,对吗?


我有同样的问题-即RNN的输出跟随输入(X)而不是目标(Y)。奇怪的是,当输入相同的RNN是它正确地学习一个简单的正弦系列,即预测Y.
雷沙德雷Cetnarski

请分享您的dataset.csv文件
Ashwin Tomar,

Answers:


2

好吧,让我们一起去吧。这里有很多地方没有考虑网络中的偏差。

选择输入和输出

如果确定矢量0-6,则实际上不需要输出1-7。1-6是已知的,添加其他输出只会增加模型的复杂性。除非您有大量数据,否则您要保持模型尽可能简单以获取良好的性能。因此,我将输出具有连续值的简单神经元。您可以通过神经网络的回归输出将RMSE用作损失函数。

此外,您应该使用一些可能会包含有关趋势线的信息的补充信息来补充放入输入空间的样本。例如,如果我有两种不同的产品,比特币和黄金,并且它们的输入向量相同,那么我可能期望黄金的波动很小,但比特币的波动很大。

您对网络的输入功能包含网络将学习的所有信息。因此,您要确保提供足够的信息以进行有意义的预测。

深度学习需要大量数据

您将需要大约100,000+个实例。每个实例都是一组功能。这些应独立绘制,并使其分布相同。换句话说,您希望从希望与网络一起使用的各种数据源中获取多个趋势线,然后您将随机绘制0-6点(即要素)和7(点)作为标签。

考虑您要学习的数据分布。如果您希望网络对猫/狗进行分类,则需要给出各种外观各异的猫和狗,以便网络可以识别这两种类别中都存在的差异。如果对数据源的限制过多,它将具有较高的偏差,并且不会推广到以后将提供给它的新颖​​数据。


试试这些,让我们知道会发生什么。


2

预测与输入相同可能反映出您的网络训练不足。所谓的用于时间序列预测的持久性模型通常用于其他模型的基线。持续性模型使用最后的观察作为预测。它很简单,通常会产生合理的精度。我的猜测是,您的网络始于学习持久性模型,只有对它进行更多的培训,并且有可能创建一个更好的模型,它才能学习它-但这需要大量的培训。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.