tutoriales.com

Predicción de Series Temporales con Modelos ARIMA en Python: Guía Completa

Este tutorial te guiará paso a paso en la creación y aplicación de modelos ARIMA para la predicción de series temporales utilizando Python. Descubrirás cómo preparar tus datos, ajustar los parámetros del modelo y evaluar su rendimiento para generar pronósticos precisos.

Intermedio20 min de lectura1 views23 de marzo de 2026Reportar error

📊 Introducción a las Series Temporales y Modelos ARIMA

Las series temporales son secuencias de datos indexadas por tiempo, como el precio de las acciones, las ventas mensuales de un producto o la temperatura diaria. Predecir su comportamiento futuro es una tarea crucial en muchos campos, desde la economía hasta la meteorología.

El modelo ARIMA (AutoRegressive Integrated Moving Average) es uno de los enfoques más populares y robustos para la predicción de series temporales. Combina componentes autorregresivos (AR), de promedios móviles (MA) y de integración (I) para capturar la estructura subyacente de los datos.

¿Por qué ARIMA? 🤔

ARIMA es una excelente opción por varias razones:

  • Flexibilidad: Puede modelar una amplia gama de comportamientos de series temporales, incluyendo tendencias y estacionalidad (cuando se extiende a SARIMA).
  • Interpretabilidad: Sus componentes tienen una interpretación estadística clara.
  • Base Teórica: Está respaldado por una sólida teoría estadística.
📌 Nota: Este tutorial se centrará en ARIMA, pero muchos de los conceptos son extensibles a **SARIMA** (Seasonal ARIMA), que añade componentes estacionales para datos con patrones cíclicos regulares.

🛠️ Requisitos Previos e Instalación

Para seguir este tutorial, necesitarás tener instalado Python y algunas librerías clave.

🐍 Entorno de Desarrollo

Se recomienda usar un entorno virtual para gestionar las dependencias.

python -m venv venv_arima
source venv_arima/bin/activate  # En Linux/macOS
venc_arima\Scripts\activate      # En Windows

📦 Instalación de Librerías

Instalaremos las librerías necesarias con pip:

  • pandas: Para manipulación y análisis de datos.
  • numpy: Para operaciones numéricas.
  • matplotlib: Para visualización de datos.
  • statsmodels: La librería principal para modelos estadísticos, incluyendo ARIMA.
  • pmdarima: Una librería útil para la selección automática de parámetros ARIMA.
pip install pandas numpy matplotlib statsmodels pmdarima

📖 Conceptos Fundamentales de ARIMA

Antes de sumergirnos en el código, es crucial entender los tres componentes de ARIMA.

🔥 Importante: Los modelos ARIMA funcionan con series temporales que son **estacionarias**. Una serie estacionaria tiene una media, varianza y estructura de autocorrelación constantes a lo largo del tiempo.

1. Componente AutoRegresivo (AR) - p 📈

Un modelo AR(p) utiliza la relación entre una observación actual y un número p de observaciones pasadas. Se asume que el valor actual depende linealmente de sus valores anteriores.

2. Componente de Integración (I) - d 📉

El componente de integración d se refiere al número de diferencias (restas) necesarias para hacer que la serie temporal sea estacionaria. Si una serie no es estacionaria, a menudo se puede hacer estacionaria diferenciándola. Por ejemplo, una d=1 significa que la serie se diferencia una vez (valor actual - valor anterior).

3. Componente de Media Móvil (MA) - q 📊

Un modelo MA(q) utiliza la relación entre una observación actual y un error residual de un número q de observaciones pasadas. Se asume que el valor actual depende linealmente de los términos de error de pronósticos anteriores.

Resumen de Parámetros ARIMA(p, d, q)

ParámetroDescripciónCómo determinarlo
pOrden autorregresivo (número de lags de la serie original)Gráficos ACF/PACF después de hacer estacionaria la serie.
dOrden de diferenciación (número de veces para hacer estacionaria)Prueba de Dickey-Fuller Aumentada (ADF), inspección visual.
qOrden de media móvil (número de lags de los errores)Gráficos ACF/PACF de la serie diferenciada.
💡 Consejo: La **función de autocorrelación (ACF)** y la **función de autocorrelación parcial (PACF)** son herramientas gráficas esenciales para identificar los valores apropiados de `p` y `q`.

📝 Pasos para la Predicción con ARIMA

El proceso para construir y usar un modelo ARIMA sigue una serie de pasos bien definidos.

Paso 1: Carga y Preprocesamiento de Datos
Paso 2: Análisis de Estacionariedad y Diferenciación
Paso 3: Identificación de `p` y `q` (ACF/PACF)
Paso 4: Ajuste del Modelo ARIMA
Paso 5: Realización de Predicciones
Paso 6: Evaluación del Modelo

🚀 Implementación en Python

Vamos a aplicar estos pasos a un conjunto de datos de ejemplo. Usaremos un dataset ficticio de ventas mensuales.

Paso 1: Carga y Preprocesamiento de Datos 💾

Primero, cargaremos los datos y nos aseguraremos de que la columna de tiempo esté en el formato correcto y sea el índice del DataFrame.

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from statsmodels.tsa.stattools import adfuller
from statsmodels.graphics.tsaplots import plot_acf, plot_pacf
from statsmodels.tsa.arima.model import ARIMA
from sklearn.metrics import mean_squared_error
import pmdarima as pm

# Generar datos de ejemplo (sustituir por tus propios datos)
np.random.seed(42)
dates = pd.date_range(start='2010-01-01', periods=120, freq='M') # 10 años de datos mensuales
sales = np.random.normal(loc=100, scale=10, size=120) # Base
sales = sales + np.linspace(0, 50, 120) # Añadir tendencia
sales = sales + 15 * np.sin(np.linspace(0, 3*np.pi, 120)) # Añadir algo de estacionalidad

df = pd.DataFrame({'Date': dates, 'Sales': sales})
df.set_index('Date', inplace=True)

plt.figure(figsize=(12, 6))
plt.plot(df['Sales'])
plt.title('Serie Temporal de Ventas Mensuales')
plt.xlabel('Fecha')
plt.ylabel('Ventas')
plt.grid(True)
plt.show()
Evolución de Ventas (2010 - 2020) 0 250 500 750 1000 Ventas ($) 2010 2012 2014 2016 2018 2020 Año de Reporte

Paso 2: Análisis de Estacionariedad y Diferenciación 🧪

Utilizaremos la prueba de Dickey-Fuller Aumentada (ADF) para verificar la estacionariedad. Un p-valor bajo (generalmente < 0.05) indica que la serie es estacionaria.

def adf_test(series):
    result = adfuller(series, autolag='AIC')
    print(f'ADF Statistic: {result[0]}')
    print(f'p-value: {result[1]}')
    print('Critical Values:')
    for key, value in result[4].items():
        print(f'\t{key}: {value}')
    if result[1] <= 0.05:
        print("\n✅ La serie es estacionaria (o se rechaza la hipótesis nula de no estacionariedad).")
    else:
        print("\n❌ La serie NO es estacionaria (no se rechaza la hipótesis nula de no estacionariedad).")

print("\n--- Prueba ADF para la serie original ---")
adf_test(df['Sales'])

# Si no es estacionaria, diferenciamos la serie
# En nuestro caso, con tendencia clara, probablemente necesite diferenciación
df['Sales_diff'] = df['Sales'].diff().dropna()

plt.figure(figsize=(12, 6))
plt.plot(df['Sales_diff'])
plt.title('Serie Temporal de Ventas Mensuales (Diferenciada una vez)')
plt.xlabel('Fecha')
plt.ylabel('Ventas Diferenciadas')
plt.grid(True)
plt.show()

print("\n--- Prueba ADF para la serie diferenciada ---")
adf_test(df['Sales_diff'])

Si la serie original no es estacionaria (lo cual es común con tendencia), d será al menos 1. Nuestro ejemplo artificial tiene una tendencia, por lo que d=1 es un buen punto de partida.

Estacionariedad: 33%

Paso 3: Identificación de p y q (ACF/PACF) 🔍

Los gráficos ACF y PACF nos ayudan a identificar el orden de los componentes AR (p) y MA (q).

  • PACF (Autocorrelación Parcial): Ayuda a identificar el orden p (AR). Busca el punto donde la PACF corta el umbral de significancia por primera vez.
  • ACF (Autocorrelación): Ayuda a identificar el orden q (MA). Busca el punto donde la ACF corta el umbral de significancia por primera vez.
plt.figure(figsize=(12, 8))
plt.subplot(211)
plot_acf(df['Sales_diff'], ax=plt.gca(), lags=20)
plt.title('Función de Autocorrelación (ACF) de la Serie Diferenciada')
plt.subplot(212)
plot_pacf(df['Sales_diff'], ax=plt.gca(), lags=20)
plt.title('Función de Autocorrelación Parcial (PACF) de la Serie Diferenciada')
plt.tight_layout()
plt.show()
Función de Autocorrelación (ACF) Función de Autocorrelación Parcial (PACF) Retraso (Lag) Retraso (Lag) Correlación Correlación Parcial 0 1 0 1

Basándonos en estos gráficos, podemos estimar p y q.

💡 Consejo: A veces, la interpretación de los gráficos ACF/PACF puede ser subjetiva. Se pueden probar varios pares de (p, q) y comparar los modelos usando criterios como AIC o BIC.

Paso 4: Ajuste del Modelo ARIMA ⚙️

Dividimos los datos en conjuntos de entrenamiento y prueba para evaluar el rendimiento del modelo.

train_size = int(len(df) * 0.8)
train_data, test_data = df['Sales'], df['Sales'][train_size:]

# Usamos auto_arima para encontrar los mejores parámetros (p, d, q)
# Esto es especialmente útil cuando la inspección visual es ambigua

# auto_arima puede ser lento en datasets grandes, ajustar max_p, max_q, etc. si es necesario
# start_p, start_q se usan para el rango de búsqueda
# d=None permite que auto_arima determine el orden de diferenciación
# seasonal=False porque estamos buscando ARIMA, no SARIMA
model_auto_arima = pm.auto_arima(
    train_data,
    start_p=1, start_q=1,
    max_p=5, max_q=5,
    d=None, # Deja que auto_arima determine d
    seasonal=False,
    trace=True, # Muestra el progreso de la búsqueda
    error_action='ignore',
    suppress_warnings=True,
    stepwise=True # Usa un enfoque de búsqueda por pasos para la eficiencia
)

print("\n--- Mejores parámetros ARIMA encontrados por auto_arima ---")
print(model_auto_arima.summary())

best_p, best_d, best_q = model_auto_arima.order
print(f"\nMejores parámetros ARIMA: p={best_p}, d={best_d}, q={best_q}")

# Ajustar el modelo ARIMA con los parámetros encontrados
# Asegúrate de usar la serie ORIGINAL para el entrenamiento si auto_arima ya diferenció internamente
model = ARIMA(train_data, order=(best_p, best_d, best_q))
model_fit = model.fit()

print(model_fit.summary())

Intermedio Este paso demuestra la utilidad de pmdarima para automatizar la selección de parámetros, que a menudo es la parte más desafiante de usar ARIMA manualmente.

Paso 5: Realización de Predicciones 🔮

Una vez ajustado el modelo, podemos generar predicciones para el conjunto de prueba.

# Generar predicciones
# start y end deben ser índices del conjunto de datos original o del índice de tiempo
start_index = len(train_data)
end_index = len(df) - 1

# Si usas predict, asegúrate de que el modelo haya sido ajustado en los datos originales
# o en la serie diferenciada si se está prediciendo la serie diferenciada y luego integrando

# Usamos get_forecast para obtener intervalos de confianza también
forecast_result = model_fit.get_forecast(steps=len(test_data))
forecast_series = forecast_result.predicted_mean
conf_int = forecast_result.conf_int()

# Reindexar las predicciones para que coincidan con el índice de tiempo de test_data
forecast_series.index = test_data.index
conf_int.index = test_data.index

plt.figure(figsize=(14, 7))
plt.plot(train_data.index, train_data, label='Datos de Entrenamiento')
plt.plot(test_data.index, test_data, label='Datos Reales (Test)')
plt.plot(forecast_series.index, forecast_series, color='red', label='Predicciones ARIMA')
plt.fill_between(conf_int.index, conf_int.iloc[:, 0], conf_int.iloc[:, 1], color='pink', alpha=0.3, label='Intervalo de Confianza 95%')
plt.title('Predicción de Ventas Mensuales con ARIMA')
plt.xlabel('Fecha')
plt.ylabel('Ventas')
plt.legend()
plt.grid(True)
plt.show()
Predicción de Series Temporales (ARIMA) Tiempo (Pasos) Valor Entrenamiento Real (Prueba) Predicción ARIMA I.C. 95%

Paso 6: Evaluación del Modelo ✅

Evaluamos el rendimiento del modelo utilizando métricas comunes como el Error Cuadrático Medio (RMSE) o el Error Absoluto Medio (MAE).

# Calcular RMSE
rmse = np.sqrt(mean_squared_error(test_data, forecast_series))
print(f'RMSE: {rmse}')

# Una métrica más para contextualizar el error
mae = np.mean(np.abs(test_data - forecast_series))
print(f'MAE: {mae}')

# Comparación visual de la distribución de los errores
residuals = test_data - forecast_series
plt.figure(figsize=(10, 5))
plt.hist(residuals, bins=20)
plt.title('Distribución de los Residuales')
plt.xlabel('Residual')
plt.ylabel('Frecuencia')
plt.show()
⚠️ Advertencia: Un buen modelo ARIMA debe tener residuales que se parezcan a ruido blanco (media cero, varianza constante y sin autocorrelación). Si los residuales muestran patrones, el modelo no ha capturado completamente la información de la serie.
Análisis de Residuales Avanzado Para un análisis más profundo de los residuales, puedes usar:
  • Gráficos ACF/PACF de los residuales: Deben mostrar que no hay autocorrelación significativa.
  • Prueba de Ljung-Box: Para verificar formalmente que los residuales son ruido blanco.
from statsmodels.stats.diagnostic import acorr_ljungbox

# Plot ACF/PACF de residuales
fig, axes = plt.subplots(1, 2, figsize=(16, 4))
plot_acf(residuals, ax=axes[0], lags=20)
plot_pacf(residuals, ax=axes[1], lags=20)
plt.suptitle('ACF y PACF de los Residuales del Modelo ARIMA')
plt.show()

# Prueba de Ljung-Box
ljung_box_results = acorr_ljungbox(residuals, lags=[10, 20], return_df=True)
print("\n--- Prueba de Ljung-Box para Residuales ---")
print(ljung_box_results)

Si los p-valores de la prueba de Ljung-Box son mayores a 0.05, no podemos rechazar la hipótesis nula de que los residuales son ruido blanco, lo cual es un buen indicio.

Tutorial Completo: 100%

💡 Mejoras y Consideraciones Adicionales

Los modelos ARIMA son potentes, pero hay formas de mejorarlos y situaciones a considerar.

SARIMA para Estacionalidad 🗓️

Si tu serie temporal tiene patrones estacionales claros (por ejemplo, ciclos anuales, mensuales), deberías considerar usar SARIMA (Seasonal ARIMA). Este modelo añade componentes estacionales (P, D, Q, s) a los componentes no estacionales (p, d, q), donde s es la longitud del ciclo estacional (e.g., 12 para datos mensuales con estacionalidad anual).

pmdarima.auto_arima puede buscar también modelos SARIMA si estableces seasonal=True y especificas m (la frecuencia estacional).

Explicaciones de AIC y BIC 📈

  • AIC (Criterio de Información de Akaike): Es una medida de la calidad relativa de un modelo estadístico para un conjunto dado de datos. Es una estimación de la información perdida cuando se usa un modelo para representar el proceso que generó los datos. Se prefieren valores de AIC más bajos.
  • BIC (Criterio de Información Bayesiano): Similar al AIC, pero penaliza más fuertemente los modelos con más parámetros. También se prefieren valores de BIC más bajos. A menudo, BIC favorecerá modelos más parsimoniosos (más simples).

Al seleccionar p, d y q, puedes ajustar manualmente el modelo con diferentes combinaciones y comparar sus valores de AIC/BIC para encontrar el mejor ajuste que equilibre la complejidad y la bondad de ajuste.

Modelos Exógenos (ARIMAX / SARIMAX) 🌍

Si tienes variables externas que crees que influyen en tu serie temporal (ej. publicidad, precio del combustible), puedes incorporarlas usando modelos ARIMAX o SARIMAX. Estas extensiones permiten incluir regresores externos en el modelo.

# Ejemplo de SARIMAX (sin ejecutarlo completamente, solo la estructura)
# from statsmodels.tsa.statespace.sarimax import SARIMAX

# Supongamos que tienes una variable exógena 'Publicidad'
# df['Publicidad'] = ...

# Si usas SARIMAX con exógenas, necesitarías pasar 'exog'
# model_sarimax = SARIMAX(train_data, order=(best_p, best_d, best_q), seasonal_order=(P, D, Q, s), exog=train_exog_data)
# model_sarimax_fit = model_sarimax.fit()

Limitaciones de ARIMA ⚠️

  • Linealidad: ARIMA asume relaciones lineales. Para relaciones no lineales, otros modelos (como redes neuronales recurrentes, LSTMs) podrían ser más adecuados.
  • Series estacionarias: Requiere que la serie sea estacionaria o pueda ser diferenciada para serlo. Esto puede no ser siempre posible o adecuado.
  • Datos atípicos: Es sensible a los outliers o valores atípicos que pueden distorsionar los parámetros del modelo.
  • Manejo de múltiples variables: No es ideal para modelar múltiples series temporales interdependientes; para eso, se considerarían modelos VAR (Vector AutoRegresión).

🏁 Conclusión

Has completado una guía exhaustiva para la predicción de series temporales utilizando modelos ARIMA en Python. Desde la carga de datos hasta la evaluación del modelo, ahora tienes las herramientas y el conocimiento para aplicar esta técnica a tus propios problemas de pronóstico. Recuerda que la práctica es clave, y experimentar con diferentes parámetros y tipos de datos te ayudará a dominar el arte de la predicción de series temporales.

La predicción de series temporales es un campo vasto y ARIMA es solo una de las muchas herramientas disponibles. Sin embargo, es una base fundamental que todo analista de datos y científico de datos debe conocer.

💡 Próximos Pasos: Explora SARIMA para datos estacionales, y considera modelos más avanzados como Prophet de Facebook o LSTMs para series con patrones complejos o grandes volúmenes de datos.

Tutoriales relacionados

Comentarios (0)

Aún no hay comentarios. ¡Sé el primero!