4. Aprendizaje supervisado: aprender con profesor
Nivel 10: Machine Learning Aplicado al Trading
Los problemas de machine learning se agrupan en unos pocos tipos según qué información tenemos disponible. El primero y más común es el aprendizaje supervisado.
Este tipo de algoritmos funciona con el modelo del profesor. Significa que tenemos un conjunto de datos con valores de entrada y de salida, es decir, datos etiquetados. Definimos un método para obtener las salidas conocidas a partir de las entradas de que disponemos. A medida que mejoramos ese método usando todos los pares entrada-salida (a eso se le llama entrenar), podemos predecir valores de salida para datos de entrada nuevos. Eso es el aprendizaje supervisado. Aprendemos el modelo usando los datos de entrenamiento y lo probamos con datos de test que no ha visto. Es decir, trabajamos tanto con datos de entrada como de salida.
Un ejemplo típico de aprendizaje supervisado es predecir precios de viviendas. Otro es decir qué dígito, qué animal o qué objeto aparece en una imagen.
Dentro del aprendizaje supervisado hay dos grandes familias, y la diferencia está en la naturaleza de y:
- Regresión: y es continua. El ejemplo canónico es la regresión lineal. En trading: predecir el retorno de mañana, la volatilidad realizada de la próxima semana, o el spread esperado.
- Clasificación: y es binaria o multiclase. El ejemplo canónico es la regresión logística. En trading: predecir si el cierre de mañana será superior al de hoy, o clasificar el régimen de mercado en alcista, lateral o de pánico.
En finanzas hay un detalle que no aparece en los tutoriales genéricos y que arruina más backtests que ningún otro error: la partición entre entrenamiento y test no puede ser aleatoria. Si barajas las filas, el modelo se entrena con días futuros y se evalúa con días pasados, y aprende relaciones que en el momento de operar no estaban disponibles. La partición tiene que respetar el orden temporal.
import numpy as np
import pandas as pd
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score
# df tiene columnas Open, High, Low, Close de un activo (por ejemplo, SPY)
df = df.dropna().copy()
# Variables de entrada (X): información disponible AL CIERRE de hoy
df["Open-Close"] = df["Open"] - df["Close"]
df["High-Low"] = df["High"] - df["Low"]
df["Ret_1d"] = np.log(df["Close"] / df["Close"].shift(1))
# Variable de salida (y): etiqueta binaria, 1 si manana cierra por encima
df["y"] = np.where(df["Close"].shift(-1) > df["Close"], 1, 0)
df = df.dropna()
X = df[["Open-Close", "High-Low", "Ret_1d"]]
y = df["y"]
# Partición TEMPORAL, nunca aleatoria: 70% pasado para entrenar, 30% futuro para test
split = int(0.7 * len(df))
X_train, X_test = X[:split], X[split:]
y_train, y_test = y[:split], y[split:]
modelo = LogisticRegression(max_iter=1000).fit(X_train, y_train)
print("Acierto en train:", accuracy_score(y_train, modelo.predict(X_train)))
print("Acierto en test :", accuracy_score(y_test, modelo.predict(X_test)))Si el acierto en train es mucho mayor que en test, tienes sobreajuste. Y si el acierto en test ronda el 50% en una tarea binaria equilibrada, tu modelo no sabe nada: está lanzando una moneda cara.