Cómo hacer preprocesamiento de datos de series temporales en Azure ML: paso a paso
Preparar series temporales es a menudo la parte más importante antes de entrenar un modelo. Este tutorial muestra cómo hacer preprocesamiento de datos de series temporales en Azure AI & Machine Learning para obtener datos limpios, imputados y con características temporales útiles para modelos de forecasting o clasificación.
Requisitos previos
- Cuenta Azure con suscripción activa y permisos para crear recursos.
- Workspace de Azure Machine Learning creado.
- Familiaridad básica con Python y Jupyter Notebooks.
- Python 3.8+ con paquetes: pandas, azureml-core, azureml-dataset-runtime.
Paso 1: Cargar los datos al Workspace
Los datos pueden estar en un blob, Data Lake o local. Aquí usamos un archivo CSV con columnas mínimas: timestamp y value. Vamos a registrar el archivo como un Dataset en el Workspace para reproducibilidad y gobernanza de datos.
from azureml.core import Workspace, Dataset
ws = Workspace.from_config()
datastore = ws.get_default_datastore()
# carrega o ficheiro local para o datastore (uma única vez)
datastore.upload_files(files=['./series.csv'], target_path='series/', overwrite=True)
# regista como Dataset
ds = Dataset.Tabular.from_delimited_files(path=(datastore, 'series/series.csv'))
ds = ds.register(workspace=ws, name='series_raw', description='Série temporal bruta')
Paso 2: Exploración inicial y detección de problemas
Explorar rápidamente para ver faltas, duplicados, formatos de fecha e irregularidades de frecuencia. Esto ayuda a decidir imputación y agregación.
import pandas as pd
df = ds.to_pandas_dataframe()
df['timestamp'] = pd.to_datetime(df['timestamp'])
df = df.sort_values('timestamp').reset_index(drop=True)
print(df.info())
print(df.head())
print('Missing values:', df['value'].isna().sum())
Paso 3: Normalizar timestamps y definir frecuencia
Convertir a un índice DatetimeIndex y reindexar a una frecuencia regular (por ej.: hourly, daily). Eso facilita la imputación y la creación de features de lag.
# definir índice e reindexar para frecuencia horaria
freq = 'H' # ajustar conforme a la serie
idx = pd.date_range(start=df['timestamp'].min(), end=df['timestamp'].max(), freq=freq)
df = df.set_index('timestamp').reindex(idx).rename_axis('timestamp').reset_index()
Paso 4: Imputación de valores faltantes
Elegir método sencillo primero: forward-fill/backfill, interpolación lineal o media móvil. Para series con estacionalidad, usar interpolación o modelos más avanzados después.
# ejemplos de imputación
# forward-fill seguido de backfill para extremos
df['value_ffill'] = df['value'].fillna(method='ffill').fillna(method='bfill')
# interpolación lineal
df['value_interp'] = df['value'].interpolate(method='time')
# media móvil (ventana 3)
df['value_ma3'] = df['value'].fillna(df['value'].rolling(window=3, min_periods=1).mean())
Paso 5: Crear características temporales y lags
Características como hour, dayofweek, month y lags son esenciales para modelos. Crear lags y medias móviles para capturar dependencias temporales.
# características temporales
df['hour'] = df['timestamp'].dt.hour
df['dayofweek'] = df['timestamp'].dt.dayofweek
df['month'] = df['timestamp'].dt.month
# lags y rolling
for lag in [1, 24, 168]: # ex.: 1h, 1 día, 1 semana (horaria)
df[f'lag_{lag}'] = df['value_interp'].shift(lag)
# rolling mean
df['rolling_24'] = df['value_interp'].shift(1).rolling(window=24, min_periods=1).mean()
# eliminar primeras líneas con NaNs derivados de los lags
df = df.dropna().reset_index(drop=True)
Paso 6: Dividir train/validación y exportar Dataset
Dividir temporalmente (sin mezclar). Registrar el resultado como nuevo Dataset para entrenamiento y reproducibilidad del pipeline.
train_end = int(len(df) * 0.8)
train_df = df.iloc[:train_end]
val_df = df.iloc[train_end:]
# exportar a CSV y subir al datastore
train_df.to_csv('train_prepared.csv', index=False)
val_df.to_csv('val_prepared.csv', index=False)
datastore.upload_files(files=['train_prepared.csv','val_prepared.csv'], target_path='series/prepared/', overwrite=True)
from azureml.core import Dataset
prepared_train = Dataset.Tabular.from_delimited_files(path=(datastore, 'series/prepared/train_prepared.csv'))
prepared_train = prepared_train.register(workspace=ws, name='series_train_prepared')
Verificar el resultado
Confirmar que no existen NaNs en las características usadas por el modelo, verificar distribución temporal y que los lags están alineados correctamente. Pruebas rápidas:
print('Train rows:', len(train_df))
print('Nulls por columna:\n', train_df.isna().sum())
print('Timestamp sample:', train_df['timestamp'].iloc[:5])
# visualizar algunas características
print(train_df[['timestamp','value_interp','lag_1','rolling_24']].head())
Conclusión
Ahora dispone de una pipeline básica de preprocesamiento de series temporales en Azure AI & Machine Learning: cargó datos, imputó faltas, creó características temporales y lags y registró el Dataset preparado para entrenamiento. Próximos pasos: experimentar con técnicas de imputación avanzadas (por ej.: Prophet, KNN imputation), ingeniería de características estacionales e integrar este código como un Pipeline en Azure ML. Consejo: siempre validar temporalmente para evitar leakage—¿ha probado testar diferentes ventanas de validación temporal?