ScikitLearn: Series temporales
El tratamiento de series temporales se diferencia de otros enfoques de aprendizaje automático por la dependencia que muestran los datos a lo largo del tiempo. A menudo, las observaciones sucesivas influyen en las subsiguientes, por lo que la estructura de los datos cambia con respecto a los supuestos clásicos de independencia entre muestras. Aunque scikit learn no dispone de un módulo específico para series temporales, ofrece diversas herramientas que pueden emplearse para afrontar problemas de predicción o clasificación con datos que presentan una dimensión temporal.
Un método habitual para aplicar algoritmos de scikit learn a series temporales consiste en transformar el problema en una tarea de supervisión estándar. Se construyen atributos (features) a partir de valores pasados y, opcionalmente, de otras variables exógenas, para luego predecir la variable objetivo (por ejemplo, la demanda en el siguiente periodo). Así, se origina un esquema de entrenamiento similar al de regresión o clasificación, pero con la precaución de no mezclar información presente y futura.
Para generar estas variables históricas, se recurre a técnicas de desplazamiento (lagging) que, por ejemplo, crean columnas que representan los valores de la serie en instantes anteriores. Un ejemplo simple de ingeniería de atributos para predecir ( y_{t} ) utilizando los valores anteriores ( y_{t-1} ) y ( y_{t-2} ) puede plasmarse en pandas o NumPy, y una vez construido este conjunto de datos, se emplea el esquema habitual de scikit learn:
import numpy as np
# Suponiendo series_values como un array 1D con los valores de la serie
X = []
y = []
lag = 2
for i in range(lag, len(series_values)):
X.append(series_values[i-lag:i]) # valores de la serie en t-2 y t-1
y.append(series_values[i]) # valor actual en t
X = np.array(X)
y = np.array(y)
# X e y se usan luego con estimadores de scikit learn
Una vez calculadas estas matrices X (características) e y (etiquetas), se puede aplicar cualquier regressor de scikit learn como LinearRegression
, RandomForestRegressor
o HistGradientBoostingRegressor
. El paso crucial es separar apropiadamente los datos en entrenamiento y validación, respetando la naturaleza temporal.
Para evitar fugas de información al generar subconjuntos de entrenamiento y prueba, conviene ordenar los datos cronológicamente y luego usar el submódulo sklearn.model_selection
con TimeSeriesSplit
. Este esquema reparte el conjunto de datos de manera que se respeten las líneas temporales y no se solape información futura en el entrenamiento. Un ejemplo de aplicación sencilla:
from sklearn.model_selection import TimeSeriesSplit
from sklearn.linear_model import Ridge
tscv = TimeSeriesSplit(n_splits=3)
model = Ridge()
for train_index, test_index in tscv.split(X):
X_train, X_test = X[train_index], X[test_index]
y_train, y_test = y[train_index], y[test_index]
model.fit(X_train, y_train)
score = model.score(X_test, y_test)
print("Score en test:", score)
Con esta validación cruzada, se crea una sucesión de divisiones en las que el conjunto de prueba siempre se sitúa después del conjunto de entrenamiento, reflejando el paso del tiempo de forma coherente. Este enfoque ayuda a estimar la capacidad de generalización y a detectar si el modelo puede adaptarse bien a los datos por venir.
La integración con pipelines también puede ser ventajosa cuando se necesita realizar transformaciones sobre la serie (por ejemplo, escalados, imputaciones de valores faltantes o generación de variables adicionales) sin mezclar datos futuros. El objeto Pipeline
permite unificar la ingeniería de características y el estimador en un único flujo. Sin embargo, en series temporales hay que tener especial cuidado al ajustar los transformadores con datos que no incluyan información del futuro.
En muchos casos, la variabilidad de las series temporales se ve afectada por tendencias a largo plazo o estacionalidades periódicas (por ejemplo, patrones diarios, semanales o anuales). Para modelar dichas estructuras, se recurre a la creación de atributos que representen la estacionalidad:
- Índices de la hora del día, día de la semana o mes del año.
- Variables binarias que identifiquen momentos especiales (festivos, fines de semana, etc.).
- Transformaciones trigonométricas para capturar periodicidades, como el uso de
sin
ycos
de la posición en el ciclo.
Otro aspecto clave al trabajar con series temporales en scikit learn es la homogeneización de la escala, pues los datos suelen presentar diferencias de magnitud a lo largo del tiempo. Utilizar transformadores como StandardScaler
o MinMaxScaler
puede ayudar a estabilizar el entrenamiento de modelos sensibles a la escala de las variables. Un ejemplo de pipeline con escalado y un regresor:
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LinearRegression
pipeline = Pipeline([
('scaler', StandardScaler()),
('regressor', LinearRegression())
])
A la hora de predecir valores múltiples a futuro (por ejemplo, horizontes de varios pasos), existen estrategias como la predicción encadenada (recursiva), donde se utiliza la salida del modelo en el instante ( t+1 ) para predecir ( t+2 ), y así sucesivamente. Otra técnica posible es entrenar un modelo directo para cada horizonte específico, de modo que se aprende directamente la relación entre las características y un futuro ( t+k ). Ambas aproximaciones pueden implementarse con scikit learn a partir del diseño adecuado de los conjuntos de datos y la iteración sobre los pasos de predicción.
Cuando la serie presenta anomalías o puntos atípicos, los modelos de scikit learn pueden combinarse con funciones de detección de outliers, como IsolationForest
o LocalOutlierFactor
, para descubrir comportamientos extraños y limpiarlos o ajustarlos antes de la predicción. Esto puede ser especialmente útil en dominios como detección de fraudes o supervisión industrial.
Si el objetivo de la modelización no es la regresión de valores sino la categorización de estados (por ejemplo, clasificación de un instante como “alerta” o “normal”), se puede convertir el problema en una clasificación supervisada. Cada ventana temporal se etiqueta con la categoría correspondiente, y se utilizan algoritmos como RandomForestClassifier
o SVC
para establecer la frontera de decisión.
En el caso de análisis avanzado de series temporales, se tiende a integrar scikit learn con librerías especializadas que ofrecen modelos ARIMA, SARIMA o métodos específicos de previsión. Sin embargo, la fortaleza de scikit learn reside en su robustez para el aprendizaje supervisado y la facilidad de crear pipelines para manipular las variables temporales y combinarlas con algoritmos de regresión o clasificación.
La evaluación de los modelos entrenados con series temporales suele basarse en métricas de error como el error absoluto medio (MAE), el error cuadrático medio (MSE) o el error porcentual absoluto medio (MAPE), y varía en función de la naturaleza de la tarea y de la escala de los datos. Por ejemplo, en un escenario de demanda energética, se podría priorizar la MAPE para obtener la desviación porcentual con respecto a la demanda real. En un sistema de detección de fallos, en cambio, podría convenir la precisión (accuracy) o la sensibilidad (recall), típicas de problemas de clasificación.
El proceso de experimentación y validación requiere, en último término, esquemas temporales que eviten la contaminación de información desde el futuro al pasado. Por ello, TimeSeriesSplit se convierte en un aliado fundamental para ajustarse a la lógica cronológica. Al terminar las pruebas, es habitual que se seleccione la configuración de hiperparámetros que haya arrojado los resultados más adecuados a la métrica de interés y que se entrene el modelo definitivo con toda la ventana temporal disponible, reservando únicamente la parte más reciente como validación final.
La manipulación de los datos para convertirlos en un conjunto de entrenamiento y prueba, junto con la estructuración de pipelines, otorga a scikit learn la flexibilidad necesaria para abordar problemas de series temporales en ámbitos muy diversos. Se puede así conjugar la potencia de sus algoritmos de regresión y clasificación con la compatibilidad de pandas y NumPy para la construcción de atributos basados en el tiempo, la detección de outliers y la generación de validaciones coherentes con la dimensión temporal.
Este enfoque es especialmente indicado para escenarios donde se parte de un volumen considerable de datos históricos y se desea aprovechar la familiaridad con scikit learn. Aunque existen bibliotecas más enfocadas en series temporales, la combinación de transformaciones personalizadas, validación adecuada y pipelines con scikit learn ofrece un entorno sólido para prototipos y soluciones basadas en predicciones a corto o mediano plazo.
Lecciones de este módulo de ScikitLearn
Lecciones de programación del módulo Series temporales del curso de ScikitLearn.
Ejercicios de programación en este módulo de ScikitLearn
Evalúa tus conocimientos en Series temporales con ejercicios de programación Series temporales de tipo Test, Puzzle, Código y Proyecto con VSCode.