1 votos

LSTM para predicción de tendencias

He estado deseando ensuciarme las manos con ML desde hace un tiempo y como también me interesa las finanzas y el comercio, pensé que este sería un buen proyecto para comenzar después de leer Deep LSTM with Reinforcement Learning Layer for Financial Trend Prediction in FX High Frequency Trading Systems (https://www.mdpi.com/2076-3417/9/20/4460/htm) de Francesco Rundo.

Estoy trabajando en el primer paso, una LSTM con 3 series temporales como entrada y una salida categórica (0, 1, 2).

Después de trabajar en ello todo el día, logré hacer algo que funcione, pero con mis resultados estando lejos de lo que aparentemente logra el modelo de Francesco (43% vs 70%), no estoy realmente seguro si es simplemente cuestión de agregar más datos de entrenamiento y tiempo, o si cometí un error básico por ser nuevo en ML en general.

def create_model():
  model = Sequential()
  model.add(LSTM(NÚMERO_DE_CELDAS_OCULTAS, input_shape=(100, 3), return_sequences=True))
  model.add(LSTM(NÚMERO_DE_CELDAS_OCULTAS, input_shape=(100, 3)))
  model.add(Dense(3, activation=activations.softmax))
  return model

NÚMERO_DE_CELDAS_OCULTAS = 300
ÉPOCAS = 10

class_weights = class_weight.compute_class_weight('balanced', np.unique(y_train), y_train)
y_train = to_categorical(y_train)
y_TEST = to_categorical(y_TEST)

model = create_model()
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['categorical_accuracy'])

model.fit(x_train, y_train, class_weight=class_weights, epochs=ÉPOCAS, verbose=1)

¿Son optimizador, pérdida y métricas las elecciones correctas para 3 salidas categóricas?
¿Hay algo más obvio que hice mal?

0 votos

Resulta que obtienes exactamente un 70% si nunca miras la matriz de confusión y permites que tu red siempre prediga con un umbral de cambio de precio del 0,1%... ¯_()_/¯

0 votos

¿Lograste alcanzar un porcentaje de victorias más alto como se menciona en el artículo? He estado tratando de colaborar con desarrolladores para crear este modelo. ¿Te gustaría conectar?

0 votos

¿Cuál es la función objetivo que estás entrenando al modelo para intentar optimizar hacia ella?

6voto

Shocker Puntos 851

Lo primero que puedes hacer para ayudar a que una red neuronal aprenda más rápidamente es normalizar todas las entradas entre 0 y 1. La librería sklearn tiene una función preprocess.scale() que hace precisamente eso: asegúrate de hacerlo por separado para los datos de entrenamiento y prueba (o datos de entrenamiento, validación y prueba si utilizas tres conjuntos separados). Esto solo puede marcar una gran diferencia. Vi un tutorial de aprendizaje profundo por refuerzo donde aceleró enormemente el aprendizaje. Solo para estar seguro, tensorflow.keras.layers tiene una función BatchNormalization() que puedes añadir entre cada capa LSTM como

model.add( BatchNormalization() )

Otro detalle muy importante aquí es que nunca introdujiste capas de dropout entre tus capas. Está diseñado esencialmente para deshacerse aleatoriamente de cierta información y típicamente se usa en todo tipo de redes recurrentes. Como predeterminado, podrías añadirlo entre cada capa con un ratio de dropout del 20%:

model.add( Dropout(0.2) )

Esto también se puede encontrar en el módulo de capas de tensorflow.keras. Una última cosa es que la gente rutinariamente apila al menos una capa densa encima de las capas LSTM antes de introducir la capa de salida. Cook and Hall (2015) en la Reserva Federal descubrieron que funcionaba bien en datos macroeconómicos y parece ser el estándar en todos lados. Así que, estas son las primeras cosas simples que personalmente intentaría primero.

En el ámbito financiero, tienes que pensar cuidadosamente en cómo etiquetar los datos. Por ejemplo, si puedes vender en corto un activo, tienes que asegurarte de que no estás etiquetando todos los movimientos a la baja como oportunidades para tomar una posición corta: la caída debe ser lo suficientemente grande como para superar tarifas, deslizamientos e impacto de precio. Lo mismo con los aumentos de precio. Generalmente significa que tienes muchas etiquetas de "no hacer nada" en tus datos y eso significa que hay un óptimo local donde decir no hacer nada el 100% del tiempo es realmente difícil de superar. Veo que estás usando pesos, pero si tienes muchos datos, una forma sencilla de lidiar con esto es seleccionar aleatoriamente un conjunto de datos equilibrado (o más cercano a estar equilibrado). Si eso falla, ponderar observaciones como haces sería la última opción simple antes de considerar el sobre muestreo.

He visto algunos sistemas que utilizan muy pocas características que funcionan relativamente bien en criptomonedas, por ejemplo. Pero de nuevo, es un tutorial y no se molestaron en hacer más que identificar el signo de la tasa de crecimiento en un intervalo de 3 minutos... Dependiendo de qué tan inteligente seas al etiquetar o cuál sea tu objetivo, la precisión puede ser difícil de conseguir. Pregúntale a Jim Simons. Él tardó 40 años y a muchos doctorados muy inteligentes en llegar lejos en finanzas cuantitativas.

EDICIÓN Puedes, por ejemplo, usar

model = Sequential()
for i in range(N_LSTM_CELLS-1):
    model.add( LSTM(LSTM(NÚMERO_DE_CELDAS_OCULTAS,
                         input_shape=(100, 3),
                         return_sequences=True)) )
    model.add( Dropout(0.2) )
    model.add( BatchNormalization() )

model.add( LSTM(LSTM(NÚMERO_DE_CELDAS_OCULTAS,
                         input_shape=(100, 3)) )
model.add( Dropout(0.2) )
model.add( BatchNormalization() )

model.add( Dense(N_UNIDADES, activation="relu") )
model.add( Dense(3,       activation="softmax") )

Y puedes visitar pythonprogramming.net, el Curso de Aprendizaje Profundo.

0 votos

¡Gracias por tu contribución Stéphane! ¿Podrías mostrar cómo se vería el modelo completo con las capas que sugeriste incluidas? ¿Dropout entre cada capa? ¿Cómo se ve esa última capa densa antes de la capa de salida, ¿también 3 nodos? Escalé las entradas con MinMaxScaler pero también revisaré BatchNormalization, ¡gracias! ¿Y podrías compartir ese artículo sobre criptomonedas al que hacías referencia? ¡Muchas gracias! ¡Saludos!

Finanhelp.com

FinanHelp es una comunidad para personas con conocimientos de economía y finanzas, o quiere aprender. Puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X