Спроба використовувати 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

Будь ласка, поділіться вашим файлом CCD.csv
Томар

Відповіді:


2

Гаразд, підемо по частинах. Тут є досить багато частин, де ви не враховуєте упередженість вашої мережі.

Вибір входів та результатів

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

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

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

Глибоке навчання - це голодні дані

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

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


Спробуйте ці речі та дайте нам знати, що відбувається.


2

Можливо, прогноз збігається з входом, що відображає, що ваша мережа недостатньо підготовлена. Так звана модель стійкості для прогнозування часових рядів часто використовується базовою лінією для інших моделей. Модель стійкості використовує останнє спостереження як прогнозування. Це просто і часто дає розумну точність. Я здогадуюсь, що ваша мережа починається з вивчення моделі стійкості, і лише якщо ви навчите її більше і можна зробити кращу модель, вона навчиться їй - але для цього потрібна велика підготовка.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.