Попытка использовать 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.
Ryszard Cetnarski
Пожалуйста, поделитесь своим файлом dataset.csv
Томар

Ответы:

2

Хорошо, давайте идти по частям. Здесь довольно много частей, где вы не учитываете смещение в вашей сети.

Выбор вашего входа и выхода

Если определяется вектор 0-6, на самом деле нет необходимости выводить 1-7. 1-6 уже известен, и добавление дополнительных выходных данных только усложнит вашу модель. Если у вас нет значительных объемов данных, вы хотите сохранить свою модель как можно более простой, чтобы получить хорошую производительность. Таким образом, я бы вывел простой нейрон с непрерывным значением. Вы можете использовать RMSE в качестве функции потерь с выходом регрессии из вашей нейронной сети.

Кроме того, вы должны дополнить образцы, которые вы поместили в свое поле ввода, дополнительной информацией, которая, по вашему мнению, будет содержать информацию о линии тренда. Например, если бы у меня было 2 разных продукта, биткойн и золото, а их входной вектор был одинаковым, я мог бы ожидать, что золото будет иметь очень небольшие колебания, но биткойны будут иметь очень высокие колебания.

Ваши функции ввода в вашу сеть содержат всю информацию, из которой ваша сеть будет учиться. Таким образом, вы хотите убедиться, что вы предоставляете достаточно информации, чтобы иметь осмысленный прогноз.

Глубокое обучение требует данных

Вам понадобится около 100 000+ экземпляров. Каждый экземпляр представляет собой набор функций. Они должны быть нарисованы независимо и так, чтобы они были одинаково распределены. Другими словами, вы хотите получить несколько линий тренда из разнообразного источника данных, с которым вы хотите использовать свою сеть, и затем вы будете случайным образом рисовать 0-6 точек, то есть ваши особенности, и 7, которые будут вашим ярлыком.

Рассмотрим распределение данных, которое вы пытаетесь изучить. Если вы хотите, чтобы ваша сеть классифицировала кошек / собак, вам нужно предоставить широкий спектр кошек и собак разного вида, чтобы сеть могла идентифицировать различия, которые существуют в обоих этих классах. Если вы слишком сильно ограничите источник данных, он будет иметь большую предвзятость и не будет обобщаться на новые данные, которые вы позже будете вводить в него.


Попробуйте эти вещи и дайте нам знать, что происходит.

JahKnows
источник
2

Возможно, прогноз, совпадающий с входным, отражает, что ваша сеть недостаточно подготовлена. Так называемая модель постоянства для прогнозирования временных рядов, часто используется в качестве основы для других моделей. Модель постоянства использует последнее наблюдение в качестве прогноза. Это просто и часто дает разумную точность. Я предполагаю, что ваша сеть начинается с изучения модели постоянства, и только если вы обучите ее больше и можно будет создать лучшую модель, она изучит ее, но это требует большого обучения.

Рышард Цетнарски
источник