Versuch, TensorFlow zu verwenden, um finanzielle Zeitreihendaten vorherzusagen

10

Ich bin neu in ML und TensorFlow (ich habe vor ungefähr ein paar Stunden angefangen) und ich versuche, damit die nächsten Datenpunkte in einer Zeitreihe vorherzusagen. Ich nehme meinen Input und mache das damit:

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

Ich dachte, ich würde x als Eingabedaten und y als gewünschte Ausgabe für diese Eingabe verwenden, so dass ich bei 0-6 1-7 (insbesondere die 7) erhalten könnte. Wenn ich jedoch mein Diagramm mit x als Eingabe ausführe , erhalte ich eine Vorhersage, die eher nach x als nach y aussieht .

Hier ist der Code (basierend auf diesem Beitrag und diesem Beitrag ):

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()

Das in der folgenden Grafik gezeigte Ergebnis ist eine Vorhersage, die auf x folgt , anstatt nach links verschoben zu werden (und die vorhergesagten Punkte auf der rechten Seite einzuschließen), wie es sein sollte, um y zu ähneln . Offensichtlich ist der Wunsch, dass die rote Linie so nah wie möglich an der blauen liegt.

Graph

Ich habe keine Ahnung, was ich mit all dem mache, also bitte ELI5.

Oh, auch meine Datenpunkte sind ziemlich kleine Zahlen (Größenordnung von 0,0001). Wenn ich sie nicht mit beispielsweise 1000000 multipliziere, sind die Ergebnisse so klein, dass die rote Linie am unteren Rand des Diagramms fast flach ist. Warum? Ich vermute, es liegt an der Quadratur in der Fitnessfunktion. Sollten Daten vor der Verwendung normalisiert werden, und wenn ja, wohin? 0-1? Wenn ich benutze:

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

Meine Vorhersage schwankt im Laufe der Zeit stärker: schwankend

Bearbeiten: Ich bin dumm und gebe nur ein Beispiel, von dem ich lernen kann, nicht 500, nicht wahr? Ich sollte also mehrere 500-Punkte-Proben geben, oder?

Isvara
quelle
Ich habe das gleiche Problem - nämlich dass der Ausgang des RNN dem Eingang (X) und nicht dem Ziel (Y) folgt. Seltsamerweise lernt die Eingabe in dieselbe RNN, wenn es sich um eine einfache Sinusreihe handelt, korrekt, dh sie sagt das Y voraus.
Ryszard Cetnarski
Bitte teilen Sie Ihre Datei dataset.csv
Ashwin Tomar

Antworten:

2

Ok, lass uns Teil für Teil gehen. Es gibt hier einige Bereiche, in denen Sie die Verzerrung in Ihrem Netzwerk nicht berücksichtigen.

Auswahl Ihrer Ein- und Ausgänge

Wenn der Vektor 0-6 bestimmt wird, besteht wirklich keine Notwendigkeit, 1-7 auszugeben. Die 1-6 ist bereits bekannt und das Hinzufügen zusätzlicher Ausgaben erhöht die Komplexität Ihres Modells. Sofern Sie nicht über erhebliche Datenmengen verfügen, möchten Sie Ihr Modell so einfach wie möglich halten, um eine gute Leistung zu erzielen. Somit würde ich ein einfaches Neuron mit einem kontinuierlichen Wert ausgeben. Sie können RMSE als Verlustfunktion mit einer Regressionsausgabe Ihres neuronalen Netzwerks verwenden.

Darüber hinaus sollten Sie die Samples, die Sie in Ihren Eingabebereich eingefügt haben, durch zusätzliche Informationen ergänzen, von denen Sie glauben, dass sie Informationen zur Trendlinie enthalten. Wenn ich zum Beispiel zwei verschiedene Produkte hätte, Bitcoin und Gold, und deren Eingabevektor der gleiche wäre, könnte ich erwarten, dass das Gold sehr wenig schwankt, das Bitcoin jedoch sehr stark schwankt.

Ihre Eingabefunktionen für Ihr Netzwerk enthalten alle Informationen, aus denen Ihr Netzwerk lernen wird. Daher möchten Sie sicherstellen, dass Sie genügend Informationen bereitstellen, um eine aussagekräftige Vorhersage zu erhalten.

Deep Learning ist datenhungrig

Sie benötigen mehr als 100.000 Instanzen. Jede Instanz besteht aus einer Reihe von Funktionen. Diese sollten unabhängig und so gezeichnet werden, dass sie identisch verteilt sind. Mit anderen Worten, Sie möchten mehrere Trendlinien aus einer unterschiedlichen Datenquelle erhalten, mit der Sie Ihr Netzwerk verwenden möchten, und dann ziehen Sie zufällig 0-6 Punkte, das sind Ihre Funktionen, und 7, die Ihre Bezeichnung sein werden.

Betrachten Sie die Datenverteilung, die Sie lernen möchten. Wenn Sie möchten, dass Ihr Netzwerk Katzen / Hunde klassifiziert, müssen Sie eine breite Palette unterschiedlich aussehender Katzen und Hunde angeben, damit das Netzwerk die Varianz identifizieren kann, die in diesen beiden Klassen besteht. Wenn Sie die Datenquelle zu stark einschränken, weist sie eine hohe Verzerrung auf und lässt sich nicht auf neuartige Daten verallgemeinern, die Sie später in die Datenquelle einspeisen.


Probieren Sie diese Dinge aus und lassen Sie uns wissen, was passiert.

JahKnows
quelle
2

Möglicherweise spiegelt die Vorhersage, die mit der Eingabe übereinstimmt, wider, dass Ihr Netzwerk nicht ausreichend trainiert ist. Das sogenannte Persistenzmodell für die Vorhersage von Zeitreihen wird häufig als Basis für andere Modelle verwendet. Das Persistenzmodell verwendet die letzte Beobachtung als Vorhersage. Es ist einfach und liefert oft eine angemessene Genauigkeit. Ich vermute, dass Ihr Netzwerk mit dem Erlernen des Persistenzmodells beginnt. Nur wenn Sie es besser trainieren und es möglich ist, ein besseres Modell zu erstellen, wird es es lernen - dies erfordert jedoch viel Training.

Ryszard Cetnarski
quelle