scikit-learn

ScikitLearn

Tutorial ScikitLearn: Introducción al análisis de series temporales

Scikit Learn: Introducción al Análisis de Series Temporales. Aprende a analizar series temporales con Python y Scikit Learn, explorando conceptos clave y ejemplos prácticos para aplicaciones en diversos campos.

Aprende ScikitLearn GRATIS y certifícate

Conceptos básicos de series temporales

Las series temporales son secuencias de datos recogidos o registrados en intervalos de tiempo sucesivos. Este tipo de datos es fundamental en diversos campos como la economía, la meteorología, la ingeniería y las finanzas, donde el análisis de patrones a lo largo del tiempo permite realizar predicciones y tomar decisiones informadas.

Una serie temporal se caracteriza por su dependencia temporal, lo que significa que los valores actuales están influenciados por los valores pasados. Esta propiedad distingue a los datos temporales de los no temporales, donde tales dependencias no existen. Por ejemplo, las ventas diarias de una tienda pueden depender de las ventas de días anteriores, mientras que las calificaciones de un conjunto de estudiantes no están necesariamente relacionadas en el tiempo.

Para trabajar con series temporales en Python utilizando Scikit Learn, es esencial estructurar los datos de manera que preserven esta dependencia temporal. A continuación, se presenta un ejemplo básico de cómo preparar una serie temporal para su análisis:

import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression

# Generar datos de ejemplo
np.random.seed(0)
fecha_rng = pd.date_range(start='2023-01-01', end='2023-12-31', freq='D')
datos = np.random.randn(len(fecha_rng)) + np.linspace(0, 10, len(fecha_rng))
serie_temporal = pd.DataFrame(data={'Fecha': fecha_rng, 'Valor': datos})
serie_temporal.set_index('Fecha', inplace=True)

# Crear variables de retraso (lags)
serie_temporal['Lag1'] = serie_temporal['Valor'].shift(1)
serie_temporal['Lag2'] = serie_temporal['Valor'].shift(2)
serie_temporal.dropna(inplace=True)

# Definir características y objetivo
X = serie_temporal[['Lag1', 'Lag2']]
y = serie_temporal['Valor']

# Dividir los datos en entrenamiento y prueba
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, shuffle=False)

# Entrenar un modelo de regresión lineal
modelo = LinearRegression()
modelo.fit(X_train, y_train)

# Realizar predicciones
predicciones = modelo.predict(X_test)

# Mostrar las primeras predicciones
print(predicciones[:5])

En este ejemplo:

  1. Generación de datos: Se crea una serie temporal sintética con una tendencia lineal y ruido aleatorio.
  2. Variables de retraso (Lags): Se añaden columnas que representan los valores anteriores de la serie, lo cual es esencial para capturar la dependencia temporal.
  3. División de datos: Los datos se dividen en conjuntos de entrenamiento y prueba sin reordenar (shuffle=False) para mantener la integridad temporal.
  4. Modelado: Se entrena un modelo de regresión lineal utilizando las variables de retraso para predecir el valor actual.

Este enfoque básico establece las bases para análisis más avanzados, permitiendo identificar y modelar patrones inherentes a los datos temporales.

Componentes de una serie temporal: tendencia, estacionalidad y ruido

Las series temporales se componen de tres elementos fundamentales: tendencia, estacionalidad y ruido. Comprender estos componentes es esencial para el análisis y modelado efectivo de datos temporales.

Tendencia

La tendencia se refiere a la dirección general en la que se mueve la serie temporal a lo largo del tiempo. Puede ser ascendente, descendente o estable. Identificar la tendencia permite entender el comportamiento a largo plazo de los datos y es crucial para realizar predicciones precisas.

Por ejemplo, en el análisis de ventas de una empresa, una tendencia ascendente podría indicar un crecimiento sostenido, mientras que una tendencia descendente podría señalar una disminución en la demanda.

Estacionalidad

La estacionalidad representa patrones recurrentes que ocurren en intervalos regulares dentro de la serie temporal, como días, meses o estaciones del año. Estos patrones son consistentes y predecibles, y su identificación es vital para ajustar modelos que capturen estas variaciones periódicas.

Un ejemplo clásico de estacionalidad es el aumento de ventas durante las festividades navideñas o la variación en la demanda de energía eléctrica según las estaciones del año.

Ruido

El ruido corresponde a las fluctuaciones aleatorias e impredecibles que no siguen ningún patrón discernible dentro de la serie temporal. Este componente puede ser resultado de factores externos o internos que afectan los datos de manera irregular.

En el contexto de predicciones, es fundamental minimizar el impacto del ruido para mejorar la precisión de los modelos. Técnicas como el suavizado pueden ayudar a reducir la influencia del ruido en el análisis.

Ejemplo práctico: descomposición de una serie temporal

A continuación, se presenta un ejemplo de cómo descomponer una serie temporal en sus componentes utilizando Python y Scikit Learn:

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from statsmodels.tsa.seasonal import seasonal_decompose

# Generar datos de ejemplo
rng = np.random.default_rng(seed=0) 

fecha_rng = pd.date_range(start='2023-01-01', end='2024-12-31', freq='D')
tendencia = np.linspace(10, 50, len(fecha_rng))
estacionalidad = 10 + 15 * np.sin(2 * np.pi * fecha_rng.dayofyear / 365)

# Utilizar el generador para producir números aleatorios
ruido = rng.normal(0, 5, len(fecha_rng))

serie_temporal = tendencia + estacionalidad + ruido
datos = pd.DataFrame({'Fecha': fecha_rng, 'Valor': serie_temporal})
datos.set_index('Fecha', inplace=True)

# Descomposición de la serie temporal
descomposicion = seasonal_decompose(datos['Valor'], model='additive', period=365)

# Visualizar los componentes
descomposicion.plot()
plt.tight_layout()
plt.show()

En este ejemplo:

  1. Generación de datos: Se crea una serie temporal sintética que combina una tendencia lineal ascendente, una componente estacional basada en una función seno y ruido aleatorio.
  2. Descomposición: Utilizando la función seasonal_decompose de la biblioteca statsmodels, se separa la serie en sus componentes de tendencia, estacionalidad y ruido.
  3. Visualización: Se grafican los componentes descompuestos para una mejor interpretación visual.

Este enfoque permite analizar cada componente por separado, facilitando la identificación de patrones y la construcción de modelos predictivos más precisos.

Diferencias entre datos temporales y no temporales

En el análisis de datos, es fundamental distinguir entre datos temporales y datos no temporales, ya que cada tipo requiere enfoques y técnicas específicas para su procesamiento y modelado. Esta diferenciación afecta directamente la selección de algoritmos, la preparación de los datos y la interpretación de los resultados.

Datos temporales

Los datos temporales son aquellos que están registrados o recolectados en intervalos de tiempo sucesivos. Estos datos poseen una dependencia temporal, lo que implica que los valores presentes están influenciados por los valores pasados y, potencialmente, futuros. Esta característica introduce autocorrelación, donde las observaciones cercanas en el tiempo tienden a estar más relacionadas que las observaciones distantes.

Características principales de los datos temporales:

  • Secuencialidad: Los datos están ordenados cronológicamente.
  • Dependencia temporal: Existe una relación entre los valores en diferentes puntos en el tiempo.
  • Estacionalidad y tendencias: Pueden presentar patrones repetitivos o tendencias a lo largo del tiempo.

Ejemplo de datos temporales:

  • Series de precios de acciones.
  • Datos meteorológicos diarios.
  • Registro de ventas mensuales.

Datos no temporales

Por otro lado, los datos no temporales no tienen una componente temporal inherente. Cada observación es independiente de las demás, y no existe una secuencia temporal que las vincule. Estos datos se analizan en función de sus características individuales sin considerar el orden en que se presentan.

Características principales de los datos no temporales:

  • Independencia: Las observaciones no dependen unas de otras.
  • No secuencialidad: No existe un orden temporal intrínseco.
  • Análisis basado en características: El enfoque se centra en las relaciones entre variables independientes y dependientes.

Ejemplo de datos no temporales:

  • Datos de encuestas de opinión.
  • Conjuntos de imágenes para reconocimiento.
  • Datos de clientes en un sistema de gestión.

Comparación y consideraciones para el modelado

La principal diferencia entre estos dos tipos de datos radica en la estructura de dependencia. Mientras que los datos temporales requieren métodos que capturen la dependencia entre observaciones consecutivas, los datos no temporales pueden ser tratados con técnicas estándar de aprendizaje automático que asumen la independencia de las muestras.

Implicaciones para el modelado:

División de datos:

  • Datos temporales: La división debe respetar la secuencia temporal para evitar fugas de información. Generalmente se utiliza una división cronológica en conjuntos de entrenamiento y prueba.
  • Datos no temporales: Se puede utilizar una división aleatoria, ya que no hay una secuencia que mantener.

Algoritmos de modelado:

  • Datos temporales: Se prefieren modelos que puedan capturar dependencias temporales, como Regresión Lineal con Variables de Retraso, Modelos ARIMA, o Redes Neuronales Recurrentes.
  • Datos no temporales: Se aplican algoritmos estándar como Regresión Logística, Árboles de Decisión, Máquinas de Soporte Vectorial, entre otros.

Validación cruzada:

  • Datos temporales: Se utilizan métodos de validación específicos, como Validación Cruzada Expanding Window o Time Series Split, que preservan el orden temporal.
  • Datos no temporales: Se emplean técnicas convencionales como K-Fold Cross-Validation.

Ejemplo práctico: Diferenciación en el procesamiento de datos

A continuación, se presenta un ejemplo que ilustra cómo manejar datos temporales y no temporales utilizando Python y Scikit Learn:

import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error

# Generación de datos temporales
rng = np.random.default_rng(seed=0) 
fecha_rng = pd.date_range(start='2023-01-01', periods=100, freq='D')
datos_temporales = pd.DataFrame({
    'Fecha': fecha_rng,
    'Valor': rng.standard_normal(100).cumsum()
})
datos_temporales.set_index('Fecha', inplace=True)

# Creación de variables de retraso para datos temporales
datos_temporales['Lag1'] = datos_temporales['Valor'].shift(1)
datos_temporales.dropna(inplace=True)

# División de datos temporales respetando la secuencia temporal
X_temporal = datos_temporales[['Lag1']]
y_temporal = datos_temporales['Valor']
X_train_t, X_test_t, y_train_t, y_test_t = train_test_split(
    X_temporal, y_temporal, test_size=0.2, shuffle=False
)

# Modelado con Regresión Lineal para datos temporales
modelo_temporal = LinearRegression()
modelo_temporal.fit(X_train_t, y_train_t)
predicciones_temporal = modelo_temporal.predict(X_test_t)
mse_temporal = mean_squared_error(y_test_t, predicciones_temporal)
print(f"MSE Datos Temporales: {mse_temporal}")

# Generación de datos no temporales
datos_no_temporales = pd.DataFrame({
    'Caracteristica1': rng.random(100),
    'Caracteristica2': rng.random(100),
    'Objetivo': rng.random(100)
})

# División aleatoria de datos no temporales
X_no_temporal = datos_no_temporales[['Caracteristica1', 'Caracteristica2']]
y_no_temporal = datos_no_temporales['Objetivo']
X_train_nt, X_test_nt, y_train_nt, y_test_nt = train_test_split(
    X_no_temporal, y_no_temporal, test_size=0.2, shuffle=True
)

# Modelado con Regresión Lineal para datos no temporales
modelo_no_temporal = LinearRegression()
modelo_no_temporal.fit(X_train_nt, y_train_nt)
predicciones_no_temporal = modelo_no_temporal.predict(X_test_nt)
mse_no_temporal = mean_squared_error(y_test_nt, predicciones_no_temporal)
print(f"MSE Datos No Temporales: {mse_no_temporal}")

Salida:

Descripción del ejemplo:

Datos temporales:

  • Se genera una serie temporal acumulativa de 100 días.
  • Se crean variables de retraso (Lag1) para capturar la dependencia temporal.
  • La división de los datos se realiza sin mezclar (shuffle=False) para mantener la secuencia temporal.
  • Se entrena un modelo de Regresión Lineal y se evalúa su rendimiento con el Error Cuadrático Medio (MSE).

Datos no temporales:

  • Se generan características aleatorias sin una secuencia temporal inherente.
  • La división de los datos se realiza de manera aleatoria (shuffle=True).
  • Se entrena otro modelo de Regresión Lineal y se evalúa igualmente con el MSE.

Este ejemplo destaca cómo la naturaleza de los datos influye en el proceso de división y modelado, asegurando que se apliquen las técnicas apropiadas para cada tipo de conjunto de datos.

Aplicaciones prácticas del análisis de series temporales

El análisis de series temporales tiene una amplia gama de aplicaciones en diversos sectores, permitiendo a las organizaciones y profesionales tomar decisiones informadas basadas en patrones y tendencias observadas a lo largo del tiempo. A continuación, se detallan algunas de las aplicaciones más destacadas:

Predicción de ventas

En el sector comercial, predecir las ventas futuras es esencial para la planificación de inventarios, estrategias de marketing y gestión financiera. Mediante el análisis de series temporales, las empresas pueden identificar patrones estacionales y tendencias de crecimiento o decrecimiento, lo que les permite anticipar la demanda y optimizar sus operaciones.

import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_absolute_error
import matplotlib.pyplot as plt

# Cargar datos de ventas
datos = pd.read_csv('ventas_mensuales.csv', parse_dates=['Fecha'])
datos.set_index('Fecha', inplace=True)

# Crear variables de retraso
datos['Lag1'] = datos['Ventas'].shift(1)
datos['Lag2'] = datos['Ventas'].shift(2)
datos.dropna(inplace=True)

# Definir características y objetivo
X = datos[['Lag1', 'Lag2']]
y = datos['Ventas']

# Dividir los datos
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, shuffle=False)

# Entrenar el modelo
modelo = LinearRegression()
modelo.fit(X_train, y_train)

# Realizar predicciones
predicciones = modelo.predict(X_test)

# Evaluar el modelo
mae = mean_absolute_error(y_test, predicciones)
print(f'Error Absoluto Medio: {mae}')

# Visualizar las predicciones
plt.figure(figsize=(10,6))
plt.plot(y_test.index, y_test, label='Ventas Reales')
plt.plot(y_test.index, predicciones, label='Predicciones', linestyle='--')
plt.xlabel('Fecha')
plt.ylabel('Ventas')
plt.title('Predicción de Ventas Mensuales')
plt.legend()
plt.show()

Análisis financiero

En el ámbito financiero, el análisis de series temporales es fundamental para predecir precios de activos, evaluar riesgos y desarrollar estrategias de inversión. Los modelos basados en series temporales permiten capturar la volatilidad y las tendencias de los mercados, facilitando decisiones más precisas y oportunas.

A continuación, se presenta un ejemplo práctico de cómo utilizar un modelo de bosques aleatorios con variables de retraso para predecir precios de acciones. Además, se realiza una validación cruzada específica para series temporales y se analizan las predicciones tanto durante la validación como en el modelo final.

import pandas as pd
import numpy as np
from sklearn.model_selection import TimeSeriesSplit
from sklearn.ensemble import RandomForestRegressor
from sklearn.metrics import r2_score
import matplotlib.pyplot as plt

# Cargar datos de precios de acciones
datos = pd.read_csv('precios_acciones.csv', parse_dates=['Fecha'])
datos.set_index('Fecha', inplace=True)

# Crear variables de retraso
datos['Lag1'] = datos['Precio'].shift(1)
datos['Lag2'] = datos['Precio'].shift(2)
datos['Lag3'] = datos['Precio'].shift(3)
datos.dropna(inplace=True)

# Definir características y objetivo
X = datos[['Lag1', 'Lag2', 'Lag3']]
y = datos['Precio']

# Configurar validación cruzada para series temporales
tscv = TimeSeriesSplit(n_splits=5)

# Entrenar y evaluar el modelo
r2_scores = []
predicciones_validacion = pd.Series(index=y.index)  # Serie para almacenar predicciones de validación

for train_index, test_index in tscv.split(X):
    X_train, X_test = X.iloc[train_index], X.iloc[test_index]
    y_train, y_test = y.iloc[train_index], y.iloc[test_index]
    
    modelo = RandomForestRegressor(n_estimators=100, random_state=42)
    modelo.fit(X_train, y_train)
    predicciones = modelo.predict(X_test)
    predicciones_validacion.iloc[test_index] = predicciones
    r2 = r2_score(y_test, predicciones)
    r2_scores.append(r2)

print(f'Puntajes R² por fold: {r2_scores}')
print(f'Promedio R²: {np.mean(r2_scores)}')

# Entrenar modelo final en todos los datos
modelo.fit(X, y)
predicciones_finales = modelo.predict(X)

# Visualizar las predicciones de validación cruzada
plt.figure(figsize=(14, 7))
plt.plot(y.index, y, label='Precio Real', alpha=0.7)
plt.plot(predicciones_validacion.index, predicciones_validacion, label='Predicción Validación', linestyle='--', color='orange')
plt.xlabel('Fecha')
plt.ylabel('Precio')
plt.title('Predicciones de Validación Cruzada')
plt.legend()
plt.show()

# Visualizar las predicciones finales
plt.figure(figsize=(14, 7))
plt.plot(y.index, y, label='Precio Real', alpha=0.7)
plt.plot(y.index, predicciones_finales, label='Predicción Final', linestyle='--', color='green')
plt.xlabel('Fecha')
plt.ylabel('Precio')
plt.title('Predicción Final de Precios de Acciones')
plt.legend()
plt.show()

Pronóstico meteorológico

El pronóstico del clima es otra área donde el análisis de series temporales juega un papel crucial. Mediante la recopilación y análisis de datos históricos de temperatura, precipitación y otros factores meteorológicos, es posible predecir condiciones futuras con mayor precisión, lo que es vital para la planificación agrícola, la gestión de recursos hídricos y la preparación ante desastres naturales.

import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.svm import SVR
from sklearn.metrics import mean_squared_error
import matplotlib.pyplot as plt

# Cargar datos meteorológicos
datos = pd.read_csv('datos_meteorologicos.csv', parse_dates=['Fecha'])
datos.set_index('Fecha', inplace=True)

# Crear variables de retraso
datos['Lag1'] = datos['Temperatura'].shift(1)
datos['Lag2'] = datos['Temperatura'].shift(2)
datos['Lag3'] = datos['Temperatura'].shift(3)
datos.dropna(inplace=True)

# Definir características y objetivo
X = datos[['Lag1', 'Lag2', 'Lag3']]
y = datos['Temperatura']

# Dividir los datos
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, shuffle=False)

# Entrenar el modelo SVR
modelo = SVR(kernel='rbf')
modelo.fit(X_train, y_train)

# Realizar predicciones
predicciones = modelo.predict(X_test)

# Evaluar el modelo
mse = mean_squared_error(y_test, predicciones)
print(f'Error Cuadrático Medio: {mse}')

# Visualizar las predicciones
plt.figure(figsize=(10,6))
plt.plot(y_test.index, y_test, label='Temperatura Real')
plt.plot(y_test.index, predicciones, label='Predicción', linestyle='--')
plt.xlabel('Fecha')
plt.ylabel('Temperatura (°C)')
plt.title('Pronóstico de Temperatura')
plt.legend()
plt.show()

Gestión de inventarios

En logística y gestión de inventarios, prever la demanda futura mediante series temporales ayuda a optimizar el almacenamiento, reducir costos y evitar desabastecimientos. Al analizar patrones de consumo históricos, las empresas pueden ajustar sus niveles de inventario de manera eficiente, respondiendo a fluctuaciones estacionales y tendencias de mercado.

import pandas as pd
import numpy as np
from sklearn.model_selection import TimeSeriesSplit
from sklearn.ensemble import GradientBoostingRegressor
from sklearn.metrics import mean_absolute_error
import matplotlib.pyplot as plt

# Cargar datos de demanda
datos = pd.read_csv('demanda_inventario.csv', parse_dates=['Fecha'])
datos.set_index('Fecha', inplace=True)

# Crear variables de retraso
datos['Lag1'] = datos['Demanda'].shift(1)
datos['Lag2'] = datos['Demanda'].shift(2)
datos['Lag3'] = datos['Demanda'].shift(3)
datos.dropna(inplace=True)

# Definir características y objetivo
X = datos[['Lag1', 'Lag2', 'Lag3']]
y = datos['Demanda']

# Configurar validación cruzada para series temporales
tscv = TimeSeriesSplit(n_splits=4)

# Entrenar y evaluar el modelo
mae_scores = []
for train_index, test_index in tscv.split(X):
    X_train, X_test = X.iloc[train_index], X.iloc[test_index]
    y_train, y_test = y.iloc[train_index], y.iloc[test_index]
    
    modelo = GradientBoostingRegressor(n_estimators=100, learning_rate=0.1, random_state=42)
    modelo.fit(X_train, y_train)
    predicciones = modelo.predict(X_test)
    mae = mean_absolute_error(y_test, predicciones)
    mae_scores.append(mae)

print(f'Puntajes MAE por fold: {mae_scores}')
print(f'Promedio MAE: {np.mean(mae_scores)}')

# Predicciones finales
predicciones_finales = modelo.predict(X_test)

# Visualizar las predicciones
plt.figure(figsize=(10,6))
plt.plot(y_test.index, y_test, label='Demanda Real')
plt.plot(y_test.index, predicciones_finales, label='Predicción', linestyle='--')
plt.xlabel('Fecha')
plt.ylabel('Demanda')
plt.title('Predicción de Demanda para Gestión de Inventarios')
plt.legend()
plt.show()

Estas aplicaciones prácticas demuestran la versatilidad del análisis de series temporales y su capacidad para abordar problemas reales en distintos dominios. La correcta implementación de estos modelos permite mejorar la eficiencia operativa, optimizar recursos y anticipar cambios en el entorno.

Enfoque de Scikit Learn para el modelado de series temporales

Scikit Learn es una de las bibliotecas más utilizadas en Python para el aprendizaje automático, ofreciendo una amplia gama de herramientas y algoritmos para el modelado de datos. Sin embargo, su enfoque está principalmente orientado hacia datos no temporales, lo que requiere adaptaciones específicas para el análisis de series temporales. A continuación, se detalla cómo abordar el modelado de series temporales utilizando Scikit Learn:

Preparación de datos

Antes de aplicar cualquier modelo de Scikit Learn, es crucial preparar los datos para capturar la dependencia temporal. Esto implica:

  • Creación de variables de retraso (lags): Incorporar valores anteriores de la serie como características.
  • Ingeniería de características temporales: Añadir información como el día de la semana, mes, etc., que puedan influir en la variable objetivo.
  • División adecuada de los datos: Mantener la secuencia temporal al dividir en conjuntos de entrenamiento y prueba, evitando la mezcla aleatoria que podría introducir fugas de información.
import pandas as pd
import numpy as np

# Cargar datos de series temporales
datos = pd.read_csv('serie_temporal.csv', parse_dates=['Fecha'])
datos.set_index('Fecha', inplace=True)

# Crear variables de retraso
datos['Lag1'] = datos['Valor'].shift(1)
datos['Lag2'] = datos['Valor'].shift(2)
datos['Lag3'] = datos['Valor'].shift(3)

# Crear características temporales
datos['Mes'] = datos.index.month
datos['Dia_Semana'] = datos.index.dayofweek

# Eliminar filas con valores faltantes
datos.dropna(inplace=True)

# Definir características y objetivo
X = datos[['Lag1', 'Lag2', 'Lag3', 'Mes', 'Dia_Semana']]
y = datos['Valor']

Modelado con algoritmos supervisados

Scikit Learn ofrece una variedad de algoritmos supervisados que pueden ser utilizados para el pronóstico de series temporales una vez que los datos han sido adecuadamente preparados. Algunos de los más comunes incluyen:

  • Regresión Lineal: Para capturar relaciones lineales entre las características y la variable objetivo.
  • Random Forest Regressor: Para modelar relaciones no lineales y capturar interacciones complejas.
  • Support Vector Regressor (SVR): Para manejar alta dimensionalidad y relaciones no lineales.
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.ensemble import RandomForestRegressor
from sklearn.svm import SVR
from sklearn.metrics import mean_squared_error
import matplotlib.pyplot as plt

# Dividir los datos sin mezclar
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, shuffle=False
)

# Inicializar los modelos
modelos = {
    'Regresión Lineal': LinearRegression(),
    'Random Forest': RandomForestRegressor(n_estimators=100, random_state=42),
    'SVR': SVR(kernel='rbf')
}

# Entrenar y evaluar los modelos
resultados = {}
for nombre, modelo in modelos.items():
    modelo.fit(X_train, y_train)
    predicciones = modelo.predict(X_test)
    mse = mean_squared_error(y_test, predicciones)
    resultados[nombre] = mse
    print(f'{nombre} - MSE: {mse}')

    # Visualizar las predicciones
    plt.figure(figsize=(10,4))
    plt.plot(y_test.index, y_test, label='Real')
    plt.plot(y_test.index, predicciones, label='Predicción')
    plt.title(f'Comparación Real vs Predicción - {nombre}')
    plt.xlabel('Fecha')
    plt.ylabel('Valor')
    plt.legend()
    plt.show()

Validación y selección de modelos

Dado que las series temporales tienen una estructura secuencial, es necesario utilizar métodos de validación cruzada específicos que respeten el orden temporal. Scikit Learn proporciona herramientas como TimeSeriesSplit para este propósito.

from sklearn.model_selection import TimeSeriesSplit
from sklearn.metrics import mean_absolute_error

# Configurar TimeSeriesSplit
tscv = TimeSeriesSplit(n_splits=5)

# Evaluar modelos con validación cruzada
for nombre, modelo in modelos.items():
    mae_scores = []
    for train_index, test_index in tscv.split(X):
        X_train_cv, X_test_cv = X.iloc[train_index], X.iloc[test_index]
        y_train_cv, y_test_cv = y.iloc[train_index], y.iloc[test_index]
        
        modelo.fit(X_train_cv, y_train_cv)
        predicciones_cv = modelo.predict(X_test_cv)
        mae = mean_absolute_error(y_test_cv, predicciones_cv)
        mae_scores.append(mae)
    
    promedio_mae = np.mean(mae_scores)
    print(f'{nombre} - Promedio MAE: {promedio_mae}')

Integración con pipelines

Para simplificar el proceso de preprocesamiento y modelado, Scikit Learn permite la creación de pipelines. Esto garantiza que todas las transformaciones se apliquen de manera consistente durante el entrenamiento y la predicción.

from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler

# Crear un pipeline con escalado y regresión lineal
pipeline = Pipeline([
    ('scaler', StandardScaler()),
    ('regresion', LinearRegression())
], memory = None)

# Entrenar el pipeline
pipeline.fit(X_train, y_train)

# Realizar predicciones
predicciones = pipeline.predict(X_test)

# Evaluar el modelo
mse = mean_squared_error(y_test, predicciones)
print(f'MSE con Pipeline: {mse}')

Consideraciones adicionales

  • Extrapolación: Los modelos de Scikit Learn están diseñados para la interpolación de datos dentro del rango de entrenamiento. Para extrapolar más allá de los datos disponibles, es necesario tener en cuenta la posible disminución de precisión.
  • Series multivariantes: Scikit Learn puede manejar múltiples variables predictoras, lo que permite capturar interacciones complejas entre diferentes series temporales.
  • Integración con otras bibliotecas: Para técnicas más avanzadas específicas de series temporales, como modelos ARIMA o Prophet, es recomendable integrar Scikit Learn con otras bibliotecas especializadas.

Ejemplo completo: Pipeline para series temporales

A continuación, se presenta un ejemplo completo que integra la preparación de datos, creación de variables de retraso, ingeniería de características, y modelado utilizando un pipeline de Scikit Learn:

import pandas as pd
import numpy as np
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.ensemble import GradientBoostingRegressor
from sklearn.metrics import mean_squared_error
from sklearn.model_selection import TimeSeriesSplit
import matplotlib.pyplot as plt

# Cargar datos de series temporales
datos = pd.read_csv('serie_temporal_completa.csv', parse_dates=['Fecha'])
datos = datos.set_index('Fecha')

# Crear variables de retraso
for lag in range(1, 4):
    datos[f'Lag{lag}'] = datos['Valor'].shift(lag)

# Crear características temporales
datos['Mes'] = datos.index.month
datos['Dia_Semana'] = datos.index.dayofweek

# Eliminar filas con valores faltantes
datos = datos.dropna()

# Definir características y objetivo
X = datos[['Lag1', 'Lag2', 'Lag3', 'Mes', 'Dia_Semana']]
y = datos['Valor']

# Configurar TimeSeriesSplit
tscv = TimeSeriesSplit(n_splits=3)

# Crear el pipeline
pipeline = Pipeline([
    ('scaler', StandardScaler()),
    ('regresor', GradientBoostingRegressor(n_estimators=100, learning_rate=0.1, random_state=42))
], memory = None)

# Entrenar y evaluar el modelo con validación cruzada
mse_scores = []
for train_index, test_index in tscv.split(X):
    X_train_cv, X_test_cv = X.iloc[train_index], X.iloc[test_index]
    y_train_cv, y_test_cv = y.iloc[train_index], y.iloc[test_index]
    
    pipeline.fit(X_train_cv, y_train_cv)
    predicciones_cv = pipeline.predict(X_test_cv)
    mse = mean_squared_error(y_test_cv, predicciones_cv)
    mse_scores.append(mse)

print(f'Puntajes MSE por fold: {mse_scores}')
print(f'Promedio MSE: {np.mean(mse_scores)}')

# Entrenar el modelo completo
pipeline.fit(X, y)

# Realizar predicciones futuras (ejemplo)
# Supongamos que queremos predecir el siguiente punto
ultimo_lag1 = y.iloc[-1]
ultimo_lag2 = y.iloc[-2]
ultimo_lag3 = y.iloc[-3]
mes_actual = datos.index[-1].month
dia_semana_actual = datos.index[-1].dayofweek

nueva_entrada = np.array([[ultimo_lag1, ultimo_lag2, ultimo_lag3, mes_actual, dia_semana_actual]])
prediccion_futura = pipeline.predict(nueva_entrada)
print(f'Predicción del siguiente valor: {prediccion_futura[0]}')

Salida:

Este enfoque integral permite aprovechar al máximo las capacidades de Scikit Learn para el modelado de series temporales, asegurando una preparación adecuada de los datos y una implementación eficiente de los modelos predictivos.

Aprende ScikitLearn GRATIS online

Ejercicios de esta lección Introducción al análisis de series temporales

Evalúa tus conocimientos de esta lección Introducción al análisis de series temporales con nuestros retos de programación de tipo Test, Puzzle, Código y Proyecto con VSCode, guiados por IA.

Todas las lecciones de ScikitLearn

Accede a todas las lecciones de ScikitLearn y aprende con ejemplos prácticos de código y ejercicios de programación con IDE web sin instalar nada.

Aprendizaje Automático

scikit-learn

Introducción Y Entorno

Introducción E Instalación

scikit-learn

Introducción Y Entorno

Introducción Al Preprocesamiento De Datos

scikit-learn

Preprocesamiento De Datos

Identificación Y Tratamiento De Valores Faltantes

scikit-learn

Preprocesamiento De Datos

Escalado De Datos

scikit-learn

Preprocesamiento De Datos

Normalización De Datos

scikit-learn

Preprocesamiento De Datos

Codificación De Variables Categóricas

scikit-learn

Preprocesamiento De Datos

Ingeniería De Características

scikit-learn

Preprocesamiento De Datos

Selección De Características

scikit-learn

Preprocesamiento De Datos

Extracción De Características

scikit-learn

Preprocesamiento De Datos

Particionamiento De Datos

scikit-learn

Preprocesamiento De Datos

Preprocesamiento De Datos Desbalanceados

scikit-learn

Preprocesamiento De Datos

Introducción A La Regresión

scikit-learn

Regresión

Regresión Lineal

scikit-learn

Regresión

Regresión Knn Kneighborsregressor

scikit-learn

Regresión

Regresión Svm Con Svr

scikit-learn

Regresión

Regresión Con Árboles Decisiontreeregressor

scikit-learn

Regresión

Regresión Con Algoritmos De Conjunto

scikit-learn

Regresión

Introducción A La Clasificación

scikit-learn

Clasificación

Clasificación Con Regresión Logística

scikit-learn

Clasificación

Clasificación Knn Kneighborsclassifier

scikit-learn

Clasificación

Clasificación Svm Con Svc

scikit-learn

Clasificación

Clasificación Con Árboles Decisiontreeclassifier

scikit-learn

Clasificación

Clasificación Con Algoritmos De Conjunto

scikit-learn

Clasificación

Reducción De La Dimensionalidad Con Pca

scikit-learn

Aprendizaje No Supervisado

Clustering Con Kmeans

scikit-learn

Aprendizaje No Supervisado

Clustering Jerárquico

scikit-learn

Aprendizaje No Supervisado

Clustering De Densidad Con Dbscan

scikit-learn

Aprendizaje No Supervisado

Preprocesamiento De Textos Para Nlp

scikit-learn

Nlp

Representación De Texto Y Extracción De Características

scikit-learn

Nlp

Clasificación De Texto Con Scikit Learn

scikit-learn

Nlp

Análisis De Sentimiento

scikit-learn

Nlp

Técnicas Avanzadas De Extracción De Características

scikit-learn

Nlp

Introducción Al Análisis De Series Temporales

scikit-learn

Series Temporales

Preprocesamiento De Datos De Series Temporales

scikit-learn

Series Temporales

Ingeniería De Características Para Series Temporales

scikit-learn

Series Temporales

Transformación Y Escalado De Series Temporales

scikit-learn

Series Temporales

Validación Y Evaluación De Modelos En Series Temporales

scikit-learn

Series Temporales

Validación Y Evaluación De Modelos

scikit-learn

Validación De Modelos

Técnicas De Validación Cruzada

scikit-learn

Validación De Modelos

Métricas De Regresión

scikit-learn

Validación De Modelos

Métricas De Clasificación

scikit-learn

Validación De Modelos

Ajuste De Hiperparámetros

scikit-learn

Validación De Modelos

Introducción A Pipelines

scikit-learn

Pipelines Y Despliegue

Creación De Pipelines Básicos

scikit-learn

Pipelines Y Despliegue

Preprocesamiento De Datos Con Pipelines

scikit-learn

Pipelines Y Despliegue

Pipelines Y Validación Cruzada

scikit-learn

Pipelines Y Despliegue

Pipelines Con Columntransformer

scikit-learn

Pipelines Y Despliegue

Exportar E Importar Pipelines

scikit-learn

Pipelines Y Despliegue

Accede GRATIS a ScikitLearn y certifícate

Objetivos de aprendizaje de esta lección

  • Comprender los conceptos básicos de las series temporales y su importancia en distintos campos.
  • Identificar y analizar los componentes de una serie temporal: tendencia, estacionalidad y ruido.
  • Diferenciar entre datos temporales y no temporales y sus implicaciones en el modelado.
  • Aplicar técnicas de análisis y modelado de series temporales utilizando Scikit Learn en Python.
  • Implementar modelos predictivos para series temporales mediante ejemplos prácticos.
  • Utilizar técnicas adecuadas de validación y selección de modelos para datos temporales.
  • Construir pipelines en Scikit Learn adaptados al modelado de series temporales.