Tentativo di utilizzare TensorFlow per prevedere i dati finanziari delle serie temporali


10

Sono nuovo di ML e TensorFlow (ho iniziato circa poche ore fa) e sto provando a usarlo per prevedere i prossimi punti dati in una serie temporale. Prendo il mio contributo e lo faccio con esso:

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

Quello che pensavo di fare è usare x come dati di input e y come output desiderato per quell'input, in modo che dato 0-6 potrei ottenere 1-7 (il 7 in particolare). Tuttavia, quando eseguo il mio grafico con x come input, ciò che ottengo è una previsione che assomiglia più a x che a y .

Ecco il codice (basato su questo post e questo post ):

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

Il risultato mostrato nel grafico seguente è una previsione che segue x , anziché essere spostata a sinistra (e includendo i punti previsti a destra) come dovrebbe essere simile a y . Ovviamente il desiderio è che la linea rossa sia il più vicino possibile a quella blu.

grafico

Non ho idea di cosa sto facendo con tutto questo, quindi per favore ELI5.

Oh, anche, i miei punti dati sono numeri abbastanza piccoli (ordine di 0,0001). Se non li moltiplico per, diciamo, per 1000000, i risultati sono così piccoli che la linea rossa è quasi piatta nella parte inferiore del grafico. Perché? Immagino sia a causa della quadratura nella funzione fitness. I dati dovrebbero essere normalizzati prima dell'uso e, in caso affermativo, a cosa? 0-1? Se uso:

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

la mia previsione fluttua più selvaggiamente man mano che procede: fluttuante

Modifica: sono stupido e gli do solo un esempio da cui imparare, non 500, no? Quindi dovrei dargli più campioni da 500 punti, giusto?


Ho lo stesso problema, ovvero che l'uscita dell'RNN segue l'input (X) e non l'obiettivo (Y). Stranamente quando l'ingresso allo stesso RNN è una semplice serie sinusoidale, apprende correttamente, ovvero predice Y.
Ryszard Cetnarski,

Si prega di condividere il file dataset.csv
Ashwin Tomar,

Risposte:


2

Ok andiamo parte per parte. Ci sono alcune parti qui in cui non si prende in considerazione la distorsione nella propria rete.

Scegli i tuoi input e output

Se viene determinato il vettore 0-6, non è necessario emettere 1-7. L'1-6 è già noto e l'aggiunta di output aggiuntivi aggiungerà solo complessità al modello. A meno che non si disponga di notevoli quantità di dati, si desidera mantenere il modello il più semplice possibile al fine di ottenere buone prestazioni. Quindi, avrei prodotto un neurone semplice con un valore continuo. È possibile utilizzare RMSE come funzione di perdita con un output di regressione dalla rete neurale.

Inoltre, è necessario integrare i campioni inseriti nello spazio di input con alcune informazioni aggiuntive che si ritiene possano contenere informazioni sulla linea di tendenza. Ad esempio, se avessi 2 prodotti diversi, bitcoin e oro, e il loro vettore di input fosse lo stesso, potrei aspettarmi che l'oro abbia una fluttuazione molto piccola ma che il bitcoin abbia una fluttuazione molto alta.

Le funzioni di input per la tua rete contengono tutte le informazioni da cui la tua rete imparerà. Pertanto, si desidera assicurarsi di fornire informazioni sufficienti per avere una previsione significativa.

L'apprendimento profondo ha fame di dati

Avrai bisogno di circa 100.000 casi. Ogni istanza è un insieme di funzionalità. Questi dovrebbero essere disegnati indipendentemente e in modo tale che siano distribuiti in modo identico. In altre parole, vuoi ottenere più linee di tendenza da una diversa fonte di dati con cui desideri utilizzare la tua rete e quindi disegnerai casualmente 0-6 punti, cioè le tue caratteristiche, e 7 che saranno la tua etichetta.

Considera la distribuzione dei dati che stai cercando di imparare. Se si desidera che la propria rete classifichi cani / gatti, è necessario fornire un'ampia gamma di cani e gatti di aspetto diverso in modo tale che la rete possa identificare la varianza esistente in entrambe queste classi. Se si restringe troppo l'origine dei dati, si avrà un'inclinazione elevata e non si generalizzerà a nuovi dati che verranno successivamente inseriti in esso.


Prova queste cose e facci sapere cosa succede.


2

Forse la previsione essendo la stessa dell'input riflette che la tua rete non è adeguatamente addestrata. Il cosiddetto modello di persistenza per la previsione di serie storiche, viene spesso utilizzato come base per altri modelli. Il modello di persistenza sta usando l'ultima osservazione come previsione. È semplice e spesso fornisce una precisione ragionevole. La mia ipotesi è che la tua rete inizi imparando il modello di persistenza, e solo se ti alleni di più ed è possibile creare un modello migliore, lo imparerà - ma questo richiede molta formazione.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.