La traductora Polina Kabirova específicamente para Netologia adaptó un artículo del ingeniero de la Universidad de Cambridge Vivek Palaniappan sobre cómo crear un modelo utilizando redes neuronales que puedan predecir los precios de las acciones en una bolsa de valores.El aprendizaje automático y profundo se ha convertido en una nueva estrategia efectiva que muchos fondos de inversión utilizan para aumentar los ingresos. En el artículo, explicaré cómo las redes neuronales ayudan a predecir la situación en el mercado de valores, por ejemplo, el precio de las acciones (o el índice). El texto está basado en mi
proyecto escrito en Python. El código completo y la guía del programa se pueden encontrar en GitHub. Lea otros artículos relacionados en el Blog
Medio .
Redes neuronales en economia
Los cambios en el campo de las finanzas no son lineales y, a veces, puede parecer que los precios de las acciones se forman completamente al azar. Los métodos tradicionales de series temporales, como los modelos ARIMA y GARCH, son efectivos cuando la serie es estacionaria; sus propiedades básicas no cambian con el tiempo. Y esto requiere que la serie haya sido preprocesada utilizando
log returns
o llevada a la estacionariedad de manera diferente. Sin embargo, el principal problema surge cuando estos modelos se implementan en un sistema comercial real, ya que la estacionariedad no está garantizada al agregar nuevos datos.
La solución a este problema puede ser redes neuronales que no requieren estacionariedad. Las redes neuronales son inicialmente muy efectivas para encontrar relaciones entre datos y son capaces de predecir (o clasificar) nuevos datos basados en ellos.
Por lo general, un proyecto de ciencia de datos consta de las siguientes operaciones:
- Recopilación de datos: proporciona un conjunto de propiedades necesarias.
- El preprocesamiento de datos suele ser un paso aterrador pero necesario antes de utilizar los datos.
- El desarrollo e implementación del modelo es la elección del tipo de red neuronal y sus parámetros.
- Los modelos de backtesting (pruebas en datos históricos) son un paso clave en cualquier estrategia comercial.
- Optimización: busque los parámetros adecuados.
Entrada para nuestra red neuronal: datos sobre los precios de las acciones de los últimos 10 días. Con su ayuda, predeciremos los precios al día siguiente.
Recogida de datos
Afortunadamente, los datos necesarios para este proyecto se pueden encontrar en Yahoo Finance. Los datos se pueden recopilar utilizando su API de Python
pdr.get_yahoo_data(ticker, start_date, end_date)
o directamente desde el sitio.
Preprocesamiento de datos
En nuestro caso, los datos deben dividirse en conjuntos de capacitación que consisten en 10 precios pasados y precios al día siguiente. Para hacer esto,
Preprocessing
clase de
Preprocessing
, que funcionará con datos de entrenamiento y prueba. Dentro de la clase,
get_train(self, seq_len)
el
get_train(self, seq_len)
, que convierte los datos de entrada y salida de entrenamiento en matrices
NumPy
, estableciendo una longitud de ventana específica (en nuestro caso 10). Todo el código se ve así:
def gen_train(self, seq_len): """ Generates training data :param seq_len: length of window :return: X_train and Y_train """ for i in range((len(self.stock_train)//seq_len)*seq_len - seq_len - 1): x = np.array(self.stock_train.iloc[i: i + seq_len, 1]) y = np.array([self.stock_train.iloc[i + seq_len + 1, 1]], np.float64) self.input_train.append(x) self.output_train.append(y) self.X_train = np.array(self.input_train) self.Y_train = np.array(self.output_train)
Del mismo modo, he definido un método que convierte los datos de prueba
X_test
e
Y_test
.
Modelos de redes neuronales
Para el proyecto, utilicé dos modelos de redes neuronales: el Perceptrón Multicapa (MLP) y el Modelo a Corto Plazo (LSTM). Hablaré brevemente sobre cómo funcionan estos modelos. Lea más sobre MLP en
otro artículo , y sobre el trabajo de LSTM en Jacob Aungiers.
MLP es la forma más simple de redes neuronales. Los datos de entrada entran en el modelo y, al usar ciertos pesos, los valores se transmiten a través de capas ocultas para obtener datos de salida. Aprender el algoritmo proviene de la propagación hacia atrás a través de capas ocultas para cambiar los valores de peso de cada neurona. El problema con este modelo es la falta de "memoria". Es imposible determinar cuáles fueron los datos anteriores y cómo pueden y deben afectar los nuevos. En el contexto de nuestro modelo, las diferencias de 10 días entre los datos de dos conjuntos de datos pueden ser importantes, pero los MLP no pueden analizar tales relaciones.
Para hacer esto, use LSTM o redes neuronales recurrentes (RNN). Los RNN almacenan cierta información de datos para su uso posterior, esto ayuda a la red neuronal a analizar la estructura compleja de las relaciones entre los datos del precio de las acciones. Pero con RNN, surge el problema de un gradiente de desvanecimiento. El gradiente disminuye porque aumenta el número de capas y el nivel de entrenamiento (un valor menor que la unidad) se multiplica varias veces. Resuelva este problema de LSTM aumentando la eficiencia.
Implementación del modelo
Para implementar el modelo, utilicé
Keras
, porque allí se agregan capas gradualmente y no definen toda la red a la vez. Por lo tanto, podemos cambiar rápidamente el número y el tipo de capas, optimizando la red neuronal.
Un paso importante para trabajar con los precios de las acciones es la normalización de datos. Por lo general, para esto se resta el error promedio y se divide por el error estándar. Pero necesitamos que este sistema se use en el comercio real durante un cierto período de tiempo. Por lo tanto, el uso de estadísticas puede no ser la forma más precisa de normalizar los datos. Así que acabo de dividir todos los datos en 200 (un número arbitrario en comparación con el cual todos los otros números son pequeños). Y aunque parece que tal normalización no está justificada y no tiene sentido, es efectivo asegurarse de que los pesos en la red neuronal no sean demasiado grandes.
Comencemos con un modelo más simple: MLP. Keras construye una secuencia y agrega capas densas encima. El código completo se ve así:
model = tf.keras.models.Sequential() model.add(tf.keras.layers.Dense(100, activation=tf.nn.relu)) model.add(tf.keras.layers.Dense(100, activation=tf.nn.relu)) model.add(tf.keras.layers.Dense(1, activation=tf.nn.relu)) model.compile(optimizer="adam", loss="mean_squared_error")
Usando Keras en cinco líneas de código, creamos MLP con capas ocultas, cien neuronas en cada una. Y ahora un poco sobre el optimizador. El método Adam (estimación de momento adaptativo) está ganando popularidad: un algoritmo de optimización más eficiente en comparación con
el descenso de gradiente estocástico . Hay otras dos extensiones del descenso de gradiente estocástico: las ventajas de Adam son inmediatamente visibles en su contexto:
AdaGrad : mantiene una velocidad de aprendizaje establecida, que mejora los resultados cuando los gradientes divergen (por ejemplo, con problemas con el lenguaje natural y la visión por computadora).
RMSProp : mantiene una velocidad de entrenamiento establecida, que puede variar según los valores promedio de los gradientes recientes para el peso (por ejemplo, qué tan rápido cambia). Esto significa que el algoritmo resuelve bien los problemas no estacionarios (por ejemplo, ruido).
Adam combina los beneficios de estas extensiones, así que lo elegí.
Ahora ajustamos el modelo a nuestros datos de entrenamiento. Keras simplifica la tarea nuevamente, solo se necesita el siguiente código:
model.fit(X_train, Y_train, epochs=100)
Cuando el modelo esté listo, debe verificarlo en los datos de prueba para determinar qué tan bien funcionó. Esto se hace así:
model.evaluate(X_test, Y_test)
La información obtenida de la verificación se puede utilizar para evaluar la capacidad del modelo para predecir los precios de las acciones.
Se utiliza un procedimiento similar para el modelo LSTM, por lo que mostraré el código y lo explicaré un poco:
model = tf.keras.Sequential() model.add(tf.keras.layers.LSTM(20, input_shape=(10, 1), return_sequences=True)) model.add(tf.keras.layers.LSTM(20)) model.add(tf.keras.layers.Dense(1, activation=tf.nn.relu)) model.compile(optimizer="adam", loss="mean_squared_error") model.fit(X_train, Y_train, epochs=50) model.evaluate(X_test, Y_test)
Tenga en cuenta que Keras necesita datos de cierto tamaño, dependiendo de su modelo. Es muy importante cambiar la forma de la matriz con NumPy.
Modelos de backtesting
Cuando preparamos nuestros modelos usando datos de entrenamiento y los probamos en datos de prueba, podemos probar el modelo en datos históricos. Esto se hace de la siguiente manera:
def back_test(strategy, seq_len, ticker, start_date, end_date, dim): """ A simple back test for a given date period :param strategy: the chosen strategy. Note to have already formed the model, and fitted with training data. :param seq_len: length of the days used for prediction :param ticker: company ticker :param start_date: starting date :type start_date: "YYYY-mm-dd" :param end_date: ending date :type end_date: "YYYY-mm-dd" :param dim: dimension required for strategy: 3dim for LSTM and 2dim for MLP :type dim: tuple :return: Percentage errors array that gives the errors for every test in the given date range """ data = pdr.get_data_yahoo(ticker, start_date, end_date) stock_data = data["Adj Close"] errors = [] for i in range((len(stock_data)//10)*10 - seq_len - 1): x = np.array(stock_data.iloc[i: i + seq_len, 1]).reshape(dim) / 200 y = np.array(stock_data.iloc[i + seq_len + 1, 1]) / 200 predict = strategy.predict(x) while predict == 0: predict = strategy.predict(x) error = (predict - y) / 100 errors.append(error) total_error = np.array(errors) print(f"Average error = {total_error.mean()}")
Sin embargo, esta es una versión simplificada de las pruebas. Para un sistema de backtesting completo, se deben considerar factores como el "sesgo de supervivencia", el sesgo (sesgo de anticipación), las condiciones cambiantes del mercado y los costos de transacción. Dado que este es solo un proyecto educativo, basta una simple prueba de respaldo.
Pronóstico de mi modelo LSTM para los precios de las acciones de Apple en febreroPara un modelo LSTM simple sin optimización, este es un muy buen resultado. Muestra que las redes neuronales y los modelos de aprendizaje automático son capaces de construir conexiones complejas y estables entre los parámetros.
Optimización de hiperparámetros
La optimización a menudo es necesaria para mejorar los resultados del modelo después de la prueba. No lo incluí en la versión de código abierto para que los lectores puedan intentar optimizar el modelo ellos mismos. Aquellos que no saben cómo optimizar tendrán que encontrar hiperparámetros que mejorarán el rendimiento del modelo. Existen varios métodos para encontrar hiperparámetros: desde la selección de parámetros en una cuadrícula hasta los métodos estocásticos.
Estoy seguro de que con la optimización de modelos, el conocimiento en el campo del aprendizaje automático va a un nuevo nivel. Intenta optimizar el modelo para que funcione mejor que el mío. Compara el resultado con el gráfico de arriba.
Conclusión
El aprendizaje automático está en constante evolución: todos los días aparecen nuevos métodos, por lo que es muy importante aprender constantemente. La mejor manera de hacer esto es crear proyectos interesantes, por ejemplo, construir modelos para pronosticar los precios de las acciones. Y aunque mi modelo LSTM no es lo suficientemente bueno para su uso en el comercio real, la base establecida en el desarrollo de dicho modelo puede ayudar en el futuro.
De los editores
Cursos de Netología sobre el tema: