Menu iconMenu icon
Fundamentos de Ingeniería de Datos

Capítulo 9: Datos de series temporales: consideraciones especiales

9.1 Trabajando con Características de Fecha/Hora

Trabajar con datos de series temporales presenta desafíos y requisitos únicos que los diferencian de los conjuntos de datos estáticos. Los datos de series temporales se caracterizan por su orden temporal, donde cada observación está intrínsecamente vinculada al momento en que fue registrada. Esta dependencia temporal introduce complejidades que requieren enfoques analíticos especializados. Ya sea que estés pronosticando tendencias de ventas, prediciendo fluctuaciones en los precios de las acciones o analizando patrones climáticos complejos, una comprensión profunda de los datos de series temporales es crucial para modelar e interpretar con precisión los patrones, tendencias y estacionalidades subyacentes en los datos.

El análisis de series temporales nos permite descubrir conocimientos ocultos y hacer predicciones fundamentadas aprovechando la naturaleza temporal de los datos. Nos permite capturar no solo el estado actual de un sistema, sino también cómo evoluciona con el tiempo. Esta dimensión temporal agrega una capa de complejidad a nuestro análisis, pero también proporciona información valiosa sobre la dinámica del sistema que estamos estudiando.

Este capítulo profundizará en las consideraciones y técnicas específicas esenciales para manejar los datos de series temporales de manera efectiva. Comenzaremos explorando el rol crítico de las características de fecha y hora, discutiendo técnicas avanzadas para manejar información temporal. Esto incluye métodos para extraer características significativas de las marcas de tiempo, lidiar con diferentes escalas de tiempo y abordar desafíos como intervalos de muestreo irregulares o puntos de datos faltantes.

A continuación, profundizaremos en métodos sofisticados para descomponer los datos de series temporales. Este paso crucial nos permite desglosar una serie temporal compleja en sus componentes: tendencias, que representan la progresión a largo plazo; estacionalidad, que captura patrones cíclicos; y residuos, que representan las fluctuaciones aleatorias en los datos. Comprender estos componentes es clave para construir modelos predictivos precisos y obtener conocimientos sobre los impulsores subyacentes de los patrones observados.

Finalmente, abordaremos el concepto de estacionariedad y su profunda importancia para el modelado predictivo en el análisis de series temporales. Exploraremos por qué la estacionariedad es un supuesto crucial para muchos modelos de series temporales y discutiremos varias pruebas para determinar si una serie es estacionaria. Además, profundizaremos en técnicas avanzadas para transformar datos no estacionarios en una forma estacionaria, como diferenciación, eliminación de tendencias y enfoques más sofisticados como la transformación de Box-Cox. Al dominar estos conceptos y técnicas, estarás bien equipado para manejar una amplia gama de desafíos de series temporales y extraer información significativa de los datos temporales.

Cuando trabajamos con datos de series temporales, los elementos de fecha y hora sirven como el eje central para entender y predecir patrones temporales. Las características de fecha y hora no son solo identificadores simples; son fuentes ricas de información que pueden revelar tendencias complejas, estacionalidades y patrones cíclicos dentro de los datos. Estas características proporcionan un contexto temporal crucial para una interpretación y pronóstico precisos.

El poder de las características de fecha y hora radica en su capacidad para capturar relaciones temporales tanto obvias como sutiles. Por ejemplo, pueden revelar ciclos anuales en los datos de ventas, fluctuaciones mensuales en la temperatura o incluso patrones horarios en el tráfico de sitios web. Al extraer y utilizar adecuadamente estas características, los analistas pueden descubrir periodicidades ocultas y tendencias a largo plazo que de otro modo podrían pasar desapercibidas.

Además, aprovechar las características de fecha y hora de manera efectiva puede conducir a mejoras significativas en la precisión del modelo. Al incorporar estos conocimientos temporales, los modelos pueden aprender a reconocer y predecir patrones que están intrínsecamente ligados a períodos específicos. Esto puede ser especialmente valioso en campos como las finanzas, donde los comportamientos del mercado a menudo siguen patrones temporales complejos, o en el pronóstico del consumo de energía, donde los patrones de uso varían considerablemente dependiendo de la hora del día, el día de la semana o la temporada del año.

El proceso de trabajar con características de fecha y hora implica más que simplemente incluirlas en un conjunto de datos. Requiere una consideración cuidadosa de cómo representar y codificar estas características para maximizar su valor informativo. Esto puede implicar técnicas como la codificación cíclica para características como días de la semana o meses, o la creación de características de retraso para capturar efectos de tiempo diferido. Al diseñar estas características de manera reflexiva, los analistas pueden dotar a sus modelos de una comprensión matizada del tiempo, lo que permite predicciones más sofisticadas y precisas.

9.1.1 Características Comunes de Fecha/Hora y Su Importancia

Las características de fecha y hora juegan un papel crucial en el análisis de series temporales, proporcionando información valiosa sobre patrones temporales. Exploremos algunas características clave y su importancia:

  • Año, Mes, Día: Estos componentes básicos son fundamentales para capturar tendencias a largo plazo y variaciones estacionales. Por ejemplo, los negocios minoristas suelen experimentar ciclos de ventas anuales, con picos durante las temporadas de vacaciones. De manera similar, los datos de temperatura muestran típicamente fluctuaciones mensuales, permitiéndonos rastrear patrones climáticos con el tiempo.
  • Día de la Semana: Esta característica es particularmente útil para identificar ritmos semanales en los datos. Muchas industrias, como restaurantes o lugares de entretenimiento, ven diferencias significativas entre las actividades de entre semana y de fin de semana. Al incorporar esta característica, los modelos pueden aprender a anticipar estas fluctuaciones regulares.
  • Trimestre: Los datos trimestrales son especialmente relevantes en contextos financieros. Muchas empresas reportan ganancias y establecen metas en una base trimestral, lo que hace que esta característica sea invaluable para analizar tendencias fiscales y realizar predicciones económicas.
  • Hora y Minuto: Para datos de alta frecuencia, estos componentes de tiempo granulares son esenciales. Pueden revelar patrones intrincados en el consumo de energía, donde el uso puede aumentar durante ciertas horas del día, o en el flujo de tráfico, donde los patrones de horas pico se vuelven evidentes.
  • Días Festivos y Eventos Especiales: Aunque no se mencionó en la lista original, estos pueden ser características cruciales. Muchas empresas ven cambios significativos en la actividad durante días festivos o eventos especiales, lo que puede impactar en gran medida las predicciones de series temporales.

Al aprovechar estas características temporales, podemos construir modelos que no solo reconocen patrones recurrentes y estacionalidades, sino que también se adaptan a las características únicas de diferentes escalas de tiempo. Este enfoque integral permite predicciones más matizadas y precisas, capturando tanto los trazos generales de las tendencias a largo plazo como los detalles de las fluctuaciones a corto plazo. Comprender y utilizar adecuadamente estas características es clave para desbloquear el potencial completo del análisis de series temporales en diversos dominios, desde finanzas y ventas minoristas hasta gestión de energía y planificación urbana.

9.1.2 Extrayendo Características de Fecha/Hora en Python

Pandas proporciona una interfaz poderosa e intuitiva para manejar características de fecha y hora en datos de series temporales. La funcionalidad Datetime de la biblioteca ofrece un conjunto completo de herramientas que simplifican la tarea, a menudo compleja, de trabajar con datos temporales. Con Pandas, podemos analizar fechas desde varios formatos, extraer componentes temporales específicos y transformar columnas de fechas en representaciones más amigables para el análisis.

Las capacidades de análisis de Pandas nos permiten convertir representaciones de fechas en cadena a objetos datetime, infiriendo automáticamente el formato en muchos casos. Esto es particularmente útil cuando se trabaja con conjuntos de datos que contienen fechas en formatos inconsistentes o no estándar. Una vez analizadas, podemos extraer fácilmente una amplia gama de características temporales, como año, mes, día, hora, minuto, segundo, día de la semana, trimestre e incluso períodos fiscales.

Además, Pandas nos permite realizar aritmética de fechas sofisticada, facilitando el cálculo de diferencias de tiempo, la adición o sustracción de períodos de tiempo o el remuestreo de datos a diferentes frecuencias de tiempo. Esta flexibilidad es crucial al preparar datos de series temporales para análisis o modelado, ya que nos permite alinear puntos de datos, crear características de retraso o agregar datos en ventanas de tiempo personalizadas.

Al aprovechar la funcionalidad de fecha y hora de Pandas, podemos transformar datos temporales sin procesar en un conjunto rico de características que capturan los patrones subyacentes y la estacionalidad en nuestras series temporales. Este paso de preprocesamiento es a menudo crítico para desarrollar modelos de pronóstico precisos o realizar un análisis significativo de series temporales en diversos dominios, desde finanzas y economía hasta estudios ambientales y más allá.

Ejemplo: Extrayendo Características Básicas de Fecha/Hora

Comencemos con un conjunto de datos que incluye una columna de Fecha. Demostraremos cómo analizar fechas y extraer características como AñoMesDía de la Semana y Trimestre.

import pandas as pd

# Sample data with dates
data = {'Date': ['2022-01-15', '2022-02-10', '2022-03-20', '2022-04-15', '2022-05-25']}
df = pd.DataFrame(data)

# Convert Date column to datetime format
df['Date'] = pd.to_datetime(df['Date'])

# Extract date/time features
df['Year'] = df['Date'].dt.year
df['Month'] = df['Date'].dt.month
df['Day'] = df['Date'].dt.day
df['DayOfWeek'] = df['Date'].dt.dayofweek
df['Quarter'] = df['Date'].dt.quarter

print(df)

Este código demuestra cómo extraer características de fecha y hora de un conjunto de datos utilizando pandas en Python. A continuación se detalla qué hace el código:

  • Primero, importa la biblioteca pandas, esencial para la manipulación de datos en Python.
  • Crea un conjunto de datos de muestra con una columna 'Date' que contiene cinco cadenas de fechas.
  • Luego, los datos se convierten en un DataFrame de pandas.
  • La columna 'Date' se convierte del formato de cadena a formato datetime usando pd.to_datetime(). Este paso es crucial para realizar operaciones basadas en fechas.
  • El código luego extrae varias características de fecha/hora de la columna 'Date':
    • Year: Extrae el año de cada fecha.
    • Month: Extrae el mes (1-12).
    • Day: Extrae el día del mes.
    • DayOfWeek: Extrae el día de la semana (0-6, donde 0 es lunes).
    • Quarter: Extrae el trimestre del año (1-4).
  • Finalmente, imprime el DataFrame resultante, que ahora incluye estas nuevas características de fecha/hora junto con la columna original 'Date'.

Este código es particularmente útil para el análisis de series temporales, ya que permite capturar diversos aspectos temporales de los datos, los cuales se pueden utilizar para identificar patrones, estacionalidad o tendencias en el conjunto de datos.

Exploremos un ejemplo más completo.

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

# Sample data with dates and sales
data = {
    'Date': ['2022-01-15', '2022-02-10', '2022-03-20', '2022-04-15', '2022-05-25', 
             '2022-06-30', '2022-07-05', '2022-08-12', '2022-09-18', '2022-10-22'],
    'Sales': [1000, 1200, 1500, 1300, 1800, 2000, 1900, 2200, 2100, 2300]
}
df = pd.DataFrame(data)

# Convert Date column to datetime format
df['Date'] = pd.to_datetime(df['Date'])

# Extract basic date/time features
df['Year'] = df['Date'].dt.year
df['Month'] = df['Date'].dt.month
df['Day'] = df['Date'].dt.day
df['DayOfWeek'] = df['Date'].dt.dayofweek
df['Quarter'] = df['Date'].dt.quarter

# Extract additional features
df['WeekOfYear'] = df['Date'].dt.isocalendar().week
df['DayOfYear'] = df['Date'].dt.dayofyear
df['IsWeekend'] = df['DayOfWeek'].isin([5, 6]).astype(int)

# Create cyclical features for Month and DayOfWeek
df['Month_sin'] = np.sin(2 * np.pi * df['Month'] / 12)
df['Month_cos'] = np.cos(2 * np.pi * df['Month'] / 12)
df['DayOfWeek_sin'] = np.sin(2 * np.pi * df['DayOfWeek'] / 7)
df['DayOfWeek_cos'] = np.cos(2 * np.pi * df['DayOfWeek'] / 7)

# Create lag features
df['Sales_Lag1'] = df['Sales'].shift(1)
df['Sales_Lag7'] = df['Sales'].shift(7)

# Calculate rolling mean
df['Sales_RollingMean7'] = df['Sales'].rolling(window=7, min_periods=1).mean()

# Print the resulting dataframe
print(df)

# Visualize sales over time
plt.figure(figsize=(12, 6))
plt.plot(df['Date'], df['Sales'])
plt.title('Sales Over Time')
plt.xlabel('Date')
plt.ylabel('Sales')
plt.xticks(rotation=45)
plt.tight_layout()
plt.show()

# Visualize cyclical features
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))
ax1.scatter(df['Month_sin'], df['Month_cos'])
ax1.set_title('Cyclical Encoding of Month')
ax1.set_xlabel('Sin(Month)')
ax1.set_ylabel('Cos(Month)')
ax2.scatter(df['DayOfWeek_sin'], df['DayOfWeek_cos'])
ax2.set_title('Cyclical Encoding of Day of Week')
ax2.set_xlabel('Sin(DayOfWeek)')
ax2.set_ylabel('Cos(DayOfWeek)')
plt.tight_layout()
plt.show()

Explicación del desglose del código:

  1. Preparación de datos:
    • Comenzamos importando las bibliotecas necesarias: pandas para manipulación de datos, numpy para operaciones numéricas y matplotlib para visualización.
    • Se crea un conjunto de datos de muestra con fechas y cifras de ventas correspondientes.
    • La columna 'Date' se convierte a formato datetime usando pd.to_datetime().
  2. Extracción básica de características:
    • Extraemos características fundamentales de fecha/hora:
      • Año, Mes, Día: Componentes básicos de la fecha.
      • Día de la semana: Útil para captar patrones semanales (0 = lunes, 6 = domingo).
      • Trimestre: Para tendencias trimestrales, comúnmente utilizadas en análisis financieros.
  3. Extracción avanzada de características:
    • Semana del año: Captura patrones cíclicos anuales.
    • Día del año: Útil para identificar efectos estacionales anuales.
    • EsFinDeSemana: Característica binaria para diferenciar entre días de semana y fines de semana.
  4. Codificación de características cíclicas:
    • El mes y el día de la semana se codifican usando funciones seno y coseno.
    • Esto conserva la naturaleza cíclica de estas características, asegurando que, por ejemplo, diciembre (12) esté cerca de enero (1) en el espacio cíclico.
  5. Características de retraso (Lag):
    • Ventas_Lag1: Ventas del día anterior.
    • Ventas_Lag7: Ventas de hace una semana.
    • Estas características ayudan a capturar tendencias a corto plazo y semanales.
  6. Estadísticas móviles:
    • Media móvil de ventas de 7 días: Suaviza las fluctuaciones a corto plazo y destaca tendencias a largo plazo.
  7. Visualización:
    • Se crea un gráfico de series temporales de las ventas a lo largo del tiempo para visualizar las tendencias generales.
    • Se generan gráficos de dispersión de las características de mes y día de la semana codificadas cíclicamente para ilustrar cómo se representan estas características circulares en el espacio 2D.

Este ejemplo ampliado demuestra un enfoque más completo para la ingeniería de características en datos de series temporales. Incluye características temporales básicas, codificación cíclica avanzada, características de retraso y estadísticas móviles. Las visualizaciones ayudan a comprender la distribución de los datos y la efectividad de la codificación cíclica. Este conjunto enriquecido de características puede mejorar significativamente el rendimiento de los modelos de pronóstico de series temporales al capturar varios patrones y dependencias temporales en los datos.

9.1.3 Uso de características de fecha y hora en el modelo

Al incorporar características de fecha y hora en el modelo, es crucial seleccionar cuidadosamente aquellas que realmente mejoren su capacidad predictiva. La relevancia de estas características puede variar considerablemente según la naturaleza de los datos y el problema a resolver. Por ejemplo:

  • Día de la semana es particularmente valioso en conjuntos de datos de venta minorista, donde el comportamiento del consumidor sigue patrones distintos a lo largo de la semana. Esta característica puede ayudar a capturar la diferencia entre las ventas de días de semana y de fin de semana, o incluso patrones más sutiles como caídas a mitad de semana o picos al final de la semana.
  • Mes es excelente para captar ciclos estacionales que ocurren anualmente. Esto podría ser útil en diversos dominios como el comercio minorista (temporadas de compras), el turismo (meses pico de viajes) o la agricultura (ciclos de cultivo).
  • Año es fundamental para captar tendencias a largo plazo, lo cual es especialmente importante en conjuntos de datos que abarcan varios años. Esta característica puede ayudar a que los modelos tengan en cuenta cambios graduales en la distribución de datos subyacente, como el crecimiento o la disminución del mercado.

No obstante, la utilidad de estas características no se limita solo a estos ejemplos. La hora del día podría ser crucial para modelar el consumo de energía o los patrones de tráfico. Trimestre podría ser más adecuado que el mes para ciertas métricas comerciales que operan en un ciclo trimestral. Semana del año podría capturar patrones que se repiten anualmente pero no se alinean perfectamente con los meses del calendario.

También vale la pena considerar características derivadas. En lugar de componentes de fecha en bruto, se podrían crear indicadores booleanos como "Es_Feriado" o "Es_DíaDePago", o calcular el número de días desde un evento significativo. La clave es reflexionar sobre qué patrones temporales podrían existir en los datos y experimentar con diferentes combinaciones de características para encontrar la que mejor se adapte al caso de uso específico.

Ejemplo: Adición de características de fecha y hora a un modelo de pronóstico de ventas

Apliquemos nuestras características de fecha a un conjunto de datos de pronóstico de ventas.

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

# Sample sales data with dates
sales_data = {
    'Date': ['2022-01-15', '2022-02-10', '2022-03-20', '2022-04-15', '2022-05-25', 
             '2022-06-30', '2022-07-05', '2022-08-12', '2022-09-18', '2022-10-22'],
    'Sales': [200, 220, 250, 210, 230, 280, 260, 300, 290, 310]
}
df_sales = pd.DataFrame(sales_data)

# Convert Date to datetime and extract date/time features
df_sales['Date'] = pd.to_datetime(df_sales['Date'])
df_sales['Year'] = df_sales['Date'].dt.year
df_sales['Month'] = df_sales['Date'].dt.month
df_sales['Day'] = df_sales['Date'].dt.day
df_sales['DayOfWeek'] = df_sales['Date'].dt.dayofweek
df_sales['Quarter'] = df_sales['Date'].dt.quarter
df_sales['WeekOfYear'] = df_sales['Date'].dt.isocalendar().week
df_sales['DayOfYear'] = df_sales['Date'].dt.dayofyear
df_sales['IsWeekend'] = df_sales['DayOfWeek'].isin([5, 6]).astype(int)

# Create cyclical features for Month and DayOfWeek
df_sales['Month_sin'] = np.sin(2 * np.pi * df_sales['Month'] / 12)
df_sales['Month_cos'] = np.cos(2 * np.pi * df_sales['Month'] / 12)
df_sales['DayOfWeek_sin'] = np.sin(2 * np.pi * df_sales['DayOfWeek'] / 7)
df_sales['DayOfWeek_cos'] = np.cos(2 * np.pi * df_sales['DayOfWeek'] / 7)

# Create lag features
df_sales['Sales_Lag1'] = df_sales['Sales'].shift(1)
df_sales['Sales_Lag7'] = df_sales['Sales'].shift(7)

# Calculate rolling statistics
df_sales['Sales_RollingMean7'] = df_sales['Sales'].rolling(window=7, min_periods=1).mean()
df_sales['Sales_RollingStd7'] = df_sales['Sales'].rolling(window=7, min_periods=1).std()

# View dataset with extracted features
print(df_sales)

# Visualize sales over time
plt.figure(figsize=(12, 6))
plt.plot(df_sales['Date'], df_sales['Sales'])
plt.title('Sales Over Time')
plt.xlabel('Date')
plt.ylabel('Sales')
plt.xticks(rotation=45)
plt.tight_layout()
plt.show()

# Visualize cyclical features
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))
ax1.scatter(df_sales['Month_sin'], df_sales['Month_cos'])
ax1.set_title('Cyclical Encoding of Month')
ax1.set_xlabel('Sin(Month)')
ax1.set_ylabel('Cos(Month)')
ax2.scatter(df_sales['DayOfWeek_sin'], df_sales['DayOfWeek_cos'])
ax2.set_title('Cyclical Encoding of Day of Week')
ax2.set_xlabel('Sin(DayOfWeek)')
ax2.set_ylabel('Cos(DayOfWeek)')
plt.tight_layout()
plt.show()

Explicación completa del desglose:

  1. Preparación de datos:
    • Importamos las bibliotecas necesarias: pandas para manipulación de datos, numpy para operaciones numéricas y matplotlib para visualización.
    • Se crea un conjunto de datos de muestra con fechas y cifras de ventas correspondientes, que abarcan de enero a octubre de 2022.
    • La columna 'Date' se convierte a formato datetime usando pd.to_datetime().
  2. Extracción básica de características:
    • Año: Extraído para capturar tendencias a largo plazo entre años.
    • Mes: Para patrones de estacionalidad mensual.
    • Día: Día del mes, que podría ser relevante para efectos de fin de mes.
    • Día de la semana: Para capturar patrones semanales (0 = lunes, 6 = domingo).
    • Trimestre: Para tendencias trimestrales, comúnmente utilizadas en análisis financieros.
    • Semana del año: Captura patrones cíclicos anuales que no se alinean con los meses del calendario.
    • Día del año: Útil para identificar efectos estacionales anuales.
    • EsFinDeSemana: Característica binaria para diferenciar entre días de semana y fines de semana.
  3. Codificación de características cíclicas:
    • El mes y el día de la semana se codifican usando funciones seno y coseno.
    • Esto preserva la naturaleza cíclica de estas características, asegurando que, por ejemplo, diciembre (12) esté cerca de enero (1) en el espacio cíclico.
    • Las características resultantes (Mes_sin, Mes_cos, DiaSemana_sin, DiaSemana_cos) representan la naturaleza cíclica de meses y días de la semana de una forma que los modelos de machine learning pueden interpretar de manera más efectiva.
  4. Características de retraso (Lag):
    • Ventas_Lag1: Ventas del día anterior.
    • Ventas_Lag7: Ventas de hace una semana.
    • Estas características ayudan a capturar tendencias a corto plazo y semanales en los datos.
  5. Estadísticas móviles:
    • Media móvil de ventas de 7 días: Suaviza las fluctuaciones a corto plazo y captura tendencias locales.
    • Desviación estándar móvil de ventas de 7 días: Captura la volatilidad local.
  6. Visualización:
    • Se crea un gráfico de series temporales de las ventas a lo largo del tiempo para visualizar las tendencias generales.
    • Se generan gráficos de dispersión de las características de mes y día de la semana codificadas cíclicamente para ilustrar cómo se representan estas características circulares en el espacio 2D.

Este ejemplo muestra un enfoque integral para la ingeniería de características en datos de series temporales. Incluye características temporales básicas, codificación cíclica avanzada, características de retraso y estadísticas móviles. Las visualizaciones ayudan a comprender la distribución de los datos y demuestran la efectividad de la codificación cíclica. Este conjunto enriquecido de características puede mejorar significativamente el rendimiento de los modelos de pronóstico de series temporales al capturar varios patrones y dependencias temporales dentro de los datos.

9.1.4 Manejo de Características Cíclicas

Ciertas características de fecha/hora, como día de la semana o mes del año, exhiben una naturaleza cíclica, es decir, repiten un patrón predecible. Por ejemplo, los días de la semana se suceden de lunes a domingo, y después del domingo, el ciclo comienza de nuevo con el lunes. Esta propiedad cíclica es crucial en el análisis de series temporales, ya que puede revelar patrones recurrentes o estacionalidad en los datos.

Sin embargo, la mayoría de los algoritmos de machine learning no están diseñados de manera inherente para entender o interpretar esta naturaleza cíclica. Cuando estas características se codifican como valores numéricos simples (por ejemplo, lunes = 1, martes = 2, ..., domingo = 7), el algoritmo puede interpretar incorrectamente que el domingo (7) está más alejado del lunes (1) que del martes (2), lo cual no representa con precisión su relación cíclica.

Para abordar este problema, es esencial codificar las características cíclicas de una forma que preserve su naturaleza circular. Un enfoque popular y efectivo es la Codificación Seno y Coseno. Este método representa cada valor cíclico como un punto en un círculo, utilizando funciones seno y coseno para capturar la relación cíclica.

Así es como funciona la Codificación Seno y Coseno:

  1. Cada valor en el ciclo se asigna a un ángulo en un círculo (de 0 a 2π radianes).
  2. Se calculan el seno y el coseno de este ángulo, creando dos nuevas características.
  3. Estas nuevas características preservan la naturaleza cíclica de la característica original.

Por ejemplo, en el caso de los meses:

  • Enero (1) y diciembre (12) tendrán valores similares de seno y coseno, reflejando su proximidad en el ciclo anual.
  • Junio (6) y julio (7) también tendrán valores similares, pero serán notablemente diferentes de enero y diciembre.

Este método de codificación permite que los modelos de machine learning comprendan y utilicen mejor la naturaleza cíclica de estas características, mejorando su capacidad para capturar patrones estacionales y hacer predicciones más precisas en el análisis de series temporales.

Ejemplo: Codificación de una Característica Cíclica

Vamos a codificar Día de la Semana usando seno y coseno para preservar su naturaleza cíclica.

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

# Create sample data
dates = pd.date_range(start='2023-01-01', end='2023-12-31', freq='D')
sales = np.random.randint(100, 1000, size=len(dates))
df_sales = pd.DataFrame({'Date': dates, 'Sales': sales})

# Extract day of week
df_sales['DayOfWeek'] = df_sales['Date'].dt.dayofweek

# Encode day of week using sine and cosine
df_sales['DayOfWeek_sin'] = np.sin(2 * np.pi * df_sales['DayOfWeek'] / 7)
df_sales['DayOfWeek_cos'] = np.cos(2 * np.pi * df_sales['DayOfWeek'] / 7)

# Encode month using sine and cosine
df_sales['Month'] = df_sales['Date'].dt.month
df_sales['Month_sin'] = np.sin(2 * np.pi * df_sales['Month'] / 12)
df_sales['Month_cos'] = np.cos(2 * np.pi * df_sales['Month'] / 12)

# View the dataframe with cyclically encoded features
print(df_sales[['Date', 'DayOfWeek', 'DayOfWeek_sin', 'DayOfWeek_cos', 'Month', 'Month_sin', 'Month_cos', 'Sales']].head())

# Visualize cyclical encoding
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))

# Day of Week
ax1.scatter(df_sales['DayOfWeek_sin'], df_sales['DayOfWeek_cos'])
ax1.set_title('Cyclical Encoding of Day of Week')
ax1.set_xlabel('Sin(DayOfWeek)')
ax1.set_ylabel('Cos(DayOfWeek)')

# Month
ax2.scatter(df_sales['Month_sin'], df_sales['Month_cos'])
ax2.set_title('Cyclical Encoding of Month')
ax2.set_xlabel('Sin(Month)')
ax2.set_ylabel('Cos(Month)')

plt.tight_layout()
plt.show()

# Analyze sales by day of week
sales_by_day = df_sales.groupby('DayOfWeek')['Sales'].mean().sort_values(ascending=False)
print("\nAverage Sales by Day of Week:")
print(sales_by_day)

# Analyze sales by month
sales_by_month = df_sales.groupby('Month')['Sales'].mean().sort_values(ascending=False)
print("\nAverage Sales by Month:")
print(sales_by_month)

Explicación del desglose del código:

  1. Preparación de datos:
    • Importamos las bibliotecas necesarias: numpy para operaciones numéricas, pandas para manipulación de datos y matplotlib para visualización.
    • Se crea un conjunto de datos de muestra con datos de ventas diarias para todo el año 2023 usando la función date_range de pandas y valores de ventas aleatorios.
  2. Extracción de características:
    • DayOfWeek (Día de la Semana): Se extrae usando el atributo dt.dayofweek, que devuelve un valor de 0 (lunes) a 6 (domingo).
    • Month (Mes): Se extrae usando el atributo dt.month, que devuelve un valor de 1 (enero) a 12 (diciembre).
  3. Codificación de características cíclicas:
    • Los valores de DayOfWeek y Month se codifican usando funciones seno y coseno.
    • La fórmula utilizada es: sin(2π * feature / max_value) y cos(2π * feature / max_value).
    • Para DayOfWeek, el max_value es 7 (7 días en una semana).
    • Para Month, el max_value es 12 (12 meses en un año).
    • Esta codificación preserva la naturaleza cíclica de estas características, asegurando que días y meses similares estén cerca en el espacio codificado.
  4. Visualización de datos:
    • Se crean dos gráficos de dispersión para visualizar la codificación cíclica de DayOfWeek y Month.
    • Cada punto en estos gráficos representa un día/mes único, mostrando cómo se distribuyen en un patrón circular.
  5. Análisis de datos:
    • Se calculan las ventas promedio para cada día de la semana y cada mes.
    • Este análisis ayuda a identificar qué días de la semana y qué meses tienden a tener ventas más altas o más bajas.

Este ejemplo ilustra cómo realizar una codificación cíclica, visualizarla y aplicarla en un análisis básico. Al representar las características temporales de manera más precisa en los modelos de machine learning, la codificación cíclica mejora su capacidad para capturar patrones estacionales en datos de series temporales.

9.1.5 Manejo de Zonas Horarias y Fechas Faltantes

Las zonas horarias y las fechas faltantes son factores críticos que requieren una consideración cuidadosa al trabajar con datos de series temporales, especialmente en un mundo globalizado y con grandes volúmenes de datos:

  • Zonas Horarias: El desafío de las diferentes zonas horarias puede afectar significativamente la consistencia de los datos, particularmente cuando se trabaja con conjuntos de datos que abarcan múltiples regiones geográficas o contienen marcas de tiempo globales.
    • Pandas, una poderosa biblioteca de manipulación de datos en Python, ofrece soluciones robustas para manejar la complejidad de las zonas horarias. La función tz_localize() permite asignar una zona horaria específica a objetos de fecha y hora, mientras que tz_convert() facilita la conversión entre diferentes zonas horarias. Estas funciones son invaluables para mantener la precisión y consistencia en conjuntos de datos multi-regionales.
    • Por ejemplo, al analizar datos de mercados financieros de distintas bolsas de valores mundiales, el manejo adecuado de las zonas horarias garantiza que los eventos de trading estén correctamente alineados y sean comparables entre diferentes mercados.
  • Fechas Faltantes: La presencia de fechas faltantes en una serie temporal puede plantear desafíos significativos, interrumpiendo la continuidad de los datos y afectando negativamente el rendimiento del modelo.
    • Para abordar este problema, se pueden emplear varios métodos de imputación, que van desde técnicas simples como el llenado hacia adelante o hacia atrás, hasta enfoques más sofisticados como la interpolación o el uso de algoritmos de machine learning para predecir valores faltantes.
    • La elección del método de imputación depende de la naturaleza de los datos y de los requisitos específicos del análisis. Por ejemplo, en los datos de ventas minoristas, el llenado hacia adelante puede ser adecuado para fines de semana cuando las tiendas están cerradas, mientras que métodos más complejos pueden ser necesarios para valores faltantes esporádicos en datos continuos de sensores.

Abordar estos factores es crucial para mantener la integridad y confiabilidad de los análisis de series temporales. El manejo adecuado de las zonas horarias asegura que las relaciones temporales se representen con precisión entre diferentes regiones, mientras que la gestión efectiva de fechas faltantes preserva la continuidad esencial para muchas técnicas de modelado de series temporales.

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

# Create sample data with missing dates
date_range = pd.date_range(start='2023-01-01', end='2023-12-31', freq='D')
sales = np.random.randint(100, 1000, size=len(date_range))
df_sales = pd.DataFrame({'Date': date_range, 'Sales': sales})

# Introduce missing dates
df_sales = df_sales.drop(df_sales.index[10:20])  # Remove 10 days of data
df_sales = df_sales.drop(df_sales.index[150:160])  # Remove another 10 days

# Print original dataframe
print("Original DataFrame:")
print(df_sales.head(15))
print("...")
print(df_sales.tail(15))

# Handling missing dates by reindexing the data
df_sales = df_sales.set_index('Date').asfreq('D')

# Fill missing values
df_sales['Sales'] = df_sales['Sales'].fillna(method='ffill')  # forward-fill

# Reset index to make 'Date' a column again
df_sales = df_sales.reset_index()

# Print updated dataframe
print("\nUpdated DataFrame:")
print(df_sales.head(15))
print("...")
print(df_sales.tail(15))

# Visualize the data
plt.figure(figsize=(12, 6))
plt.plot(df_sales['Date'], df_sales['Sales'])
plt.title('Sales Data with Filled Missing Dates')
plt.xlabel('Date')
plt.ylabel('Sales')
plt.xticks(rotation=45)
plt.tight_layout()
plt.show()

# Basic statistics
print("\nBasic Statistics:")
print(df_sales['Sales'].describe())

# Check for any remaining missing values
print("\nRemaining Missing Values:")
print(df_sales.isnull().sum())

Explicación del desglose del código:

  1. Preparación de datos:
    • Importamos las bibliotecas necesarias: pandas para manipulación de datos, numpy para operaciones numéricas y matplotlib para visualización.
    • Se crea un conjunto de datos de ejemplo con datos de ventas diarias para todo el año 2023 usando la función date_range de pandas y cifras de ventas aleatorias.
    • Introducimos fechas faltantes intencionalmente al eliminar dos rangos de 10 días cada uno del conjunto de datos.
  2. Manejo de fechas faltantes:
    • Usamos set_index('Date').asfreq('D') para reindexar el DataFrame con un rango completo de fechas en frecuencia diaria ('D').
    • Esta operación introduce valores NaN para las ventas en las fechas que estaban previamente ausentes.
  3. Relleno de valores faltantes:
    • Usamos fillna(method='ffill') para realizar un llenado hacia adelante de los valores de ventas faltantes.
    • Esto significa que cada valor faltante se completa con la última cifra de ventas conocida.
  4. Visualización de datos:
    • Creamos un gráfico de líneas de los datos de ventas a lo largo del tiempo usando matplotlib.
    • Esta visualización ayuda a identificar cualquier brecha restante o patrones inusuales en los datos.
  5. Análisis de datos:
    • Imprimimos estadísticas descriptivas básicas de los datos de ventas usando el método describe().
    • También verificamos si quedan valores faltantes en el conjunto de datos.

Este ejemplo muestra un enfoque exhaustivo para gestionar fechas faltantes en datos de series temporales. Abarca la creación de un conjunto de datos, la introducción deliberada de brechas, la gestión de esas fechas faltantes, la visualización de los resultados y la realización de un análisis estadístico básico. Este proceso integral asegura la continuidad de los datos, un factor crítico para muchas técnicas de análisis de series temporales.

9.1.6 Puntos clave y sus implicaciones

  • Características de fecha y hora son fundamentales para la previsión de series temporales, permitiendo que los modelos distingan patrones complejos:
    • Estacionalidad: Patrones recurrentes asociados a períodos del calendario (ej., picos de ventas en vacaciones).
    • Tendencias: Movimientos direccionales a largo plazo en los datos.
    • Ciclos: Fluctuaciones no ligadas a períodos del calendario (ej., ciclos económicos).
  • Extracción de componentes de fecha y hora mejora el rendimiento del modelo:
    • Patrones a nivel de días: Capturando ritmos semanales en los datos.
    • Efectos de mes y trimestre: Identificando tendencias estacionales más amplias.
    • Comparaciones año a año: Permiten el reconocimiento de patrones a largo plazo.
  • Codificación cíclica preserva la naturaleza circular de ciertas características de tiempo:
    • Día de la semana: Asegura que el lunes y el domingo se reconozcan como días adyacentes.
    • Mes del año: Mantiene la naturaleza continua de los meses entre años.
    • Precisión mejorada del modelo: Ayuda a los algoritmos a comprender efectos circulares.
  • Manejo de fechas faltantes y zonas horarias es crucial para la integridad de los datos:
    • Consistencia de datos globales: Alineación de puntos de datos de diferentes regiones.
    • Gestión de datos de alta frecuencia: Asegura precisión en marcas de tiempo a nivel de milisegundos.
    • Estrategias de imputación: Selección de métodos adecuados para rellenar huecos sin introducir sesgos.

Al dominar estos conceptos, los científicos de datos pueden construir modelos de series temporales más robustos y precisos, logrando mejores predicciones y una comprensión más profunda en áreas como finanzas, predicción del clima y previsión de demanda.

9.1 Trabajando con Características de Fecha/Hora

Trabajar con datos de series temporales presenta desafíos y requisitos únicos que los diferencian de los conjuntos de datos estáticos. Los datos de series temporales se caracterizan por su orden temporal, donde cada observación está intrínsecamente vinculada al momento en que fue registrada. Esta dependencia temporal introduce complejidades que requieren enfoques analíticos especializados. Ya sea que estés pronosticando tendencias de ventas, prediciendo fluctuaciones en los precios de las acciones o analizando patrones climáticos complejos, una comprensión profunda de los datos de series temporales es crucial para modelar e interpretar con precisión los patrones, tendencias y estacionalidades subyacentes en los datos.

El análisis de series temporales nos permite descubrir conocimientos ocultos y hacer predicciones fundamentadas aprovechando la naturaleza temporal de los datos. Nos permite capturar no solo el estado actual de un sistema, sino también cómo evoluciona con el tiempo. Esta dimensión temporal agrega una capa de complejidad a nuestro análisis, pero también proporciona información valiosa sobre la dinámica del sistema que estamos estudiando.

Este capítulo profundizará en las consideraciones y técnicas específicas esenciales para manejar los datos de series temporales de manera efectiva. Comenzaremos explorando el rol crítico de las características de fecha y hora, discutiendo técnicas avanzadas para manejar información temporal. Esto incluye métodos para extraer características significativas de las marcas de tiempo, lidiar con diferentes escalas de tiempo y abordar desafíos como intervalos de muestreo irregulares o puntos de datos faltantes.

A continuación, profundizaremos en métodos sofisticados para descomponer los datos de series temporales. Este paso crucial nos permite desglosar una serie temporal compleja en sus componentes: tendencias, que representan la progresión a largo plazo; estacionalidad, que captura patrones cíclicos; y residuos, que representan las fluctuaciones aleatorias en los datos. Comprender estos componentes es clave para construir modelos predictivos precisos y obtener conocimientos sobre los impulsores subyacentes de los patrones observados.

Finalmente, abordaremos el concepto de estacionariedad y su profunda importancia para el modelado predictivo en el análisis de series temporales. Exploraremos por qué la estacionariedad es un supuesto crucial para muchos modelos de series temporales y discutiremos varias pruebas para determinar si una serie es estacionaria. Además, profundizaremos en técnicas avanzadas para transformar datos no estacionarios en una forma estacionaria, como diferenciación, eliminación de tendencias y enfoques más sofisticados como la transformación de Box-Cox. Al dominar estos conceptos y técnicas, estarás bien equipado para manejar una amplia gama de desafíos de series temporales y extraer información significativa de los datos temporales.

Cuando trabajamos con datos de series temporales, los elementos de fecha y hora sirven como el eje central para entender y predecir patrones temporales. Las características de fecha y hora no son solo identificadores simples; son fuentes ricas de información que pueden revelar tendencias complejas, estacionalidades y patrones cíclicos dentro de los datos. Estas características proporcionan un contexto temporal crucial para una interpretación y pronóstico precisos.

El poder de las características de fecha y hora radica en su capacidad para capturar relaciones temporales tanto obvias como sutiles. Por ejemplo, pueden revelar ciclos anuales en los datos de ventas, fluctuaciones mensuales en la temperatura o incluso patrones horarios en el tráfico de sitios web. Al extraer y utilizar adecuadamente estas características, los analistas pueden descubrir periodicidades ocultas y tendencias a largo plazo que de otro modo podrían pasar desapercibidas.

Además, aprovechar las características de fecha y hora de manera efectiva puede conducir a mejoras significativas en la precisión del modelo. Al incorporar estos conocimientos temporales, los modelos pueden aprender a reconocer y predecir patrones que están intrínsecamente ligados a períodos específicos. Esto puede ser especialmente valioso en campos como las finanzas, donde los comportamientos del mercado a menudo siguen patrones temporales complejos, o en el pronóstico del consumo de energía, donde los patrones de uso varían considerablemente dependiendo de la hora del día, el día de la semana o la temporada del año.

El proceso de trabajar con características de fecha y hora implica más que simplemente incluirlas en un conjunto de datos. Requiere una consideración cuidadosa de cómo representar y codificar estas características para maximizar su valor informativo. Esto puede implicar técnicas como la codificación cíclica para características como días de la semana o meses, o la creación de características de retraso para capturar efectos de tiempo diferido. Al diseñar estas características de manera reflexiva, los analistas pueden dotar a sus modelos de una comprensión matizada del tiempo, lo que permite predicciones más sofisticadas y precisas.

9.1.1 Características Comunes de Fecha/Hora y Su Importancia

Las características de fecha y hora juegan un papel crucial en el análisis de series temporales, proporcionando información valiosa sobre patrones temporales. Exploremos algunas características clave y su importancia:

  • Año, Mes, Día: Estos componentes básicos son fundamentales para capturar tendencias a largo plazo y variaciones estacionales. Por ejemplo, los negocios minoristas suelen experimentar ciclos de ventas anuales, con picos durante las temporadas de vacaciones. De manera similar, los datos de temperatura muestran típicamente fluctuaciones mensuales, permitiéndonos rastrear patrones climáticos con el tiempo.
  • Día de la Semana: Esta característica es particularmente útil para identificar ritmos semanales en los datos. Muchas industrias, como restaurantes o lugares de entretenimiento, ven diferencias significativas entre las actividades de entre semana y de fin de semana. Al incorporar esta característica, los modelos pueden aprender a anticipar estas fluctuaciones regulares.
  • Trimestre: Los datos trimestrales son especialmente relevantes en contextos financieros. Muchas empresas reportan ganancias y establecen metas en una base trimestral, lo que hace que esta característica sea invaluable para analizar tendencias fiscales y realizar predicciones económicas.
  • Hora y Minuto: Para datos de alta frecuencia, estos componentes de tiempo granulares son esenciales. Pueden revelar patrones intrincados en el consumo de energía, donde el uso puede aumentar durante ciertas horas del día, o en el flujo de tráfico, donde los patrones de horas pico se vuelven evidentes.
  • Días Festivos y Eventos Especiales: Aunque no se mencionó en la lista original, estos pueden ser características cruciales. Muchas empresas ven cambios significativos en la actividad durante días festivos o eventos especiales, lo que puede impactar en gran medida las predicciones de series temporales.

Al aprovechar estas características temporales, podemos construir modelos que no solo reconocen patrones recurrentes y estacionalidades, sino que también se adaptan a las características únicas de diferentes escalas de tiempo. Este enfoque integral permite predicciones más matizadas y precisas, capturando tanto los trazos generales de las tendencias a largo plazo como los detalles de las fluctuaciones a corto plazo. Comprender y utilizar adecuadamente estas características es clave para desbloquear el potencial completo del análisis de series temporales en diversos dominios, desde finanzas y ventas minoristas hasta gestión de energía y planificación urbana.

9.1.2 Extrayendo Características de Fecha/Hora en Python

Pandas proporciona una interfaz poderosa e intuitiva para manejar características de fecha y hora en datos de series temporales. La funcionalidad Datetime de la biblioteca ofrece un conjunto completo de herramientas que simplifican la tarea, a menudo compleja, de trabajar con datos temporales. Con Pandas, podemos analizar fechas desde varios formatos, extraer componentes temporales específicos y transformar columnas de fechas en representaciones más amigables para el análisis.

Las capacidades de análisis de Pandas nos permiten convertir representaciones de fechas en cadena a objetos datetime, infiriendo automáticamente el formato en muchos casos. Esto es particularmente útil cuando se trabaja con conjuntos de datos que contienen fechas en formatos inconsistentes o no estándar. Una vez analizadas, podemos extraer fácilmente una amplia gama de características temporales, como año, mes, día, hora, minuto, segundo, día de la semana, trimestre e incluso períodos fiscales.

Además, Pandas nos permite realizar aritmética de fechas sofisticada, facilitando el cálculo de diferencias de tiempo, la adición o sustracción de períodos de tiempo o el remuestreo de datos a diferentes frecuencias de tiempo. Esta flexibilidad es crucial al preparar datos de series temporales para análisis o modelado, ya que nos permite alinear puntos de datos, crear características de retraso o agregar datos en ventanas de tiempo personalizadas.

Al aprovechar la funcionalidad de fecha y hora de Pandas, podemos transformar datos temporales sin procesar en un conjunto rico de características que capturan los patrones subyacentes y la estacionalidad en nuestras series temporales. Este paso de preprocesamiento es a menudo crítico para desarrollar modelos de pronóstico precisos o realizar un análisis significativo de series temporales en diversos dominios, desde finanzas y economía hasta estudios ambientales y más allá.

Ejemplo: Extrayendo Características Básicas de Fecha/Hora

Comencemos con un conjunto de datos que incluye una columna de Fecha. Demostraremos cómo analizar fechas y extraer características como AñoMesDía de la Semana y Trimestre.

import pandas as pd

# Sample data with dates
data = {'Date': ['2022-01-15', '2022-02-10', '2022-03-20', '2022-04-15', '2022-05-25']}
df = pd.DataFrame(data)

# Convert Date column to datetime format
df['Date'] = pd.to_datetime(df['Date'])

# Extract date/time features
df['Year'] = df['Date'].dt.year
df['Month'] = df['Date'].dt.month
df['Day'] = df['Date'].dt.day
df['DayOfWeek'] = df['Date'].dt.dayofweek
df['Quarter'] = df['Date'].dt.quarter

print(df)

Este código demuestra cómo extraer características de fecha y hora de un conjunto de datos utilizando pandas en Python. A continuación se detalla qué hace el código:

  • Primero, importa la biblioteca pandas, esencial para la manipulación de datos en Python.
  • Crea un conjunto de datos de muestra con una columna 'Date' que contiene cinco cadenas de fechas.
  • Luego, los datos se convierten en un DataFrame de pandas.
  • La columna 'Date' se convierte del formato de cadena a formato datetime usando pd.to_datetime(). Este paso es crucial para realizar operaciones basadas en fechas.
  • El código luego extrae varias características de fecha/hora de la columna 'Date':
    • Year: Extrae el año de cada fecha.
    • Month: Extrae el mes (1-12).
    • Day: Extrae el día del mes.
    • DayOfWeek: Extrae el día de la semana (0-6, donde 0 es lunes).
    • Quarter: Extrae el trimestre del año (1-4).
  • Finalmente, imprime el DataFrame resultante, que ahora incluye estas nuevas características de fecha/hora junto con la columna original 'Date'.

Este código es particularmente útil para el análisis de series temporales, ya que permite capturar diversos aspectos temporales de los datos, los cuales se pueden utilizar para identificar patrones, estacionalidad o tendencias en el conjunto de datos.

Exploremos un ejemplo más completo.

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

# Sample data with dates and sales
data = {
    'Date': ['2022-01-15', '2022-02-10', '2022-03-20', '2022-04-15', '2022-05-25', 
             '2022-06-30', '2022-07-05', '2022-08-12', '2022-09-18', '2022-10-22'],
    'Sales': [1000, 1200, 1500, 1300, 1800, 2000, 1900, 2200, 2100, 2300]
}
df = pd.DataFrame(data)

# Convert Date column to datetime format
df['Date'] = pd.to_datetime(df['Date'])

# Extract basic date/time features
df['Year'] = df['Date'].dt.year
df['Month'] = df['Date'].dt.month
df['Day'] = df['Date'].dt.day
df['DayOfWeek'] = df['Date'].dt.dayofweek
df['Quarter'] = df['Date'].dt.quarter

# Extract additional features
df['WeekOfYear'] = df['Date'].dt.isocalendar().week
df['DayOfYear'] = df['Date'].dt.dayofyear
df['IsWeekend'] = df['DayOfWeek'].isin([5, 6]).astype(int)

# Create cyclical features for Month and DayOfWeek
df['Month_sin'] = np.sin(2 * np.pi * df['Month'] / 12)
df['Month_cos'] = np.cos(2 * np.pi * df['Month'] / 12)
df['DayOfWeek_sin'] = np.sin(2 * np.pi * df['DayOfWeek'] / 7)
df['DayOfWeek_cos'] = np.cos(2 * np.pi * df['DayOfWeek'] / 7)

# Create lag features
df['Sales_Lag1'] = df['Sales'].shift(1)
df['Sales_Lag7'] = df['Sales'].shift(7)

# Calculate rolling mean
df['Sales_RollingMean7'] = df['Sales'].rolling(window=7, min_periods=1).mean()

# Print the resulting dataframe
print(df)

# Visualize sales over time
plt.figure(figsize=(12, 6))
plt.plot(df['Date'], df['Sales'])
plt.title('Sales Over Time')
plt.xlabel('Date')
plt.ylabel('Sales')
plt.xticks(rotation=45)
plt.tight_layout()
plt.show()

# Visualize cyclical features
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))
ax1.scatter(df['Month_sin'], df['Month_cos'])
ax1.set_title('Cyclical Encoding of Month')
ax1.set_xlabel('Sin(Month)')
ax1.set_ylabel('Cos(Month)')
ax2.scatter(df['DayOfWeek_sin'], df['DayOfWeek_cos'])
ax2.set_title('Cyclical Encoding of Day of Week')
ax2.set_xlabel('Sin(DayOfWeek)')
ax2.set_ylabel('Cos(DayOfWeek)')
plt.tight_layout()
plt.show()

Explicación del desglose del código:

  1. Preparación de datos:
    • Comenzamos importando las bibliotecas necesarias: pandas para manipulación de datos, numpy para operaciones numéricas y matplotlib para visualización.
    • Se crea un conjunto de datos de muestra con fechas y cifras de ventas correspondientes.
    • La columna 'Date' se convierte a formato datetime usando pd.to_datetime().
  2. Extracción básica de características:
    • Extraemos características fundamentales de fecha/hora:
      • Año, Mes, Día: Componentes básicos de la fecha.
      • Día de la semana: Útil para captar patrones semanales (0 = lunes, 6 = domingo).
      • Trimestre: Para tendencias trimestrales, comúnmente utilizadas en análisis financieros.
  3. Extracción avanzada de características:
    • Semana del año: Captura patrones cíclicos anuales.
    • Día del año: Útil para identificar efectos estacionales anuales.
    • EsFinDeSemana: Característica binaria para diferenciar entre días de semana y fines de semana.
  4. Codificación de características cíclicas:
    • El mes y el día de la semana se codifican usando funciones seno y coseno.
    • Esto conserva la naturaleza cíclica de estas características, asegurando que, por ejemplo, diciembre (12) esté cerca de enero (1) en el espacio cíclico.
  5. Características de retraso (Lag):
    • Ventas_Lag1: Ventas del día anterior.
    • Ventas_Lag7: Ventas de hace una semana.
    • Estas características ayudan a capturar tendencias a corto plazo y semanales.
  6. Estadísticas móviles:
    • Media móvil de ventas de 7 días: Suaviza las fluctuaciones a corto plazo y destaca tendencias a largo plazo.
  7. Visualización:
    • Se crea un gráfico de series temporales de las ventas a lo largo del tiempo para visualizar las tendencias generales.
    • Se generan gráficos de dispersión de las características de mes y día de la semana codificadas cíclicamente para ilustrar cómo se representan estas características circulares en el espacio 2D.

Este ejemplo ampliado demuestra un enfoque más completo para la ingeniería de características en datos de series temporales. Incluye características temporales básicas, codificación cíclica avanzada, características de retraso y estadísticas móviles. Las visualizaciones ayudan a comprender la distribución de los datos y la efectividad de la codificación cíclica. Este conjunto enriquecido de características puede mejorar significativamente el rendimiento de los modelos de pronóstico de series temporales al capturar varios patrones y dependencias temporales en los datos.

9.1.3 Uso de características de fecha y hora en el modelo

Al incorporar características de fecha y hora en el modelo, es crucial seleccionar cuidadosamente aquellas que realmente mejoren su capacidad predictiva. La relevancia de estas características puede variar considerablemente según la naturaleza de los datos y el problema a resolver. Por ejemplo:

  • Día de la semana es particularmente valioso en conjuntos de datos de venta minorista, donde el comportamiento del consumidor sigue patrones distintos a lo largo de la semana. Esta característica puede ayudar a capturar la diferencia entre las ventas de días de semana y de fin de semana, o incluso patrones más sutiles como caídas a mitad de semana o picos al final de la semana.
  • Mes es excelente para captar ciclos estacionales que ocurren anualmente. Esto podría ser útil en diversos dominios como el comercio minorista (temporadas de compras), el turismo (meses pico de viajes) o la agricultura (ciclos de cultivo).
  • Año es fundamental para captar tendencias a largo plazo, lo cual es especialmente importante en conjuntos de datos que abarcan varios años. Esta característica puede ayudar a que los modelos tengan en cuenta cambios graduales en la distribución de datos subyacente, como el crecimiento o la disminución del mercado.

No obstante, la utilidad de estas características no se limita solo a estos ejemplos. La hora del día podría ser crucial para modelar el consumo de energía o los patrones de tráfico. Trimestre podría ser más adecuado que el mes para ciertas métricas comerciales que operan en un ciclo trimestral. Semana del año podría capturar patrones que se repiten anualmente pero no se alinean perfectamente con los meses del calendario.

También vale la pena considerar características derivadas. En lugar de componentes de fecha en bruto, se podrían crear indicadores booleanos como "Es_Feriado" o "Es_DíaDePago", o calcular el número de días desde un evento significativo. La clave es reflexionar sobre qué patrones temporales podrían existir en los datos y experimentar con diferentes combinaciones de características para encontrar la que mejor se adapte al caso de uso específico.

Ejemplo: Adición de características de fecha y hora a un modelo de pronóstico de ventas

Apliquemos nuestras características de fecha a un conjunto de datos de pronóstico de ventas.

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

# Sample sales data with dates
sales_data = {
    'Date': ['2022-01-15', '2022-02-10', '2022-03-20', '2022-04-15', '2022-05-25', 
             '2022-06-30', '2022-07-05', '2022-08-12', '2022-09-18', '2022-10-22'],
    'Sales': [200, 220, 250, 210, 230, 280, 260, 300, 290, 310]
}
df_sales = pd.DataFrame(sales_data)

# Convert Date to datetime and extract date/time features
df_sales['Date'] = pd.to_datetime(df_sales['Date'])
df_sales['Year'] = df_sales['Date'].dt.year
df_sales['Month'] = df_sales['Date'].dt.month
df_sales['Day'] = df_sales['Date'].dt.day
df_sales['DayOfWeek'] = df_sales['Date'].dt.dayofweek
df_sales['Quarter'] = df_sales['Date'].dt.quarter
df_sales['WeekOfYear'] = df_sales['Date'].dt.isocalendar().week
df_sales['DayOfYear'] = df_sales['Date'].dt.dayofyear
df_sales['IsWeekend'] = df_sales['DayOfWeek'].isin([5, 6]).astype(int)

# Create cyclical features for Month and DayOfWeek
df_sales['Month_sin'] = np.sin(2 * np.pi * df_sales['Month'] / 12)
df_sales['Month_cos'] = np.cos(2 * np.pi * df_sales['Month'] / 12)
df_sales['DayOfWeek_sin'] = np.sin(2 * np.pi * df_sales['DayOfWeek'] / 7)
df_sales['DayOfWeek_cos'] = np.cos(2 * np.pi * df_sales['DayOfWeek'] / 7)

# Create lag features
df_sales['Sales_Lag1'] = df_sales['Sales'].shift(1)
df_sales['Sales_Lag7'] = df_sales['Sales'].shift(7)

# Calculate rolling statistics
df_sales['Sales_RollingMean7'] = df_sales['Sales'].rolling(window=7, min_periods=1).mean()
df_sales['Sales_RollingStd7'] = df_sales['Sales'].rolling(window=7, min_periods=1).std()

# View dataset with extracted features
print(df_sales)

# Visualize sales over time
plt.figure(figsize=(12, 6))
plt.plot(df_sales['Date'], df_sales['Sales'])
plt.title('Sales Over Time')
plt.xlabel('Date')
plt.ylabel('Sales')
plt.xticks(rotation=45)
plt.tight_layout()
plt.show()

# Visualize cyclical features
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))
ax1.scatter(df_sales['Month_sin'], df_sales['Month_cos'])
ax1.set_title('Cyclical Encoding of Month')
ax1.set_xlabel('Sin(Month)')
ax1.set_ylabel('Cos(Month)')
ax2.scatter(df_sales['DayOfWeek_sin'], df_sales['DayOfWeek_cos'])
ax2.set_title('Cyclical Encoding of Day of Week')
ax2.set_xlabel('Sin(DayOfWeek)')
ax2.set_ylabel('Cos(DayOfWeek)')
plt.tight_layout()
plt.show()

Explicación completa del desglose:

  1. Preparación de datos:
    • Importamos las bibliotecas necesarias: pandas para manipulación de datos, numpy para operaciones numéricas y matplotlib para visualización.
    • Se crea un conjunto de datos de muestra con fechas y cifras de ventas correspondientes, que abarcan de enero a octubre de 2022.
    • La columna 'Date' se convierte a formato datetime usando pd.to_datetime().
  2. Extracción básica de características:
    • Año: Extraído para capturar tendencias a largo plazo entre años.
    • Mes: Para patrones de estacionalidad mensual.
    • Día: Día del mes, que podría ser relevante para efectos de fin de mes.
    • Día de la semana: Para capturar patrones semanales (0 = lunes, 6 = domingo).
    • Trimestre: Para tendencias trimestrales, comúnmente utilizadas en análisis financieros.
    • Semana del año: Captura patrones cíclicos anuales que no se alinean con los meses del calendario.
    • Día del año: Útil para identificar efectos estacionales anuales.
    • EsFinDeSemana: Característica binaria para diferenciar entre días de semana y fines de semana.
  3. Codificación de características cíclicas:
    • El mes y el día de la semana se codifican usando funciones seno y coseno.
    • Esto preserva la naturaleza cíclica de estas características, asegurando que, por ejemplo, diciembre (12) esté cerca de enero (1) en el espacio cíclico.
    • Las características resultantes (Mes_sin, Mes_cos, DiaSemana_sin, DiaSemana_cos) representan la naturaleza cíclica de meses y días de la semana de una forma que los modelos de machine learning pueden interpretar de manera más efectiva.
  4. Características de retraso (Lag):
    • Ventas_Lag1: Ventas del día anterior.
    • Ventas_Lag7: Ventas de hace una semana.
    • Estas características ayudan a capturar tendencias a corto plazo y semanales en los datos.
  5. Estadísticas móviles:
    • Media móvil de ventas de 7 días: Suaviza las fluctuaciones a corto plazo y captura tendencias locales.
    • Desviación estándar móvil de ventas de 7 días: Captura la volatilidad local.
  6. Visualización:
    • Se crea un gráfico de series temporales de las ventas a lo largo del tiempo para visualizar las tendencias generales.
    • Se generan gráficos de dispersión de las características de mes y día de la semana codificadas cíclicamente para ilustrar cómo se representan estas características circulares en el espacio 2D.

Este ejemplo muestra un enfoque integral para la ingeniería de características en datos de series temporales. Incluye características temporales básicas, codificación cíclica avanzada, características de retraso y estadísticas móviles. Las visualizaciones ayudan a comprender la distribución de los datos y demuestran la efectividad de la codificación cíclica. Este conjunto enriquecido de características puede mejorar significativamente el rendimiento de los modelos de pronóstico de series temporales al capturar varios patrones y dependencias temporales dentro de los datos.

9.1.4 Manejo de Características Cíclicas

Ciertas características de fecha/hora, como día de la semana o mes del año, exhiben una naturaleza cíclica, es decir, repiten un patrón predecible. Por ejemplo, los días de la semana se suceden de lunes a domingo, y después del domingo, el ciclo comienza de nuevo con el lunes. Esta propiedad cíclica es crucial en el análisis de series temporales, ya que puede revelar patrones recurrentes o estacionalidad en los datos.

Sin embargo, la mayoría de los algoritmos de machine learning no están diseñados de manera inherente para entender o interpretar esta naturaleza cíclica. Cuando estas características se codifican como valores numéricos simples (por ejemplo, lunes = 1, martes = 2, ..., domingo = 7), el algoritmo puede interpretar incorrectamente que el domingo (7) está más alejado del lunes (1) que del martes (2), lo cual no representa con precisión su relación cíclica.

Para abordar este problema, es esencial codificar las características cíclicas de una forma que preserve su naturaleza circular. Un enfoque popular y efectivo es la Codificación Seno y Coseno. Este método representa cada valor cíclico como un punto en un círculo, utilizando funciones seno y coseno para capturar la relación cíclica.

Así es como funciona la Codificación Seno y Coseno:

  1. Cada valor en el ciclo se asigna a un ángulo en un círculo (de 0 a 2π radianes).
  2. Se calculan el seno y el coseno de este ángulo, creando dos nuevas características.
  3. Estas nuevas características preservan la naturaleza cíclica de la característica original.

Por ejemplo, en el caso de los meses:

  • Enero (1) y diciembre (12) tendrán valores similares de seno y coseno, reflejando su proximidad en el ciclo anual.
  • Junio (6) y julio (7) también tendrán valores similares, pero serán notablemente diferentes de enero y diciembre.

Este método de codificación permite que los modelos de machine learning comprendan y utilicen mejor la naturaleza cíclica de estas características, mejorando su capacidad para capturar patrones estacionales y hacer predicciones más precisas en el análisis de series temporales.

Ejemplo: Codificación de una Característica Cíclica

Vamos a codificar Día de la Semana usando seno y coseno para preservar su naturaleza cíclica.

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

# Create sample data
dates = pd.date_range(start='2023-01-01', end='2023-12-31', freq='D')
sales = np.random.randint(100, 1000, size=len(dates))
df_sales = pd.DataFrame({'Date': dates, 'Sales': sales})

# Extract day of week
df_sales['DayOfWeek'] = df_sales['Date'].dt.dayofweek

# Encode day of week using sine and cosine
df_sales['DayOfWeek_sin'] = np.sin(2 * np.pi * df_sales['DayOfWeek'] / 7)
df_sales['DayOfWeek_cos'] = np.cos(2 * np.pi * df_sales['DayOfWeek'] / 7)

# Encode month using sine and cosine
df_sales['Month'] = df_sales['Date'].dt.month
df_sales['Month_sin'] = np.sin(2 * np.pi * df_sales['Month'] / 12)
df_sales['Month_cos'] = np.cos(2 * np.pi * df_sales['Month'] / 12)

# View the dataframe with cyclically encoded features
print(df_sales[['Date', 'DayOfWeek', 'DayOfWeek_sin', 'DayOfWeek_cos', 'Month', 'Month_sin', 'Month_cos', 'Sales']].head())

# Visualize cyclical encoding
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))

# Day of Week
ax1.scatter(df_sales['DayOfWeek_sin'], df_sales['DayOfWeek_cos'])
ax1.set_title('Cyclical Encoding of Day of Week')
ax1.set_xlabel('Sin(DayOfWeek)')
ax1.set_ylabel('Cos(DayOfWeek)')

# Month
ax2.scatter(df_sales['Month_sin'], df_sales['Month_cos'])
ax2.set_title('Cyclical Encoding of Month')
ax2.set_xlabel('Sin(Month)')
ax2.set_ylabel('Cos(Month)')

plt.tight_layout()
plt.show()

# Analyze sales by day of week
sales_by_day = df_sales.groupby('DayOfWeek')['Sales'].mean().sort_values(ascending=False)
print("\nAverage Sales by Day of Week:")
print(sales_by_day)

# Analyze sales by month
sales_by_month = df_sales.groupby('Month')['Sales'].mean().sort_values(ascending=False)
print("\nAverage Sales by Month:")
print(sales_by_month)

Explicación del desglose del código:

  1. Preparación de datos:
    • Importamos las bibliotecas necesarias: numpy para operaciones numéricas, pandas para manipulación de datos y matplotlib para visualización.
    • Se crea un conjunto de datos de muestra con datos de ventas diarias para todo el año 2023 usando la función date_range de pandas y valores de ventas aleatorios.
  2. Extracción de características:
    • DayOfWeek (Día de la Semana): Se extrae usando el atributo dt.dayofweek, que devuelve un valor de 0 (lunes) a 6 (domingo).
    • Month (Mes): Se extrae usando el atributo dt.month, que devuelve un valor de 1 (enero) a 12 (diciembre).
  3. Codificación de características cíclicas:
    • Los valores de DayOfWeek y Month se codifican usando funciones seno y coseno.
    • La fórmula utilizada es: sin(2π * feature / max_value) y cos(2π * feature / max_value).
    • Para DayOfWeek, el max_value es 7 (7 días en una semana).
    • Para Month, el max_value es 12 (12 meses en un año).
    • Esta codificación preserva la naturaleza cíclica de estas características, asegurando que días y meses similares estén cerca en el espacio codificado.
  4. Visualización de datos:
    • Se crean dos gráficos de dispersión para visualizar la codificación cíclica de DayOfWeek y Month.
    • Cada punto en estos gráficos representa un día/mes único, mostrando cómo se distribuyen en un patrón circular.
  5. Análisis de datos:
    • Se calculan las ventas promedio para cada día de la semana y cada mes.
    • Este análisis ayuda a identificar qué días de la semana y qué meses tienden a tener ventas más altas o más bajas.

Este ejemplo ilustra cómo realizar una codificación cíclica, visualizarla y aplicarla en un análisis básico. Al representar las características temporales de manera más precisa en los modelos de machine learning, la codificación cíclica mejora su capacidad para capturar patrones estacionales en datos de series temporales.

9.1.5 Manejo de Zonas Horarias y Fechas Faltantes

Las zonas horarias y las fechas faltantes son factores críticos que requieren una consideración cuidadosa al trabajar con datos de series temporales, especialmente en un mundo globalizado y con grandes volúmenes de datos:

  • Zonas Horarias: El desafío de las diferentes zonas horarias puede afectar significativamente la consistencia de los datos, particularmente cuando se trabaja con conjuntos de datos que abarcan múltiples regiones geográficas o contienen marcas de tiempo globales.
    • Pandas, una poderosa biblioteca de manipulación de datos en Python, ofrece soluciones robustas para manejar la complejidad de las zonas horarias. La función tz_localize() permite asignar una zona horaria específica a objetos de fecha y hora, mientras que tz_convert() facilita la conversión entre diferentes zonas horarias. Estas funciones son invaluables para mantener la precisión y consistencia en conjuntos de datos multi-regionales.
    • Por ejemplo, al analizar datos de mercados financieros de distintas bolsas de valores mundiales, el manejo adecuado de las zonas horarias garantiza que los eventos de trading estén correctamente alineados y sean comparables entre diferentes mercados.
  • Fechas Faltantes: La presencia de fechas faltantes en una serie temporal puede plantear desafíos significativos, interrumpiendo la continuidad de los datos y afectando negativamente el rendimiento del modelo.
    • Para abordar este problema, se pueden emplear varios métodos de imputación, que van desde técnicas simples como el llenado hacia adelante o hacia atrás, hasta enfoques más sofisticados como la interpolación o el uso de algoritmos de machine learning para predecir valores faltantes.
    • La elección del método de imputación depende de la naturaleza de los datos y de los requisitos específicos del análisis. Por ejemplo, en los datos de ventas minoristas, el llenado hacia adelante puede ser adecuado para fines de semana cuando las tiendas están cerradas, mientras que métodos más complejos pueden ser necesarios para valores faltantes esporádicos en datos continuos de sensores.

Abordar estos factores es crucial para mantener la integridad y confiabilidad de los análisis de series temporales. El manejo adecuado de las zonas horarias asegura que las relaciones temporales se representen con precisión entre diferentes regiones, mientras que la gestión efectiva de fechas faltantes preserva la continuidad esencial para muchas técnicas de modelado de series temporales.

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

# Create sample data with missing dates
date_range = pd.date_range(start='2023-01-01', end='2023-12-31', freq='D')
sales = np.random.randint(100, 1000, size=len(date_range))
df_sales = pd.DataFrame({'Date': date_range, 'Sales': sales})

# Introduce missing dates
df_sales = df_sales.drop(df_sales.index[10:20])  # Remove 10 days of data
df_sales = df_sales.drop(df_sales.index[150:160])  # Remove another 10 days

# Print original dataframe
print("Original DataFrame:")
print(df_sales.head(15))
print("...")
print(df_sales.tail(15))

# Handling missing dates by reindexing the data
df_sales = df_sales.set_index('Date').asfreq('D')

# Fill missing values
df_sales['Sales'] = df_sales['Sales'].fillna(method='ffill')  # forward-fill

# Reset index to make 'Date' a column again
df_sales = df_sales.reset_index()

# Print updated dataframe
print("\nUpdated DataFrame:")
print(df_sales.head(15))
print("...")
print(df_sales.tail(15))

# Visualize the data
plt.figure(figsize=(12, 6))
plt.plot(df_sales['Date'], df_sales['Sales'])
plt.title('Sales Data with Filled Missing Dates')
plt.xlabel('Date')
plt.ylabel('Sales')
plt.xticks(rotation=45)
plt.tight_layout()
plt.show()

# Basic statistics
print("\nBasic Statistics:")
print(df_sales['Sales'].describe())

# Check for any remaining missing values
print("\nRemaining Missing Values:")
print(df_sales.isnull().sum())

Explicación del desglose del código:

  1. Preparación de datos:
    • Importamos las bibliotecas necesarias: pandas para manipulación de datos, numpy para operaciones numéricas y matplotlib para visualización.
    • Se crea un conjunto de datos de ejemplo con datos de ventas diarias para todo el año 2023 usando la función date_range de pandas y cifras de ventas aleatorias.
    • Introducimos fechas faltantes intencionalmente al eliminar dos rangos de 10 días cada uno del conjunto de datos.
  2. Manejo de fechas faltantes:
    • Usamos set_index('Date').asfreq('D') para reindexar el DataFrame con un rango completo de fechas en frecuencia diaria ('D').
    • Esta operación introduce valores NaN para las ventas en las fechas que estaban previamente ausentes.
  3. Relleno de valores faltantes:
    • Usamos fillna(method='ffill') para realizar un llenado hacia adelante de los valores de ventas faltantes.
    • Esto significa que cada valor faltante se completa con la última cifra de ventas conocida.
  4. Visualización de datos:
    • Creamos un gráfico de líneas de los datos de ventas a lo largo del tiempo usando matplotlib.
    • Esta visualización ayuda a identificar cualquier brecha restante o patrones inusuales en los datos.
  5. Análisis de datos:
    • Imprimimos estadísticas descriptivas básicas de los datos de ventas usando el método describe().
    • También verificamos si quedan valores faltantes en el conjunto de datos.

Este ejemplo muestra un enfoque exhaustivo para gestionar fechas faltantes en datos de series temporales. Abarca la creación de un conjunto de datos, la introducción deliberada de brechas, la gestión de esas fechas faltantes, la visualización de los resultados y la realización de un análisis estadístico básico. Este proceso integral asegura la continuidad de los datos, un factor crítico para muchas técnicas de análisis de series temporales.

9.1.6 Puntos clave y sus implicaciones

  • Características de fecha y hora son fundamentales para la previsión de series temporales, permitiendo que los modelos distingan patrones complejos:
    • Estacionalidad: Patrones recurrentes asociados a períodos del calendario (ej., picos de ventas en vacaciones).
    • Tendencias: Movimientos direccionales a largo plazo en los datos.
    • Ciclos: Fluctuaciones no ligadas a períodos del calendario (ej., ciclos económicos).
  • Extracción de componentes de fecha y hora mejora el rendimiento del modelo:
    • Patrones a nivel de días: Capturando ritmos semanales en los datos.
    • Efectos de mes y trimestre: Identificando tendencias estacionales más amplias.
    • Comparaciones año a año: Permiten el reconocimiento de patrones a largo plazo.
  • Codificación cíclica preserva la naturaleza circular de ciertas características de tiempo:
    • Día de la semana: Asegura que el lunes y el domingo se reconozcan como días adyacentes.
    • Mes del año: Mantiene la naturaleza continua de los meses entre años.
    • Precisión mejorada del modelo: Ayuda a los algoritmos a comprender efectos circulares.
  • Manejo de fechas faltantes y zonas horarias es crucial para la integridad de los datos:
    • Consistencia de datos globales: Alineación de puntos de datos de diferentes regiones.
    • Gestión de datos de alta frecuencia: Asegura precisión en marcas de tiempo a nivel de milisegundos.
    • Estrategias de imputación: Selección de métodos adecuados para rellenar huecos sin introducir sesgos.

Al dominar estos conceptos, los científicos de datos pueden construir modelos de series temporales más robustos y precisos, logrando mejores predicciones y una comprensión más profunda en áreas como finanzas, predicción del clima y previsión de demanda.

9.1 Trabajando con Características de Fecha/Hora

Trabajar con datos de series temporales presenta desafíos y requisitos únicos que los diferencian de los conjuntos de datos estáticos. Los datos de series temporales se caracterizan por su orden temporal, donde cada observación está intrínsecamente vinculada al momento en que fue registrada. Esta dependencia temporal introduce complejidades que requieren enfoques analíticos especializados. Ya sea que estés pronosticando tendencias de ventas, prediciendo fluctuaciones en los precios de las acciones o analizando patrones climáticos complejos, una comprensión profunda de los datos de series temporales es crucial para modelar e interpretar con precisión los patrones, tendencias y estacionalidades subyacentes en los datos.

El análisis de series temporales nos permite descubrir conocimientos ocultos y hacer predicciones fundamentadas aprovechando la naturaleza temporal de los datos. Nos permite capturar no solo el estado actual de un sistema, sino también cómo evoluciona con el tiempo. Esta dimensión temporal agrega una capa de complejidad a nuestro análisis, pero también proporciona información valiosa sobre la dinámica del sistema que estamos estudiando.

Este capítulo profundizará en las consideraciones y técnicas específicas esenciales para manejar los datos de series temporales de manera efectiva. Comenzaremos explorando el rol crítico de las características de fecha y hora, discutiendo técnicas avanzadas para manejar información temporal. Esto incluye métodos para extraer características significativas de las marcas de tiempo, lidiar con diferentes escalas de tiempo y abordar desafíos como intervalos de muestreo irregulares o puntos de datos faltantes.

A continuación, profundizaremos en métodos sofisticados para descomponer los datos de series temporales. Este paso crucial nos permite desglosar una serie temporal compleja en sus componentes: tendencias, que representan la progresión a largo plazo; estacionalidad, que captura patrones cíclicos; y residuos, que representan las fluctuaciones aleatorias en los datos. Comprender estos componentes es clave para construir modelos predictivos precisos y obtener conocimientos sobre los impulsores subyacentes de los patrones observados.

Finalmente, abordaremos el concepto de estacionariedad y su profunda importancia para el modelado predictivo en el análisis de series temporales. Exploraremos por qué la estacionariedad es un supuesto crucial para muchos modelos de series temporales y discutiremos varias pruebas para determinar si una serie es estacionaria. Además, profundizaremos en técnicas avanzadas para transformar datos no estacionarios en una forma estacionaria, como diferenciación, eliminación de tendencias y enfoques más sofisticados como la transformación de Box-Cox. Al dominar estos conceptos y técnicas, estarás bien equipado para manejar una amplia gama de desafíos de series temporales y extraer información significativa de los datos temporales.

Cuando trabajamos con datos de series temporales, los elementos de fecha y hora sirven como el eje central para entender y predecir patrones temporales. Las características de fecha y hora no son solo identificadores simples; son fuentes ricas de información que pueden revelar tendencias complejas, estacionalidades y patrones cíclicos dentro de los datos. Estas características proporcionan un contexto temporal crucial para una interpretación y pronóstico precisos.

El poder de las características de fecha y hora radica en su capacidad para capturar relaciones temporales tanto obvias como sutiles. Por ejemplo, pueden revelar ciclos anuales en los datos de ventas, fluctuaciones mensuales en la temperatura o incluso patrones horarios en el tráfico de sitios web. Al extraer y utilizar adecuadamente estas características, los analistas pueden descubrir periodicidades ocultas y tendencias a largo plazo que de otro modo podrían pasar desapercibidas.

Además, aprovechar las características de fecha y hora de manera efectiva puede conducir a mejoras significativas en la precisión del modelo. Al incorporar estos conocimientos temporales, los modelos pueden aprender a reconocer y predecir patrones que están intrínsecamente ligados a períodos específicos. Esto puede ser especialmente valioso en campos como las finanzas, donde los comportamientos del mercado a menudo siguen patrones temporales complejos, o en el pronóstico del consumo de energía, donde los patrones de uso varían considerablemente dependiendo de la hora del día, el día de la semana o la temporada del año.

El proceso de trabajar con características de fecha y hora implica más que simplemente incluirlas en un conjunto de datos. Requiere una consideración cuidadosa de cómo representar y codificar estas características para maximizar su valor informativo. Esto puede implicar técnicas como la codificación cíclica para características como días de la semana o meses, o la creación de características de retraso para capturar efectos de tiempo diferido. Al diseñar estas características de manera reflexiva, los analistas pueden dotar a sus modelos de una comprensión matizada del tiempo, lo que permite predicciones más sofisticadas y precisas.

9.1.1 Características Comunes de Fecha/Hora y Su Importancia

Las características de fecha y hora juegan un papel crucial en el análisis de series temporales, proporcionando información valiosa sobre patrones temporales. Exploremos algunas características clave y su importancia:

  • Año, Mes, Día: Estos componentes básicos son fundamentales para capturar tendencias a largo plazo y variaciones estacionales. Por ejemplo, los negocios minoristas suelen experimentar ciclos de ventas anuales, con picos durante las temporadas de vacaciones. De manera similar, los datos de temperatura muestran típicamente fluctuaciones mensuales, permitiéndonos rastrear patrones climáticos con el tiempo.
  • Día de la Semana: Esta característica es particularmente útil para identificar ritmos semanales en los datos. Muchas industrias, como restaurantes o lugares de entretenimiento, ven diferencias significativas entre las actividades de entre semana y de fin de semana. Al incorporar esta característica, los modelos pueden aprender a anticipar estas fluctuaciones regulares.
  • Trimestre: Los datos trimestrales son especialmente relevantes en contextos financieros. Muchas empresas reportan ganancias y establecen metas en una base trimestral, lo que hace que esta característica sea invaluable para analizar tendencias fiscales y realizar predicciones económicas.
  • Hora y Minuto: Para datos de alta frecuencia, estos componentes de tiempo granulares son esenciales. Pueden revelar patrones intrincados en el consumo de energía, donde el uso puede aumentar durante ciertas horas del día, o en el flujo de tráfico, donde los patrones de horas pico se vuelven evidentes.
  • Días Festivos y Eventos Especiales: Aunque no se mencionó en la lista original, estos pueden ser características cruciales. Muchas empresas ven cambios significativos en la actividad durante días festivos o eventos especiales, lo que puede impactar en gran medida las predicciones de series temporales.

Al aprovechar estas características temporales, podemos construir modelos que no solo reconocen patrones recurrentes y estacionalidades, sino que también se adaptan a las características únicas de diferentes escalas de tiempo. Este enfoque integral permite predicciones más matizadas y precisas, capturando tanto los trazos generales de las tendencias a largo plazo como los detalles de las fluctuaciones a corto plazo. Comprender y utilizar adecuadamente estas características es clave para desbloquear el potencial completo del análisis de series temporales en diversos dominios, desde finanzas y ventas minoristas hasta gestión de energía y planificación urbana.

9.1.2 Extrayendo Características de Fecha/Hora en Python

Pandas proporciona una interfaz poderosa e intuitiva para manejar características de fecha y hora en datos de series temporales. La funcionalidad Datetime de la biblioteca ofrece un conjunto completo de herramientas que simplifican la tarea, a menudo compleja, de trabajar con datos temporales. Con Pandas, podemos analizar fechas desde varios formatos, extraer componentes temporales específicos y transformar columnas de fechas en representaciones más amigables para el análisis.

Las capacidades de análisis de Pandas nos permiten convertir representaciones de fechas en cadena a objetos datetime, infiriendo automáticamente el formato en muchos casos. Esto es particularmente útil cuando se trabaja con conjuntos de datos que contienen fechas en formatos inconsistentes o no estándar. Una vez analizadas, podemos extraer fácilmente una amplia gama de características temporales, como año, mes, día, hora, minuto, segundo, día de la semana, trimestre e incluso períodos fiscales.

Además, Pandas nos permite realizar aritmética de fechas sofisticada, facilitando el cálculo de diferencias de tiempo, la adición o sustracción de períodos de tiempo o el remuestreo de datos a diferentes frecuencias de tiempo. Esta flexibilidad es crucial al preparar datos de series temporales para análisis o modelado, ya que nos permite alinear puntos de datos, crear características de retraso o agregar datos en ventanas de tiempo personalizadas.

Al aprovechar la funcionalidad de fecha y hora de Pandas, podemos transformar datos temporales sin procesar en un conjunto rico de características que capturan los patrones subyacentes y la estacionalidad en nuestras series temporales. Este paso de preprocesamiento es a menudo crítico para desarrollar modelos de pronóstico precisos o realizar un análisis significativo de series temporales en diversos dominios, desde finanzas y economía hasta estudios ambientales y más allá.

Ejemplo: Extrayendo Características Básicas de Fecha/Hora

Comencemos con un conjunto de datos que incluye una columna de Fecha. Demostraremos cómo analizar fechas y extraer características como AñoMesDía de la Semana y Trimestre.

import pandas as pd

# Sample data with dates
data = {'Date': ['2022-01-15', '2022-02-10', '2022-03-20', '2022-04-15', '2022-05-25']}
df = pd.DataFrame(data)

# Convert Date column to datetime format
df['Date'] = pd.to_datetime(df['Date'])

# Extract date/time features
df['Year'] = df['Date'].dt.year
df['Month'] = df['Date'].dt.month
df['Day'] = df['Date'].dt.day
df['DayOfWeek'] = df['Date'].dt.dayofweek
df['Quarter'] = df['Date'].dt.quarter

print(df)

Este código demuestra cómo extraer características de fecha y hora de un conjunto de datos utilizando pandas en Python. A continuación se detalla qué hace el código:

  • Primero, importa la biblioteca pandas, esencial para la manipulación de datos en Python.
  • Crea un conjunto de datos de muestra con una columna 'Date' que contiene cinco cadenas de fechas.
  • Luego, los datos se convierten en un DataFrame de pandas.
  • La columna 'Date' se convierte del formato de cadena a formato datetime usando pd.to_datetime(). Este paso es crucial para realizar operaciones basadas en fechas.
  • El código luego extrae varias características de fecha/hora de la columna 'Date':
    • Year: Extrae el año de cada fecha.
    • Month: Extrae el mes (1-12).
    • Day: Extrae el día del mes.
    • DayOfWeek: Extrae el día de la semana (0-6, donde 0 es lunes).
    • Quarter: Extrae el trimestre del año (1-4).
  • Finalmente, imprime el DataFrame resultante, que ahora incluye estas nuevas características de fecha/hora junto con la columna original 'Date'.

Este código es particularmente útil para el análisis de series temporales, ya que permite capturar diversos aspectos temporales de los datos, los cuales se pueden utilizar para identificar patrones, estacionalidad o tendencias en el conjunto de datos.

Exploremos un ejemplo más completo.

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

# Sample data with dates and sales
data = {
    'Date': ['2022-01-15', '2022-02-10', '2022-03-20', '2022-04-15', '2022-05-25', 
             '2022-06-30', '2022-07-05', '2022-08-12', '2022-09-18', '2022-10-22'],
    'Sales': [1000, 1200, 1500, 1300, 1800, 2000, 1900, 2200, 2100, 2300]
}
df = pd.DataFrame(data)

# Convert Date column to datetime format
df['Date'] = pd.to_datetime(df['Date'])

# Extract basic date/time features
df['Year'] = df['Date'].dt.year
df['Month'] = df['Date'].dt.month
df['Day'] = df['Date'].dt.day
df['DayOfWeek'] = df['Date'].dt.dayofweek
df['Quarter'] = df['Date'].dt.quarter

# Extract additional features
df['WeekOfYear'] = df['Date'].dt.isocalendar().week
df['DayOfYear'] = df['Date'].dt.dayofyear
df['IsWeekend'] = df['DayOfWeek'].isin([5, 6]).astype(int)

# Create cyclical features for Month and DayOfWeek
df['Month_sin'] = np.sin(2 * np.pi * df['Month'] / 12)
df['Month_cos'] = np.cos(2 * np.pi * df['Month'] / 12)
df['DayOfWeek_sin'] = np.sin(2 * np.pi * df['DayOfWeek'] / 7)
df['DayOfWeek_cos'] = np.cos(2 * np.pi * df['DayOfWeek'] / 7)

# Create lag features
df['Sales_Lag1'] = df['Sales'].shift(1)
df['Sales_Lag7'] = df['Sales'].shift(7)

# Calculate rolling mean
df['Sales_RollingMean7'] = df['Sales'].rolling(window=7, min_periods=1).mean()

# Print the resulting dataframe
print(df)

# Visualize sales over time
plt.figure(figsize=(12, 6))
plt.plot(df['Date'], df['Sales'])
plt.title('Sales Over Time')
plt.xlabel('Date')
plt.ylabel('Sales')
plt.xticks(rotation=45)
plt.tight_layout()
plt.show()

# Visualize cyclical features
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))
ax1.scatter(df['Month_sin'], df['Month_cos'])
ax1.set_title('Cyclical Encoding of Month')
ax1.set_xlabel('Sin(Month)')
ax1.set_ylabel('Cos(Month)')
ax2.scatter(df['DayOfWeek_sin'], df['DayOfWeek_cos'])
ax2.set_title('Cyclical Encoding of Day of Week')
ax2.set_xlabel('Sin(DayOfWeek)')
ax2.set_ylabel('Cos(DayOfWeek)')
plt.tight_layout()
plt.show()

Explicación del desglose del código:

  1. Preparación de datos:
    • Comenzamos importando las bibliotecas necesarias: pandas para manipulación de datos, numpy para operaciones numéricas y matplotlib para visualización.
    • Se crea un conjunto de datos de muestra con fechas y cifras de ventas correspondientes.
    • La columna 'Date' se convierte a formato datetime usando pd.to_datetime().
  2. Extracción básica de características:
    • Extraemos características fundamentales de fecha/hora:
      • Año, Mes, Día: Componentes básicos de la fecha.
      • Día de la semana: Útil para captar patrones semanales (0 = lunes, 6 = domingo).
      • Trimestre: Para tendencias trimestrales, comúnmente utilizadas en análisis financieros.
  3. Extracción avanzada de características:
    • Semana del año: Captura patrones cíclicos anuales.
    • Día del año: Útil para identificar efectos estacionales anuales.
    • EsFinDeSemana: Característica binaria para diferenciar entre días de semana y fines de semana.
  4. Codificación de características cíclicas:
    • El mes y el día de la semana se codifican usando funciones seno y coseno.
    • Esto conserva la naturaleza cíclica de estas características, asegurando que, por ejemplo, diciembre (12) esté cerca de enero (1) en el espacio cíclico.
  5. Características de retraso (Lag):
    • Ventas_Lag1: Ventas del día anterior.
    • Ventas_Lag7: Ventas de hace una semana.
    • Estas características ayudan a capturar tendencias a corto plazo y semanales.
  6. Estadísticas móviles:
    • Media móvil de ventas de 7 días: Suaviza las fluctuaciones a corto plazo y destaca tendencias a largo plazo.
  7. Visualización:
    • Se crea un gráfico de series temporales de las ventas a lo largo del tiempo para visualizar las tendencias generales.
    • Se generan gráficos de dispersión de las características de mes y día de la semana codificadas cíclicamente para ilustrar cómo se representan estas características circulares en el espacio 2D.

Este ejemplo ampliado demuestra un enfoque más completo para la ingeniería de características en datos de series temporales. Incluye características temporales básicas, codificación cíclica avanzada, características de retraso y estadísticas móviles. Las visualizaciones ayudan a comprender la distribución de los datos y la efectividad de la codificación cíclica. Este conjunto enriquecido de características puede mejorar significativamente el rendimiento de los modelos de pronóstico de series temporales al capturar varios patrones y dependencias temporales en los datos.

9.1.3 Uso de características de fecha y hora en el modelo

Al incorporar características de fecha y hora en el modelo, es crucial seleccionar cuidadosamente aquellas que realmente mejoren su capacidad predictiva. La relevancia de estas características puede variar considerablemente según la naturaleza de los datos y el problema a resolver. Por ejemplo:

  • Día de la semana es particularmente valioso en conjuntos de datos de venta minorista, donde el comportamiento del consumidor sigue patrones distintos a lo largo de la semana. Esta característica puede ayudar a capturar la diferencia entre las ventas de días de semana y de fin de semana, o incluso patrones más sutiles como caídas a mitad de semana o picos al final de la semana.
  • Mes es excelente para captar ciclos estacionales que ocurren anualmente. Esto podría ser útil en diversos dominios como el comercio minorista (temporadas de compras), el turismo (meses pico de viajes) o la agricultura (ciclos de cultivo).
  • Año es fundamental para captar tendencias a largo plazo, lo cual es especialmente importante en conjuntos de datos que abarcan varios años. Esta característica puede ayudar a que los modelos tengan en cuenta cambios graduales en la distribución de datos subyacente, como el crecimiento o la disminución del mercado.

No obstante, la utilidad de estas características no se limita solo a estos ejemplos. La hora del día podría ser crucial para modelar el consumo de energía o los patrones de tráfico. Trimestre podría ser más adecuado que el mes para ciertas métricas comerciales que operan en un ciclo trimestral. Semana del año podría capturar patrones que se repiten anualmente pero no se alinean perfectamente con los meses del calendario.

También vale la pena considerar características derivadas. En lugar de componentes de fecha en bruto, se podrían crear indicadores booleanos como "Es_Feriado" o "Es_DíaDePago", o calcular el número de días desde un evento significativo. La clave es reflexionar sobre qué patrones temporales podrían existir en los datos y experimentar con diferentes combinaciones de características para encontrar la que mejor se adapte al caso de uso específico.

Ejemplo: Adición de características de fecha y hora a un modelo de pronóstico de ventas

Apliquemos nuestras características de fecha a un conjunto de datos de pronóstico de ventas.

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

# Sample sales data with dates
sales_data = {
    'Date': ['2022-01-15', '2022-02-10', '2022-03-20', '2022-04-15', '2022-05-25', 
             '2022-06-30', '2022-07-05', '2022-08-12', '2022-09-18', '2022-10-22'],
    'Sales': [200, 220, 250, 210, 230, 280, 260, 300, 290, 310]
}
df_sales = pd.DataFrame(sales_data)

# Convert Date to datetime and extract date/time features
df_sales['Date'] = pd.to_datetime(df_sales['Date'])
df_sales['Year'] = df_sales['Date'].dt.year
df_sales['Month'] = df_sales['Date'].dt.month
df_sales['Day'] = df_sales['Date'].dt.day
df_sales['DayOfWeek'] = df_sales['Date'].dt.dayofweek
df_sales['Quarter'] = df_sales['Date'].dt.quarter
df_sales['WeekOfYear'] = df_sales['Date'].dt.isocalendar().week
df_sales['DayOfYear'] = df_sales['Date'].dt.dayofyear
df_sales['IsWeekend'] = df_sales['DayOfWeek'].isin([5, 6]).astype(int)

# Create cyclical features for Month and DayOfWeek
df_sales['Month_sin'] = np.sin(2 * np.pi * df_sales['Month'] / 12)
df_sales['Month_cos'] = np.cos(2 * np.pi * df_sales['Month'] / 12)
df_sales['DayOfWeek_sin'] = np.sin(2 * np.pi * df_sales['DayOfWeek'] / 7)
df_sales['DayOfWeek_cos'] = np.cos(2 * np.pi * df_sales['DayOfWeek'] / 7)

# Create lag features
df_sales['Sales_Lag1'] = df_sales['Sales'].shift(1)
df_sales['Sales_Lag7'] = df_sales['Sales'].shift(7)

# Calculate rolling statistics
df_sales['Sales_RollingMean7'] = df_sales['Sales'].rolling(window=7, min_periods=1).mean()
df_sales['Sales_RollingStd7'] = df_sales['Sales'].rolling(window=7, min_periods=1).std()

# View dataset with extracted features
print(df_sales)

# Visualize sales over time
plt.figure(figsize=(12, 6))
plt.plot(df_sales['Date'], df_sales['Sales'])
plt.title('Sales Over Time')
plt.xlabel('Date')
plt.ylabel('Sales')
plt.xticks(rotation=45)
plt.tight_layout()
plt.show()

# Visualize cyclical features
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))
ax1.scatter(df_sales['Month_sin'], df_sales['Month_cos'])
ax1.set_title('Cyclical Encoding of Month')
ax1.set_xlabel('Sin(Month)')
ax1.set_ylabel('Cos(Month)')
ax2.scatter(df_sales['DayOfWeek_sin'], df_sales['DayOfWeek_cos'])
ax2.set_title('Cyclical Encoding of Day of Week')
ax2.set_xlabel('Sin(DayOfWeek)')
ax2.set_ylabel('Cos(DayOfWeek)')
plt.tight_layout()
plt.show()

Explicación completa del desglose:

  1. Preparación de datos:
    • Importamos las bibliotecas necesarias: pandas para manipulación de datos, numpy para operaciones numéricas y matplotlib para visualización.
    • Se crea un conjunto de datos de muestra con fechas y cifras de ventas correspondientes, que abarcan de enero a octubre de 2022.
    • La columna 'Date' se convierte a formato datetime usando pd.to_datetime().
  2. Extracción básica de características:
    • Año: Extraído para capturar tendencias a largo plazo entre años.
    • Mes: Para patrones de estacionalidad mensual.
    • Día: Día del mes, que podría ser relevante para efectos de fin de mes.
    • Día de la semana: Para capturar patrones semanales (0 = lunes, 6 = domingo).
    • Trimestre: Para tendencias trimestrales, comúnmente utilizadas en análisis financieros.
    • Semana del año: Captura patrones cíclicos anuales que no se alinean con los meses del calendario.
    • Día del año: Útil para identificar efectos estacionales anuales.
    • EsFinDeSemana: Característica binaria para diferenciar entre días de semana y fines de semana.
  3. Codificación de características cíclicas:
    • El mes y el día de la semana se codifican usando funciones seno y coseno.
    • Esto preserva la naturaleza cíclica de estas características, asegurando que, por ejemplo, diciembre (12) esté cerca de enero (1) en el espacio cíclico.
    • Las características resultantes (Mes_sin, Mes_cos, DiaSemana_sin, DiaSemana_cos) representan la naturaleza cíclica de meses y días de la semana de una forma que los modelos de machine learning pueden interpretar de manera más efectiva.
  4. Características de retraso (Lag):
    • Ventas_Lag1: Ventas del día anterior.
    • Ventas_Lag7: Ventas de hace una semana.
    • Estas características ayudan a capturar tendencias a corto plazo y semanales en los datos.
  5. Estadísticas móviles:
    • Media móvil de ventas de 7 días: Suaviza las fluctuaciones a corto plazo y captura tendencias locales.
    • Desviación estándar móvil de ventas de 7 días: Captura la volatilidad local.
  6. Visualización:
    • Se crea un gráfico de series temporales de las ventas a lo largo del tiempo para visualizar las tendencias generales.
    • Se generan gráficos de dispersión de las características de mes y día de la semana codificadas cíclicamente para ilustrar cómo se representan estas características circulares en el espacio 2D.

Este ejemplo muestra un enfoque integral para la ingeniería de características en datos de series temporales. Incluye características temporales básicas, codificación cíclica avanzada, características de retraso y estadísticas móviles. Las visualizaciones ayudan a comprender la distribución de los datos y demuestran la efectividad de la codificación cíclica. Este conjunto enriquecido de características puede mejorar significativamente el rendimiento de los modelos de pronóstico de series temporales al capturar varios patrones y dependencias temporales dentro de los datos.

9.1.4 Manejo de Características Cíclicas

Ciertas características de fecha/hora, como día de la semana o mes del año, exhiben una naturaleza cíclica, es decir, repiten un patrón predecible. Por ejemplo, los días de la semana se suceden de lunes a domingo, y después del domingo, el ciclo comienza de nuevo con el lunes. Esta propiedad cíclica es crucial en el análisis de series temporales, ya que puede revelar patrones recurrentes o estacionalidad en los datos.

Sin embargo, la mayoría de los algoritmos de machine learning no están diseñados de manera inherente para entender o interpretar esta naturaleza cíclica. Cuando estas características se codifican como valores numéricos simples (por ejemplo, lunes = 1, martes = 2, ..., domingo = 7), el algoritmo puede interpretar incorrectamente que el domingo (7) está más alejado del lunes (1) que del martes (2), lo cual no representa con precisión su relación cíclica.

Para abordar este problema, es esencial codificar las características cíclicas de una forma que preserve su naturaleza circular. Un enfoque popular y efectivo es la Codificación Seno y Coseno. Este método representa cada valor cíclico como un punto en un círculo, utilizando funciones seno y coseno para capturar la relación cíclica.

Así es como funciona la Codificación Seno y Coseno:

  1. Cada valor en el ciclo se asigna a un ángulo en un círculo (de 0 a 2π radianes).
  2. Se calculan el seno y el coseno de este ángulo, creando dos nuevas características.
  3. Estas nuevas características preservan la naturaleza cíclica de la característica original.

Por ejemplo, en el caso de los meses:

  • Enero (1) y diciembre (12) tendrán valores similares de seno y coseno, reflejando su proximidad en el ciclo anual.
  • Junio (6) y julio (7) también tendrán valores similares, pero serán notablemente diferentes de enero y diciembre.

Este método de codificación permite que los modelos de machine learning comprendan y utilicen mejor la naturaleza cíclica de estas características, mejorando su capacidad para capturar patrones estacionales y hacer predicciones más precisas en el análisis de series temporales.

Ejemplo: Codificación de una Característica Cíclica

Vamos a codificar Día de la Semana usando seno y coseno para preservar su naturaleza cíclica.

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

# Create sample data
dates = pd.date_range(start='2023-01-01', end='2023-12-31', freq='D')
sales = np.random.randint(100, 1000, size=len(dates))
df_sales = pd.DataFrame({'Date': dates, 'Sales': sales})

# Extract day of week
df_sales['DayOfWeek'] = df_sales['Date'].dt.dayofweek

# Encode day of week using sine and cosine
df_sales['DayOfWeek_sin'] = np.sin(2 * np.pi * df_sales['DayOfWeek'] / 7)
df_sales['DayOfWeek_cos'] = np.cos(2 * np.pi * df_sales['DayOfWeek'] / 7)

# Encode month using sine and cosine
df_sales['Month'] = df_sales['Date'].dt.month
df_sales['Month_sin'] = np.sin(2 * np.pi * df_sales['Month'] / 12)
df_sales['Month_cos'] = np.cos(2 * np.pi * df_sales['Month'] / 12)

# View the dataframe with cyclically encoded features
print(df_sales[['Date', 'DayOfWeek', 'DayOfWeek_sin', 'DayOfWeek_cos', 'Month', 'Month_sin', 'Month_cos', 'Sales']].head())

# Visualize cyclical encoding
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))

# Day of Week
ax1.scatter(df_sales['DayOfWeek_sin'], df_sales['DayOfWeek_cos'])
ax1.set_title('Cyclical Encoding of Day of Week')
ax1.set_xlabel('Sin(DayOfWeek)')
ax1.set_ylabel('Cos(DayOfWeek)')

# Month
ax2.scatter(df_sales['Month_sin'], df_sales['Month_cos'])
ax2.set_title('Cyclical Encoding of Month')
ax2.set_xlabel('Sin(Month)')
ax2.set_ylabel('Cos(Month)')

plt.tight_layout()
plt.show()

# Analyze sales by day of week
sales_by_day = df_sales.groupby('DayOfWeek')['Sales'].mean().sort_values(ascending=False)
print("\nAverage Sales by Day of Week:")
print(sales_by_day)

# Analyze sales by month
sales_by_month = df_sales.groupby('Month')['Sales'].mean().sort_values(ascending=False)
print("\nAverage Sales by Month:")
print(sales_by_month)

Explicación del desglose del código:

  1. Preparación de datos:
    • Importamos las bibliotecas necesarias: numpy para operaciones numéricas, pandas para manipulación de datos y matplotlib para visualización.
    • Se crea un conjunto de datos de muestra con datos de ventas diarias para todo el año 2023 usando la función date_range de pandas y valores de ventas aleatorios.
  2. Extracción de características:
    • DayOfWeek (Día de la Semana): Se extrae usando el atributo dt.dayofweek, que devuelve un valor de 0 (lunes) a 6 (domingo).
    • Month (Mes): Se extrae usando el atributo dt.month, que devuelve un valor de 1 (enero) a 12 (diciembre).
  3. Codificación de características cíclicas:
    • Los valores de DayOfWeek y Month se codifican usando funciones seno y coseno.
    • La fórmula utilizada es: sin(2π * feature / max_value) y cos(2π * feature / max_value).
    • Para DayOfWeek, el max_value es 7 (7 días en una semana).
    • Para Month, el max_value es 12 (12 meses en un año).
    • Esta codificación preserva la naturaleza cíclica de estas características, asegurando que días y meses similares estén cerca en el espacio codificado.
  4. Visualización de datos:
    • Se crean dos gráficos de dispersión para visualizar la codificación cíclica de DayOfWeek y Month.
    • Cada punto en estos gráficos representa un día/mes único, mostrando cómo se distribuyen en un patrón circular.
  5. Análisis de datos:
    • Se calculan las ventas promedio para cada día de la semana y cada mes.
    • Este análisis ayuda a identificar qué días de la semana y qué meses tienden a tener ventas más altas o más bajas.

Este ejemplo ilustra cómo realizar una codificación cíclica, visualizarla y aplicarla en un análisis básico. Al representar las características temporales de manera más precisa en los modelos de machine learning, la codificación cíclica mejora su capacidad para capturar patrones estacionales en datos de series temporales.

9.1.5 Manejo de Zonas Horarias y Fechas Faltantes

Las zonas horarias y las fechas faltantes son factores críticos que requieren una consideración cuidadosa al trabajar con datos de series temporales, especialmente en un mundo globalizado y con grandes volúmenes de datos:

  • Zonas Horarias: El desafío de las diferentes zonas horarias puede afectar significativamente la consistencia de los datos, particularmente cuando se trabaja con conjuntos de datos que abarcan múltiples regiones geográficas o contienen marcas de tiempo globales.
    • Pandas, una poderosa biblioteca de manipulación de datos en Python, ofrece soluciones robustas para manejar la complejidad de las zonas horarias. La función tz_localize() permite asignar una zona horaria específica a objetos de fecha y hora, mientras que tz_convert() facilita la conversión entre diferentes zonas horarias. Estas funciones son invaluables para mantener la precisión y consistencia en conjuntos de datos multi-regionales.
    • Por ejemplo, al analizar datos de mercados financieros de distintas bolsas de valores mundiales, el manejo adecuado de las zonas horarias garantiza que los eventos de trading estén correctamente alineados y sean comparables entre diferentes mercados.
  • Fechas Faltantes: La presencia de fechas faltantes en una serie temporal puede plantear desafíos significativos, interrumpiendo la continuidad de los datos y afectando negativamente el rendimiento del modelo.
    • Para abordar este problema, se pueden emplear varios métodos de imputación, que van desde técnicas simples como el llenado hacia adelante o hacia atrás, hasta enfoques más sofisticados como la interpolación o el uso de algoritmos de machine learning para predecir valores faltantes.
    • La elección del método de imputación depende de la naturaleza de los datos y de los requisitos específicos del análisis. Por ejemplo, en los datos de ventas minoristas, el llenado hacia adelante puede ser adecuado para fines de semana cuando las tiendas están cerradas, mientras que métodos más complejos pueden ser necesarios para valores faltantes esporádicos en datos continuos de sensores.

Abordar estos factores es crucial para mantener la integridad y confiabilidad de los análisis de series temporales. El manejo adecuado de las zonas horarias asegura que las relaciones temporales se representen con precisión entre diferentes regiones, mientras que la gestión efectiva de fechas faltantes preserva la continuidad esencial para muchas técnicas de modelado de series temporales.

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

# Create sample data with missing dates
date_range = pd.date_range(start='2023-01-01', end='2023-12-31', freq='D')
sales = np.random.randint(100, 1000, size=len(date_range))
df_sales = pd.DataFrame({'Date': date_range, 'Sales': sales})

# Introduce missing dates
df_sales = df_sales.drop(df_sales.index[10:20])  # Remove 10 days of data
df_sales = df_sales.drop(df_sales.index[150:160])  # Remove another 10 days

# Print original dataframe
print("Original DataFrame:")
print(df_sales.head(15))
print("...")
print(df_sales.tail(15))

# Handling missing dates by reindexing the data
df_sales = df_sales.set_index('Date').asfreq('D')

# Fill missing values
df_sales['Sales'] = df_sales['Sales'].fillna(method='ffill')  # forward-fill

# Reset index to make 'Date' a column again
df_sales = df_sales.reset_index()

# Print updated dataframe
print("\nUpdated DataFrame:")
print(df_sales.head(15))
print("...")
print(df_sales.tail(15))

# Visualize the data
plt.figure(figsize=(12, 6))
plt.plot(df_sales['Date'], df_sales['Sales'])
plt.title('Sales Data with Filled Missing Dates')
plt.xlabel('Date')
plt.ylabel('Sales')
plt.xticks(rotation=45)
plt.tight_layout()
plt.show()

# Basic statistics
print("\nBasic Statistics:")
print(df_sales['Sales'].describe())

# Check for any remaining missing values
print("\nRemaining Missing Values:")
print(df_sales.isnull().sum())

Explicación del desglose del código:

  1. Preparación de datos:
    • Importamos las bibliotecas necesarias: pandas para manipulación de datos, numpy para operaciones numéricas y matplotlib para visualización.
    • Se crea un conjunto de datos de ejemplo con datos de ventas diarias para todo el año 2023 usando la función date_range de pandas y cifras de ventas aleatorias.
    • Introducimos fechas faltantes intencionalmente al eliminar dos rangos de 10 días cada uno del conjunto de datos.
  2. Manejo de fechas faltantes:
    • Usamos set_index('Date').asfreq('D') para reindexar el DataFrame con un rango completo de fechas en frecuencia diaria ('D').
    • Esta operación introduce valores NaN para las ventas en las fechas que estaban previamente ausentes.
  3. Relleno de valores faltantes:
    • Usamos fillna(method='ffill') para realizar un llenado hacia adelante de los valores de ventas faltantes.
    • Esto significa que cada valor faltante se completa con la última cifra de ventas conocida.
  4. Visualización de datos:
    • Creamos un gráfico de líneas de los datos de ventas a lo largo del tiempo usando matplotlib.
    • Esta visualización ayuda a identificar cualquier brecha restante o patrones inusuales en los datos.
  5. Análisis de datos:
    • Imprimimos estadísticas descriptivas básicas de los datos de ventas usando el método describe().
    • También verificamos si quedan valores faltantes en el conjunto de datos.

Este ejemplo muestra un enfoque exhaustivo para gestionar fechas faltantes en datos de series temporales. Abarca la creación de un conjunto de datos, la introducción deliberada de brechas, la gestión de esas fechas faltantes, la visualización de los resultados y la realización de un análisis estadístico básico. Este proceso integral asegura la continuidad de los datos, un factor crítico para muchas técnicas de análisis de series temporales.

9.1.6 Puntos clave y sus implicaciones

  • Características de fecha y hora son fundamentales para la previsión de series temporales, permitiendo que los modelos distingan patrones complejos:
    • Estacionalidad: Patrones recurrentes asociados a períodos del calendario (ej., picos de ventas en vacaciones).
    • Tendencias: Movimientos direccionales a largo plazo en los datos.
    • Ciclos: Fluctuaciones no ligadas a períodos del calendario (ej., ciclos económicos).
  • Extracción de componentes de fecha y hora mejora el rendimiento del modelo:
    • Patrones a nivel de días: Capturando ritmos semanales en los datos.
    • Efectos de mes y trimestre: Identificando tendencias estacionales más amplias.
    • Comparaciones año a año: Permiten el reconocimiento de patrones a largo plazo.
  • Codificación cíclica preserva la naturaleza circular de ciertas características de tiempo:
    • Día de la semana: Asegura que el lunes y el domingo se reconozcan como días adyacentes.
    • Mes del año: Mantiene la naturaleza continua de los meses entre años.
    • Precisión mejorada del modelo: Ayuda a los algoritmos a comprender efectos circulares.
  • Manejo de fechas faltantes y zonas horarias es crucial para la integridad de los datos:
    • Consistencia de datos globales: Alineación de puntos de datos de diferentes regiones.
    • Gestión de datos de alta frecuencia: Asegura precisión en marcas de tiempo a nivel de milisegundos.
    • Estrategias de imputación: Selección de métodos adecuados para rellenar huecos sin introducir sesgos.

Al dominar estos conceptos, los científicos de datos pueden construir modelos de series temporales más robustos y precisos, logrando mejores predicciones y una comprensión más profunda en áreas como finanzas, predicción del clima y previsión de demanda.

9.1 Trabajando con Características de Fecha/Hora

Trabajar con datos de series temporales presenta desafíos y requisitos únicos que los diferencian de los conjuntos de datos estáticos. Los datos de series temporales se caracterizan por su orden temporal, donde cada observación está intrínsecamente vinculada al momento en que fue registrada. Esta dependencia temporal introduce complejidades que requieren enfoques analíticos especializados. Ya sea que estés pronosticando tendencias de ventas, prediciendo fluctuaciones en los precios de las acciones o analizando patrones climáticos complejos, una comprensión profunda de los datos de series temporales es crucial para modelar e interpretar con precisión los patrones, tendencias y estacionalidades subyacentes en los datos.

El análisis de series temporales nos permite descubrir conocimientos ocultos y hacer predicciones fundamentadas aprovechando la naturaleza temporal de los datos. Nos permite capturar no solo el estado actual de un sistema, sino también cómo evoluciona con el tiempo. Esta dimensión temporal agrega una capa de complejidad a nuestro análisis, pero también proporciona información valiosa sobre la dinámica del sistema que estamos estudiando.

Este capítulo profundizará en las consideraciones y técnicas específicas esenciales para manejar los datos de series temporales de manera efectiva. Comenzaremos explorando el rol crítico de las características de fecha y hora, discutiendo técnicas avanzadas para manejar información temporal. Esto incluye métodos para extraer características significativas de las marcas de tiempo, lidiar con diferentes escalas de tiempo y abordar desafíos como intervalos de muestreo irregulares o puntos de datos faltantes.

A continuación, profundizaremos en métodos sofisticados para descomponer los datos de series temporales. Este paso crucial nos permite desglosar una serie temporal compleja en sus componentes: tendencias, que representan la progresión a largo plazo; estacionalidad, que captura patrones cíclicos; y residuos, que representan las fluctuaciones aleatorias en los datos. Comprender estos componentes es clave para construir modelos predictivos precisos y obtener conocimientos sobre los impulsores subyacentes de los patrones observados.

Finalmente, abordaremos el concepto de estacionariedad y su profunda importancia para el modelado predictivo en el análisis de series temporales. Exploraremos por qué la estacionariedad es un supuesto crucial para muchos modelos de series temporales y discutiremos varias pruebas para determinar si una serie es estacionaria. Además, profundizaremos en técnicas avanzadas para transformar datos no estacionarios en una forma estacionaria, como diferenciación, eliminación de tendencias y enfoques más sofisticados como la transformación de Box-Cox. Al dominar estos conceptos y técnicas, estarás bien equipado para manejar una amplia gama de desafíos de series temporales y extraer información significativa de los datos temporales.

Cuando trabajamos con datos de series temporales, los elementos de fecha y hora sirven como el eje central para entender y predecir patrones temporales. Las características de fecha y hora no son solo identificadores simples; son fuentes ricas de información que pueden revelar tendencias complejas, estacionalidades y patrones cíclicos dentro de los datos. Estas características proporcionan un contexto temporal crucial para una interpretación y pronóstico precisos.

El poder de las características de fecha y hora radica en su capacidad para capturar relaciones temporales tanto obvias como sutiles. Por ejemplo, pueden revelar ciclos anuales en los datos de ventas, fluctuaciones mensuales en la temperatura o incluso patrones horarios en el tráfico de sitios web. Al extraer y utilizar adecuadamente estas características, los analistas pueden descubrir periodicidades ocultas y tendencias a largo plazo que de otro modo podrían pasar desapercibidas.

Además, aprovechar las características de fecha y hora de manera efectiva puede conducir a mejoras significativas en la precisión del modelo. Al incorporar estos conocimientos temporales, los modelos pueden aprender a reconocer y predecir patrones que están intrínsecamente ligados a períodos específicos. Esto puede ser especialmente valioso en campos como las finanzas, donde los comportamientos del mercado a menudo siguen patrones temporales complejos, o en el pronóstico del consumo de energía, donde los patrones de uso varían considerablemente dependiendo de la hora del día, el día de la semana o la temporada del año.

El proceso de trabajar con características de fecha y hora implica más que simplemente incluirlas en un conjunto de datos. Requiere una consideración cuidadosa de cómo representar y codificar estas características para maximizar su valor informativo. Esto puede implicar técnicas como la codificación cíclica para características como días de la semana o meses, o la creación de características de retraso para capturar efectos de tiempo diferido. Al diseñar estas características de manera reflexiva, los analistas pueden dotar a sus modelos de una comprensión matizada del tiempo, lo que permite predicciones más sofisticadas y precisas.

9.1.1 Características Comunes de Fecha/Hora y Su Importancia

Las características de fecha y hora juegan un papel crucial en el análisis de series temporales, proporcionando información valiosa sobre patrones temporales. Exploremos algunas características clave y su importancia:

  • Año, Mes, Día: Estos componentes básicos son fundamentales para capturar tendencias a largo plazo y variaciones estacionales. Por ejemplo, los negocios minoristas suelen experimentar ciclos de ventas anuales, con picos durante las temporadas de vacaciones. De manera similar, los datos de temperatura muestran típicamente fluctuaciones mensuales, permitiéndonos rastrear patrones climáticos con el tiempo.
  • Día de la Semana: Esta característica es particularmente útil para identificar ritmos semanales en los datos. Muchas industrias, como restaurantes o lugares de entretenimiento, ven diferencias significativas entre las actividades de entre semana y de fin de semana. Al incorporar esta característica, los modelos pueden aprender a anticipar estas fluctuaciones regulares.
  • Trimestre: Los datos trimestrales son especialmente relevantes en contextos financieros. Muchas empresas reportan ganancias y establecen metas en una base trimestral, lo que hace que esta característica sea invaluable para analizar tendencias fiscales y realizar predicciones económicas.
  • Hora y Minuto: Para datos de alta frecuencia, estos componentes de tiempo granulares son esenciales. Pueden revelar patrones intrincados en el consumo de energía, donde el uso puede aumentar durante ciertas horas del día, o en el flujo de tráfico, donde los patrones de horas pico se vuelven evidentes.
  • Días Festivos y Eventos Especiales: Aunque no se mencionó en la lista original, estos pueden ser características cruciales. Muchas empresas ven cambios significativos en la actividad durante días festivos o eventos especiales, lo que puede impactar en gran medida las predicciones de series temporales.

Al aprovechar estas características temporales, podemos construir modelos que no solo reconocen patrones recurrentes y estacionalidades, sino que también se adaptan a las características únicas de diferentes escalas de tiempo. Este enfoque integral permite predicciones más matizadas y precisas, capturando tanto los trazos generales de las tendencias a largo plazo como los detalles de las fluctuaciones a corto plazo. Comprender y utilizar adecuadamente estas características es clave para desbloquear el potencial completo del análisis de series temporales en diversos dominios, desde finanzas y ventas minoristas hasta gestión de energía y planificación urbana.

9.1.2 Extrayendo Características de Fecha/Hora en Python

Pandas proporciona una interfaz poderosa e intuitiva para manejar características de fecha y hora en datos de series temporales. La funcionalidad Datetime de la biblioteca ofrece un conjunto completo de herramientas que simplifican la tarea, a menudo compleja, de trabajar con datos temporales. Con Pandas, podemos analizar fechas desde varios formatos, extraer componentes temporales específicos y transformar columnas de fechas en representaciones más amigables para el análisis.

Las capacidades de análisis de Pandas nos permiten convertir representaciones de fechas en cadena a objetos datetime, infiriendo automáticamente el formato en muchos casos. Esto es particularmente útil cuando se trabaja con conjuntos de datos que contienen fechas en formatos inconsistentes o no estándar. Una vez analizadas, podemos extraer fácilmente una amplia gama de características temporales, como año, mes, día, hora, minuto, segundo, día de la semana, trimestre e incluso períodos fiscales.

Además, Pandas nos permite realizar aritmética de fechas sofisticada, facilitando el cálculo de diferencias de tiempo, la adición o sustracción de períodos de tiempo o el remuestreo de datos a diferentes frecuencias de tiempo. Esta flexibilidad es crucial al preparar datos de series temporales para análisis o modelado, ya que nos permite alinear puntos de datos, crear características de retraso o agregar datos en ventanas de tiempo personalizadas.

Al aprovechar la funcionalidad de fecha y hora de Pandas, podemos transformar datos temporales sin procesar en un conjunto rico de características que capturan los patrones subyacentes y la estacionalidad en nuestras series temporales. Este paso de preprocesamiento es a menudo crítico para desarrollar modelos de pronóstico precisos o realizar un análisis significativo de series temporales en diversos dominios, desde finanzas y economía hasta estudios ambientales y más allá.

Ejemplo: Extrayendo Características Básicas de Fecha/Hora

Comencemos con un conjunto de datos que incluye una columna de Fecha. Demostraremos cómo analizar fechas y extraer características como AñoMesDía de la Semana y Trimestre.

import pandas as pd

# Sample data with dates
data = {'Date': ['2022-01-15', '2022-02-10', '2022-03-20', '2022-04-15', '2022-05-25']}
df = pd.DataFrame(data)

# Convert Date column to datetime format
df['Date'] = pd.to_datetime(df['Date'])

# Extract date/time features
df['Year'] = df['Date'].dt.year
df['Month'] = df['Date'].dt.month
df['Day'] = df['Date'].dt.day
df['DayOfWeek'] = df['Date'].dt.dayofweek
df['Quarter'] = df['Date'].dt.quarter

print(df)

Este código demuestra cómo extraer características de fecha y hora de un conjunto de datos utilizando pandas en Python. A continuación se detalla qué hace el código:

  • Primero, importa la biblioteca pandas, esencial para la manipulación de datos en Python.
  • Crea un conjunto de datos de muestra con una columna 'Date' que contiene cinco cadenas de fechas.
  • Luego, los datos se convierten en un DataFrame de pandas.
  • La columna 'Date' se convierte del formato de cadena a formato datetime usando pd.to_datetime(). Este paso es crucial para realizar operaciones basadas en fechas.
  • El código luego extrae varias características de fecha/hora de la columna 'Date':
    • Year: Extrae el año de cada fecha.
    • Month: Extrae el mes (1-12).
    • Day: Extrae el día del mes.
    • DayOfWeek: Extrae el día de la semana (0-6, donde 0 es lunes).
    • Quarter: Extrae el trimestre del año (1-4).
  • Finalmente, imprime el DataFrame resultante, que ahora incluye estas nuevas características de fecha/hora junto con la columna original 'Date'.

Este código es particularmente útil para el análisis de series temporales, ya que permite capturar diversos aspectos temporales de los datos, los cuales se pueden utilizar para identificar patrones, estacionalidad o tendencias en el conjunto de datos.

Exploremos un ejemplo más completo.

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

# Sample data with dates and sales
data = {
    'Date': ['2022-01-15', '2022-02-10', '2022-03-20', '2022-04-15', '2022-05-25', 
             '2022-06-30', '2022-07-05', '2022-08-12', '2022-09-18', '2022-10-22'],
    'Sales': [1000, 1200, 1500, 1300, 1800, 2000, 1900, 2200, 2100, 2300]
}
df = pd.DataFrame(data)

# Convert Date column to datetime format
df['Date'] = pd.to_datetime(df['Date'])

# Extract basic date/time features
df['Year'] = df['Date'].dt.year
df['Month'] = df['Date'].dt.month
df['Day'] = df['Date'].dt.day
df['DayOfWeek'] = df['Date'].dt.dayofweek
df['Quarter'] = df['Date'].dt.quarter

# Extract additional features
df['WeekOfYear'] = df['Date'].dt.isocalendar().week
df['DayOfYear'] = df['Date'].dt.dayofyear
df['IsWeekend'] = df['DayOfWeek'].isin([5, 6]).astype(int)

# Create cyclical features for Month and DayOfWeek
df['Month_sin'] = np.sin(2 * np.pi * df['Month'] / 12)
df['Month_cos'] = np.cos(2 * np.pi * df['Month'] / 12)
df['DayOfWeek_sin'] = np.sin(2 * np.pi * df['DayOfWeek'] / 7)
df['DayOfWeek_cos'] = np.cos(2 * np.pi * df['DayOfWeek'] / 7)

# Create lag features
df['Sales_Lag1'] = df['Sales'].shift(1)
df['Sales_Lag7'] = df['Sales'].shift(7)

# Calculate rolling mean
df['Sales_RollingMean7'] = df['Sales'].rolling(window=7, min_periods=1).mean()

# Print the resulting dataframe
print(df)

# Visualize sales over time
plt.figure(figsize=(12, 6))
plt.plot(df['Date'], df['Sales'])
plt.title('Sales Over Time')
plt.xlabel('Date')
plt.ylabel('Sales')
plt.xticks(rotation=45)
plt.tight_layout()
plt.show()

# Visualize cyclical features
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))
ax1.scatter(df['Month_sin'], df['Month_cos'])
ax1.set_title('Cyclical Encoding of Month')
ax1.set_xlabel('Sin(Month)')
ax1.set_ylabel('Cos(Month)')
ax2.scatter(df['DayOfWeek_sin'], df['DayOfWeek_cos'])
ax2.set_title('Cyclical Encoding of Day of Week')
ax2.set_xlabel('Sin(DayOfWeek)')
ax2.set_ylabel('Cos(DayOfWeek)')
plt.tight_layout()
plt.show()

Explicación del desglose del código:

  1. Preparación de datos:
    • Comenzamos importando las bibliotecas necesarias: pandas para manipulación de datos, numpy para operaciones numéricas y matplotlib para visualización.
    • Se crea un conjunto de datos de muestra con fechas y cifras de ventas correspondientes.
    • La columna 'Date' se convierte a formato datetime usando pd.to_datetime().
  2. Extracción básica de características:
    • Extraemos características fundamentales de fecha/hora:
      • Año, Mes, Día: Componentes básicos de la fecha.
      • Día de la semana: Útil para captar patrones semanales (0 = lunes, 6 = domingo).
      • Trimestre: Para tendencias trimestrales, comúnmente utilizadas en análisis financieros.
  3. Extracción avanzada de características:
    • Semana del año: Captura patrones cíclicos anuales.
    • Día del año: Útil para identificar efectos estacionales anuales.
    • EsFinDeSemana: Característica binaria para diferenciar entre días de semana y fines de semana.
  4. Codificación de características cíclicas:
    • El mes y el día de la semana se codifican usando funciones seno y coseno.
    • Esto conserva la naturaleza cíclica de estas características, asegurando que, por ejemplo, diciembre (12) esté cerca de enero (1) en el espacio cíclico.
  5. Características de retraso (Lag):
    • Ventas_Lag1: Ventas del día anterior.
    • Ventas_Lag7: Ventas de hace una semana.
    • Estas características ayudan a capturar tendencias a corto plazo y semanales.
  6. Estadísticas móviles:
    • Media móvil de ventas de 7 días: Suaviza las fluctuaciones a corto plazo y destaca tendencias a largo plazo.
  7. Visualización:
    • Se crea un gráfico de series temporales de las ventas a lo largo del tiempo para visualizar las tendencias generales.
    • Se generan gráficos de dispersión de las características de mes y día de la semana codificadas cíclicamente para ilustrar cómo se representan estas características circulares en el espacio 2D.

Este ejemplo ampliado demuestra un enfoque más completo para la ingeniería de características en datos de series temporales. Incluye características temporales básicas, codificación cíclica avanzada, características de retraso y estadísticas móviles. Las visualizaciones ayudan a comprender la distribución de los datos y la efectividad de la codificación cíclica. Este conjunto enriquecido de características puede mejorar significativamente el rendimiento de los modelos de pronóstico de series temporales al capturar varios patrones y dependencias temporales en los datos.

9.1.3 Uso de características de fecha y hora en el modelo

Al incorporar características de fecha y hora en el modelo, es crucial seleccionar cuidadosamente aquellas que realmente mejoren su capacidad predictiva. La relevancia de estas características puede variar considerablemente según la naturaleza de los datos y el problema a resolver. Por ejemplo:

  • Día de la semana es particularmente valioso en conjuntos de datos de venta minorista, donde el comportamiento del consumidor sigue patrones distintos a lo largo de la semana. Esta característica puede ayudar a capturar la diferencia entre las ventas de días de semana y de fin de semana, o incluso patrones más sutiles como caídas a mitad de semana o picos al final de la semana.
  • Mes es excelente para captar ciclos estacionales que ocurren anualmente. Esto podría ser útil en diversos dominios como el comercio minorista (temporadas de compras), el turismo (meses pico de viajes) o la agricultura (ciclos de cultivo).
  • Año es fundamental para captar tendencias a largo plazo, lo cual es especialmente importante en conjuntos de datos que abarcan varios años. Esta característica puede ayudar a que los modelos tengan en cuenta cambios graduales en la distribución de datos subyacente, como el crecimiento o la disminución del mercado.

No obstante, la utilidad de estas características no se limita solo a estos ejemplos. La hora del día podría ser crucial para modelar el consumo de energía o los patrones de tráfico. Trimestre podría ser más adecuado que el mes para ciertas métricas comerciales que operan en un ciclo trimestral. Semana del año podría capturar patrones que se repiten anualmente pero no se alinean perfectamente con los meses del calendario.

También vale la pena considerar características derivadas. En lugar de componentes de fecha en bruto, se podrían crear indicadores booleanos como "Es_Feriado" o "Es_DíaDePago", o calcular el número de días desde un evento significativo. La clave es reflexionar sobre qué patrones temporales podrían existir en los datos y experimentar con diferentes combinaciones de características para encontrar la que mejor se adapte al caso de uso específico.

Ejemplo: Adición de características de fecha y hora a un modelo de pronóstico de ventas

Apliquemos nuestras características de fecha a un conjunto de datos de pronóstico de ventas.

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

# Sample sales data with dates
sales_data = {
    'Date': ['2022-01-15', '2022-02-10', '2022-03-20', '2022-04-15', '2022-05-25', 
             '2022-06-30', '2022-07-05', '2022-08-12', '2022-09-18', '2022-10-22'],
    'Sales': [200, 220, 250, 210, 230, 280, 260, 300, 290, 310]
}
df_sales = pd.DataFrame(sales_data)

# Convert Date to datetime and extract date/time features
df_sales['Date'] = pd.to_datetime(df_sales['Date'])
df_sales['Year'] = df_sales['Date'].dt.year
df_sales['Month'] = df_sales['Date'].dt.month
df_sales['Day'] = df_sales['Date'].dt.day
df_sales['DayOfWeek'] = df_sales['Date'].dt.dayofweek
df_sales['Quarter'] = df_sales['Date'].dt.quarter
df_sales['WeekOfYear'] = df_sales['Date'].dt.isocalendar().week
df_sales['DayOfYear'] = df_sales['Date'].dt.dayofyear
df_sales['IsWeekend'] = df_sales['DayOfWeek'].isin([5, 6]).astype(int)

# Create cyclical features for Month and DayOfWeek
df_sales['Month_sin'] = np.sin(2 * np.pi * df_sales['Month'] / 12)
df_sales['Month_cos'] = np.cos(2 * np.pi * df_sales['Month'] / 12)
df_sales['DayOfWeek_sin'] = np.sin(2 * np.pi * df_sales['DayOfWeek'] / 7)
df_sales['DayOfWeek_cos'] = np.cos(2 * np.pi * df_sales['DayOfWeek'] / 7)

# Create lag features
df_sales['Sales_Lag1'] = df_sales['Sales'].shift(1)
df_sales['Sales_Lag7'] = df_sales['Sales'].shift(7)

# Calculate rolling statistics
df_sales['Sales_RollingMean7'] = df_sales['Sales'].rolling(window=7, min_periods=1).mean()
df_sales['Sales_RollingStd7'] = df_sales['Sales'].rolling(window=7, min_periods=1).std()

# View dataset with extracted features
print(df_sales)

# Visualize sales over time
plt.figure(figsize=(12, 6))
plt.plot(df_sales['Date'], df_sales['Sales'])
plt.title('Sales Over Time')
plt.xlabel('Date')
plt.ylabel('Sales')
plt.xticks(rotation=45)
plt.tight_layout()
plt.show()

# Visualize cyclical features
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))
ax1.scatter(df_sales['Month_sin'], df_sales['Month_cos'])
ax1.set_title('Cyclical Encoding of Month')
ax1.set_xlabel('Sin(Month)')
ax1.set_ylabel('Cos(Month)')
ax2.scatter(df_sales['DayOfWeek_sin'], df_sales['DayOfWeek_cos'])
ax2.set_title('Cyclical Encoding of Day of Week')
ax2.set_xlabel('Sin(DayOfWeek)')
ax2.set_ylabel('Cos(DayOfWeek)')
plt.tight_layout()
plt.show()

Explicación completa del desglose:

  1. Preparación de datos:
    • Importamos las bibliotecas necesarias: pandas para manipulación de datos, numpy para operaciones numéricas y matplotlib para visualización.
    • Se crea un conjunto de datos de muestra con fechas y cifras de ventas correspondientes, que abarcan de enero a octubre de 2022.
    • La columna 'Date' se convierte a formato datetime usando pd.to_datetime().
  2. Extracción básica de características:
    • Año: Extraído para capturar tendencias a largo plazo entre años.
    • Mes: Para patrones de estacionalidad mensual.
    • Día: Día del mes, que podría ser relevante para efectos de fin de mes.
    • Día de la semana: Para capturar patrones semanales (0 = lunes, 6 = domingo).
    • Trimestre: Para tendencias trimestrales, comúnmente utilizadas en análisis financieros.
    • Semana del año: Captura patrones cíclicos anuales que no se alinean con los meses del calendario.
    • Día del año: Útil para identificar efectos estacionales anuales.
    • EsFinDeSemana: Característica binaria para diferenciar entre días de semana y fines de semana.
  3. Codificación de características cíclicas:
    • El mes y el día de la semana se codifican usando funciones seno y coseno.
    • Esto preserva la naturaleza cíclica de estas características, asegurando que, por ejemplo, diciembre (12) esté cerca de enero (1) en el espacio cíclico.
    • Las características resultantes (Mes_sin, Mes_cos, DiaSemana_sin, DiaSemana_cos) representan la naturaleza cíclica de meses y días de la semana de una forma que los modelos de machine learning pueden interpretar de manera más efectiva.
  4. Características de retraso (Lag):
    • Ventas_Lag1: Ventas del día anterior.
    • Ventas_Lag7: Ventas de hace una semana.
    • Estas características ayudan a capturar tendencias a corto plazo y semanales en los datos.
  5. Estadísticas móviles:
    • Media móvil de ventas de 7 días: Suaviza las fluctuaciones a corto plazo y captura tendencias locales.
    • Desviación estándar móvil de ventas de 7 días: Captura la volatilidad local.
  6. Visualización:
    • Se crea un gráfico de series temporales de las ventas a lo largo del tiempo para visualizar las tendencias generales.
    • Se generan gráficos de dispersión de las características de mes y día de la semana codificadas cíclicamente para ilustrar cómo se representan estas características circulares en el espacio 2D.

Este ejemplo muestra un enfoque integral para la ingeniería de características en datos de series temporales. Incluye características temporales básicas, codificación cíclica avanzada, características de retraso y estadísticas móviles. Las visualizaciones ayudan a comprender la distribución de los datos y demuestran la efectividad de la codificación cíclica. Este conjunto enriquecido de características puede mejorar significativamente el rendimiento de los modelos de pronóstico de series temporales al capturar varios patrones y dependencias temporales dentro de los datos.

9.1.4 Manejo de Características Cíclicas

Ciertas características de fecha/hora, como día de la semana o mes del año, exhiben una naturaleza cíclica, es decir, repiten un patrón predecible. Por ejemplo, los días de la semana se suceden de lunes a domingo, y después del domingo, el ciclo comienza de nuevo con el lunes. Esta propiedad cíclica es crucial en el análisis de series temporales, ya que puede revelar patrones recurrentes o estacionalidad en los datos.

Sin embargo, la mayoría de los algoritmos de machine learning no están diseñados de manera inherente para entender o interpretar esta naturaleza cíclica. Cuando estas características se codifican como valores numéricos simples (por ejemplo, lunes = 1, martes = 2, ..., domingo = 7), el algoritmo puede interpretar incorrectamente que el domingo (7) está más alejado del lunes (1) que del martes (2), lo cual no representa con precisión su relación cíclica.

Para abordar este problema, es esencial codificar las características cíclicas de una forma que preserve su naturaleza circular. Un enfoque popular y efectivo es la Codificación Seno y Coseno. Este método representa cada valor cíclico como un punto en un círculo, utilizando funciones seno y coseno para capturar la relación cíclica.

Así es como funciona la Codificación Seno y Coseno:

  1. Cada valor en el ciclo se asigna a un ángulo en un círculo (de 0 a 2π radianes).
  2. Se calculan el seno y el coseno de este ángulo, creando dos nuevas características.
  3. Estas nuevas características preservan la naturaleza cíclica de la característica original.

Por ejemplo, en el caso de los meses:

  • Enero (1) y diciembre (12) tendrán valores similares de seno y coseno, reflejando su proximidad en el ciclo anual.
  • Junio (6) y julio (7) también tendrán valores similares, pero serán notablemente diferentes de enero y diciembre.

Este método de codificación permite que los modelos de machine learning comprendan y utilicen mejor la naturaleza cíclica de estas características, mejorando su capacidad para capturar patrones estacionales y hacer predicciones más precisas en el análisis de series temporales.

Ejemplo: Codificación de una Característica Cíclica

Vamos a codificar Día de la Semana usando seno y coseno para preservar su naturaleza cíclica.

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

# Create sample data
dates = pd.date_range(start='2023-01-01', end='2023-12-31', freq='D')
sales = np.random.randint(100, 1000, size=len(dates))
df_sales = pd.DataFrame({'Date': dates, 'Sales': sales})

# Extract day of week
df_sales['DayOfWeek'] = df_sales['Date'].dt.dayofweek

# Encode day of week using sine and cosine
df_sales['DayOfWeek_sin'] = np.sin(2 * np.pi * df_sales['DayOfWeek'] / 7)
df_sales['DayOfWeek_cos'] = np.cos(2 * np.pi * df_sales['DayOfWeek'] / 7)

# Encode month using sine and cosine
df_sales['Month'] = df_sales['Date'].dt.month
df_sales['Month_sin'] = np.sin(2 * np.pi * df_sales['Month'] / 12)
df_sales['Month_cos'] = np.cos(2 * np.pi * df_sales['Month'] / 12)

# View the dataframe with cyclically encoded features
print(df_sales[['Date', 'DayOfWeek', 'DayOfWeek_sin', 'DayOfWeek_cos', 'Month', 'Month_sin', 'Month_cos', 'Sales']].head())

# Visualize cyclical encoding
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))

# Day of Week
ax1.scatter(df_sales['DayOfWeek_sin'], df_sales['DayOfWeek_cos'])
ax1.set_title('Cyclical Encoding of Day of Week')
ax1.set_xlabel('Sin(DayOfWeek)')
ax1.set_ylabel('Cos(DayOfWeek)')

# Month
ax2.scatter(df_sales['Month_sin'], df_sales['Month_cos'])
ax2.set_title('Cyclical Encoding of Month')
ax2.set_xlabel('Sin(Month)')
ax2.set_ylabel('Cos(Month)')

plt.tight_layout()
plt.show()

# Analyze sales by day of week
sales_by_day = df_sales.groupby('DayOfWeek')['Sales'].mean().sort_values(ascending=False)
print("\nAverage Sales by Day of Week:")
print(sales_by_day)

# Analyze sales by month
sales_by_month = df_sales.groupby('Month')['Sales'].mean().sort_values(ascending=False)
print("\nAverage Sales by Month:")
print(sales_by_month)

Explicación del desglose del código:

  1. Preparación de datos:
    • Importamos las bibliotecas necesarias: numpy para operaciones numéricas, pandas para manipulación de datos y matplotlib para visualización.
    • Se crea un conjunto de datos de muestra con datos de ventas diarias para todo el año 2023 usando la función date_range de pandas y valores de ventas aleatorios.
  2. Extracción de características:
    • DayOfWeek (Día de la Semana): Se extrae usando el atributo dt.dayofweek, que devuelve un valor de 0 (lunes) a 6 (domingo).
    • Month (Mes): Se extrae usando el atributo dt.month, que devuelve un valor de 1 (enero) a 12 (diciembre).
  3. Codificación de características cíclicas:
    • Los valores de DayOfWeek y Month se codifican usando funciones seno y coseno.
    • La fórmula utilizada es: sin(2π * feature / max_value) y cos(2π * feature / max_value).
    • Para DayOfWeek, el max_value es 7 (7 días en una semana).
    • Para Month, el max_value es 12 (12 meses en un año).
    • Esta codificación preserva la naturaleza cíclica de estas características, asegurando que días y meses similares estén cerca en el espacio codificado.
  4. Visualización de datos:
    • Se crean dos gráficos de dispersión para visualizar la codificación cíclica de DayOfWeek y Month.
    • Cada punto en estos gráficos representa un día/mes único, mostrando cómo se distribuyen en un patrón circular.
  5. Análisis de datos:
    • Se calculan las ventas promedio para cada día de la semana y cada mes.
    • Este análisis ayuda a identificar qué días de la semana y qué meses tienden a tener ventas más altas o más bajas.

Este ejemplo ilustra cómo realizar una codificación cíclica, visualizarla y aplicarla en un análisis básico. Al representar las características temporales de manera más precisa en los modelos de machine learning, la codificación cíclica mejora su capacidad para capturar patrones estacionales en datos de series temporales.

9.1.5 Manejo de Zonas Horarias y Fechas Faltantes

Las zonas horarias y las fechas faltantes son factores críticos que requieren una consideración cuidadosa al trabajar con datos de series temporales, especialmente en un mundo globalizado y con grandes volúmenes de datos:

  • Zonas Horarias: El desafío de las diferentes zonas horarias puede afectar significativamente la consistencia de los datos, particularmente cuando se trabaja con conjuntos de datos que abarcan múltiples regiones geográficas o contienen marcas de tiempo globales.
    • Pandas, una poderosa biblioteca de manipulación de datos en Python, ofrece soluciones robustas para manejar la complejidad de las zonas horarias. La función tz_localize() permite asignar una zona horaria específica a objetos de fecha y hora, mientras que tz_convert() facilita la conversión entre diferentes zonas horarias. Estas funciones son invaluables para mantener la precisión y consistencia en conjuntos de datos multi-regionales.
    • Por ejemplo, al analizar datos de mercados financieros de distintas bolsas de valores mundiales, el manejo adecuado de las zonas horarias garantiza que los eventos de trading estén correctamente alineados y sean comparables entre diferentes mercados.
  • Fechas Faltantes: La presencia de fechas faltantes en una serie temporal puede plantear desafíos significativos, interrumpiendo la continuidad de los datos y afectando negativamente el rendimiento del modelo.
    • Para abordar este problema, se pueden emplear varios métodos de imputación, que van desde técnicas simples como el llenado hacia adelante o hacia atrás, hasta enfoques más sofisticados como la interpolación o el uso de algoritmos de machine learning para predecir valores faltantes.
    • La elección del método de imputación depende de la naturaleza de los datos y de los requisitos específicos del análisis. Por ejemplo, en los datos de ventas minoristas, el llenado hacia adelante puede ser adecuado para fines de semana cuando las tiendas están cerradas, mientras que métodos más complejos pueden ser necesarios para valores faltantes esporádicos en datos continuos de sensores.

Abordar estos factores es crucial para mantener la integridad y confiabilidad de los análisis de series temporales. El manejo adecuado de las zonas horarias asegura que las relaciones temporales se representen con precisión entre diferentes regiones, mientras que la gestión efectiva de fechas faltantes preserva la continuidad esencial para muchas técnicas de modelado de series temporales.

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

# Create sample data with missing dates
date_range = pd.date_range(start='2023-01-01', end='2023-12-31', freq='D')
sales = np.random.randint(100, 1000, size=len(date_range))
df_sales = pd.DataFrame({'Date': date_range, 'Sales': sales})

# Introduce missing dates
df_sales = df_sales.drop(df_sales.index[10:20])  # Remove 10 days of data
df_sales = df_sales.drop(df_sales.index[150:160])  # Remove another 10 days

# Print original dataframe
print("Original DataFrame:")
print(df_sales.head(15))
print("...")
print(df_sales.tail(15))

# Handling missing dates by reindexing the data
df_sales = df_sales.set_index('Date').asfreq('D')

# Fill missing values
df_sales['Sales'] = df_sales['Sales'].fillna(method='ffill')  # forward-fill

# Reset index to make 'Date' a column again
df_sales = df_sales.reset_index()

# Print updated dataframe
print("\nUpdated DataFrame:")
print(df_sales.head(15))
print("...")
print(df_sales.tail(15))

# Visualize the data
plt.figure(figsize=(12, 6))
plt.plot(df_sales['Date'], df_sales['Sales'])
plt.title('Sales Data with Filled Missing Dates')
plt.xlabel('Date')
plt.ylabel('Sales')
plt.xticks(rotation=45)
plt.tight_layout()
plt.show()

# Basic statistics
print("\nBasic Statistics:")
print(df_sales['Sales'].describe())

# Check for any remaining missing values
print("\nRemaining Missing Values:")
print(df_sales.isnull().sum())

Explicación del desglose del código:

  1. Preparación de datos:
    • Importamos las bibliotecas necesarias: pandas para manipulación de datos, numpy para operaciones numéricas y matplotlib para visualización.
    • Se crea un conjunto de datos de ejemplo con datos de ventas diarias para todo el año 2023 usando la función date_range de pandas y cifras de ventas aleatorias.
    • Introducimos fechas faltantes intencionalmente al eliminar dos rangos de 10 días cada uno del conjunto de datos.
  2. Manejo de fechas faltantes:
    • Usamos set_index('Date').asfreq('D') para reindexar el DataFrame con un rango completo de fechas en frecuencia diaria ('D').
    • Esta operación introduce valores NaN para las ventas en las fechas que estaban previamente ausentes.
  3. Relleno de valores faltantes:
    • Usamos fillna(method='ffill') para realizar un llenado hacia adelante de los valores de ventas faltantes.
    • Esto significa que cada valor faltante se completa con la última cifra de ventas conocida.
  4. Visualización de datos:
    • Creamos un gráfico de líneas de los datos de ventas a lo largo del tiempo usando matplotlib.
    • Esta visualización ayuda a identificar cualquier brecha restante o patrones inusuales en los datos.
  5. Análisis de datos:
    • Imprimimos estadísticas descriptivas básicas de los datos de ventas usando el método describe().
    • También verificamos si quedan valores faltantes en el conjunto de datos.

Este ejemplo muestra un enfoque exhaustivo para gestionar fechas faltantes en datos de series temporales. Abarca la creación de un conjunto de datos, la introducción deliberada de brechas, la gestión de esas fechas faltantes, la visualización de los resultados y la realización de un análisis estadístico básico. Este proceso integral asegura la continuidad de los datos, un factor crítico para muchas técnicas de análisis de series temporales.

9.1.6 Puntos clave y sus implicaciones

  • Características de fecha y hora son fundamentales para la previsión de series temporales, permitiendo que los modelos distingan patrones complejos:
    • Estacionalidad: Patrones recurrentes asociados a períodos del calendario (ej., picos de ventas en vacaciones).
    • Tendencias: Movimientos direccionales a largo plazo en los datos.
    • Ciclos: Fluctuaciones no ligadas a períodos del calendario (ej., ciclos económicos).
  • Extracción de componentes de fecha y hora mejora el rendimiento del modelo:
    • Patrones a nivel de días: Capturando ritmos semanales en los datos.
    • Efectos de mes y trimestre: Identificando tendencias estacionales más amplias.
    • Comparaciones año a año: Permiten el reconocimiento de patrones a largo plazo.
  • Codificación cíclica preserva la naturaleza circular de ciertas características de tiempo:
    • Día de la semana: Asegura que el lunes y el domingo se reconozcan como días adyacentes.
    • Mes del año: Mantiene la naturaleza continua de los meses entre años.
    • Precisión mejorada del modelo: Ayuda a los algoritmos a comprender efectos circulares.
  • Manejo de fechas faltantes y zonas horarias es crucial para la integridad de los datos:
    • Consistencia de datos globales: Alineación de puntos de datos de diferentes regiones.
    • Gestión de datos de alta frecuencia: Asegura precisión en marcas de tiempo a nivel de milisegundos.
    • Estrategias de imputación: Selección de métodos adecuados para rellenar huecos sin introducir sesgos.

Al dominar estos conceptos, los científicos de datos pueden construir modelos de series temporales más robustos y precisos, logrando mejores predicciones y una comprensión más profunda en áreas como finanzas, predicción del clima y previsión de demanda.