Python para Economía
Introducción a Python
Aplicado a Series Temporales en Economía
El Papel del Análisis de Datos en la Economía Moderna
La economía moderna se ha transformado en una disciplina cada vez más empírica, donde la validación de teorías y la comprensión de fenómenos complejos dependen intrínsecamente del análisis de datos. Esta evolución ha hecho que el desarrollo de sólidas habilidades en ciencia de datos sea fundamental para los economistas. En este contexto, Python ha emergido como una herramienta líder, apreciada por su versatilidad y su vasto ecosistema de bibliotecas especializadas.
Dominar esta herramienta permite a los estudiantes trascender los marcos teóricos y aplicarlos a situaciones económicas concretas, lo que enriquece su formación y les proporciona una comprensión más profunda y aplicable de la economía.
Fundamentos de Python
Tipos de Datos y Estructuras
Una comprensión fundamental de los tipos y estructuras de datos de Python es esencial. Los tipos de datos básicos (int
, float
, str
, bool
) son los ladrillos de la información, mientras que las estructuras de datos (listas, diccionarios) nos permiten organizarla.
# Tipos de Datos
tasa_inflacion = 8.5 # float
anio = 2023 # int
pais = "Argentina" # str
en_recesion = True # bool
# Estructuras de Datos
ipc_serie = [8.4, 7.7, 11.0, 8.8] # Lista: ideal para series de tiempo
dato_actual = { # Diccionario: para observaciones con múltiples variables
'pbi_var': -2.5,
'desempleo': 6.9
}
print(f"La inflación del primer mes fue: {ipc_serie[0]}%")
print(f"La tasa de desempleo actual es: {dato_actual['desempleo']}%")
Control de Flujo y Funciones
Las estructuras de control (if/else
, for
) permiten que nuestros programas tomen decisiones y repitan tareas. Las funciones (def
) nos permiten encapsular esta lógica para reutilizarla, haciendo nuestro código más limpio y modular.
# Función para clasificar el crecimiento económico
def clasificar_crecimiento(tasa_pbi):
if tasa_pbi > 2.0:
return "Fuerte Expansión"
elif tasa_pbi > 0:
return "Expansión Moderada"
else:
return "Recesión"
# Bucle para analizar varias tasas
tasas_anuales = [2.5, -1.0, 0.5]
for tasa in tasas_anuales:
clasificacion = clasificar_crecimiento(tasa)
print(f"Una tasa de {tasa}% se clasifica como: {clasificacion}")
Computación Numérica con NumPy
Arrays de NumPy: Operaciones Numéricas Eficientes
NumPy es la piedra angular de la computación numérica en Python. Su objeto ndarray
permite operaciones matemáticas eficientes sobre grandes volúmenes de datos (vectorización), lo cual es órdenes de magnitud más rápido que usar bucles.
import numpy as np
# Ejemplo: Ajustar salarios por inflación
salarios = np.array([50000, 65000, 80000])
inflacion = 0.45 # 45%
# Operación vectorizada: rápida y concisa
salarios_ajustados = salarios * (1 + inflacion)
print(f"Salarios ajustados: {salarios_ajustados}")
Atributos, Indexación y Slicing de Arrays
Entender las propiedades de un array y cómo acceder a sus elementos es fundamental. Los atributos como .shape
y .dtype
nos dan información sobre la estructura del array. La indexación y el slicing nos permiten seleccionar subconjuntos de datos de manera eficiente.
import numpy as np
# Creamos un array de 2 dimensiones (matriz)
datos = np.array([[1, 2, 3], [4, 5, 6]])
# Atributos
print(f"Forma del array: {datos.shape}") # (2 filas, 3 columnas)
print(f"Tipo de datos: {datos.dtype}") # int64
# Indexación (acceder a un elemento: fila 0, columna 2)
elemento = datos[0, 2]
print(f"Elemento en [0, 2]: {elemento}") # 3
# Slicing (acceder a una columna entera: todas las filas, columna 1)
columna_1 = datos[:, 1]
print(f"Segunda columna: {columna_1}") # [2 5]
Manipulación de Datos con Pandas
Lectura de Datos desde Archivos
El punto de partida de casi todo análisis es cargar datos. Pandas ofrece funciones robustas para leer una gran variedad de formatos. Las más comunes son pd.read_csv()
para archivos de texto delimitado (CSV) y pd.read_excel()
para hojas de cálculo de Excel.
Es fundamental prestar atención a los parámetros de estas funciones para asegurar una carga correcta de los datos. Algunos de los más importantes para read_csv
son:
sep
: El delimitador de columnas (por defecto es ',', pero en Latinoamérica es común ';').decimal
: El separador de decimales (por defecto es '.', a veces es ',').index_col
: Especifica qué columna debe usarse como índice del DataFrame.parse_dates
: Una lista de columnas que Pandas intentará convertir automáticamente a formato de fecha, crucial para series de tiempo.
import pandas as pd
from io import StringIO
# En un caso real, usarías la ruta a tu archivo:
# df = pd.read_csv('datos/economia.csv', sep=';', decimal=',', index_col='Fecha', parse_dates=True)
# Para que este ejemplo sea reproducible, simulamos un archivo CSV:
data_csv = """Fecha;PBI;Inflacion
2023-01-01;102.5;7.7
2023-02-01;103.1;8.4
2023-03-01;102.9;11.0"""
# Usamos StringIO para que pandas lea el string como si fuera un archivo
df_simulado = pd.read_csv(
StringIO(data_csv),
sep=';',
index_col='Fecha',
parse_dates=True
)
print(df_simulado)
print("\nTipo de dato del índice:", type(df_simulado.index))
Selección y Filtrado Interactivo
Una vez cargados los datos, la habilidad más fundamental es aprender a seleccionar y filtrar. Haz clic en los botones para ver el código de Pandas y cómo afecta a la tabla de datos de ejemplo.
Comandos de Pandas
Resultado del DataFrame
Limpieza y Tratamiento de Datos Faltantes
En el mundo real, los datos rara vez son perfectos. Una de las tareas más comunes es lidiar con los datos faltantes (NaN). Pandas ofrece métodos sencillos para detectarlos y tratarlos.
import pandas as pd
import numpy as np
data = {'Tasa_Desempleo': [3.5, 3.6, np.nan, 3.7],
'Tasa_Interes': [5.25, 5.25, 5.50, np.nan]}
df = pd.DataFrame(data, index=['2023-Q1', '2023-Q2', '2023-Q3', '2023-Q4'])
print("Datos faltantes por columna:")
print(df.isnull().sum())
# Estrategia 1: Eliminar filas con cualquier dato faltante
print("\nDataFrame sin filas con NaN:")
print(df.dropna())
# Estrategia 2: Rellenar NaN con el valor anterior (forward-fill)
print("\nDataFrame con NaN rellenados:")
print(df.fillna(method='ffill'))
Rezagos, Diferencias y Ventanas Móviles
El análisis de series temporales se basa en transformaciones específicas de los datos. Pandas las hace triviales:
.shift(n)
: Crea un rezago (lag) den
períodos, fundamental para modelos autorregresivos..diff(n)
: Calcula la diferencia de ordenn
, usada para estabilizar la media de una serie y alcanzar la estacionariedad..rolling(window)
: Calcula una estadística (como.mean()
o.std()
) sobre una ventana móvil, útil para suavizar una serie y visualizar tendencias.
# 'unrate' es nuestro DataFrame de desempleo de FRED
import pandas as pd
data = {'PBI': [100, 102, 105, 103, 106]}
idx = pd.date_range('2023-01-01', periods=5, freq='Q')
df = pd.DataFrame(data, index=idx)
# Crear un rezago de 1 período del PBI
df['PBI_rezago_1'] = df['PBI'].shift(1)
# Crear la diferencia de 1er orden del PBI
df['PBI_diferencia_1'] = df['PBI'].diff(1)
# Calcular la media móvil de 12 meses para suavizar la serie
unrate['12M_MA'] = unrate['UNRATE'].rolling(window=12).mean()
# Graficar la serie original y su media móvil
unrate[['UNRATE', '12M_MA']].plot(figsize=(10,6), title='Tasa de Desempleo y Media Móvil de 12 Meses')
print(df)
Agrupación y Agregación de Datos
El método .groupby()
es una de las herramientas más potentes de Pandas. Permite agrupar datos basándose en una o más columnas y luego aplicar una función de agregación (como .mean()
, .sum()
, .count()
) a cada grupo.
import pandas as pd
data = {
'Año': [2022, 2022, 2023, 2023],
'Trimestre': ['T1', 'T2', 'T1', 'T2'],
'Crecimiento_PBI': [1.2, 0.8, -0.5, 0.2]
}
df = pd.DataFrame(data)
# Calcular el crecimiento promedio por año
crecimiento_anual = df.groupby('Año')['Crecimiento_PBI'].mean()
print(crecimiento_anual)
Combinando DataFrames (Merge & Join)
En economía es muy común necesitar combinar datos de diferentes fuentes (ej: PBI, población, inflación). El método pd.merge()
es la herramienta principal para realizar uniones entre DataFrames, similar al JOIN de SQL. La clave es el parámetro how
, que define la lógica de la unión.
import pandas as pd
# DataFrame de datos del PBI (miles de millones USD)
data1 = {'Anio': [2021, 2022, 2023],
'PBI': [605, 632, 622]}
df1 = pd.DataFrame(data1)
# DataFrame de datos de Población (millones)
data2 = {'Anio': [2022, 2023, 2024],
'Poblacion': [46.2, 46.6, 47.0]}
df2 = pd.DataFrame(data2)
# Ejemplo de combinación usando un 'left' join
df_combinado = pd.merge(df1, df2, on='Anio', how='left')
print("--- df1 (PBI) ---")
print(df1)
print("\n--- df2 (Población) ---")
print(df2)
print("\n--- Resultado del Merge (left) ---")
print(df_combinado)
Prueba Interactiva de Joins
Haz clic en los botones para visualizar el resultado de cada tipo de join
.
Tablas Originales
PBI (df1)
Población (df2)
Código y Resultado de la Unión
Obtención de Datos por API
Datos Económicos con `pandas-datareader`
Gran parte del análisis económico moderno se nutre de datos públicos. La librería `pandas-datareader` permite conectarse directamente a fuentes como la Reserva Federal de St. Louis (FRED), que aloja cientos de miles de series económicas (PBI, inflación, desempleo, etc.).
Cada serie en FRED tiene un código único (ej: `GDPC1` para el PBI de EE.UU.). Podemos descargar estos datos directamente a un DataFrame de Pandas, listos para analizar.
!pip install pandas_datareader
import pandas_datareader.data as web
import datetime
# Definir fechas de inicio y fin
start = datetime.datetime(2020, 1, 1)
end = datetime.datetime(2023, 12, 31)
# Descargar la Tasa de Desempleo de EEUU (UNRATE) desde FRED
unrate = web.DataReader('UNRATE', 'fred', start, end)
print("Últimos 5 datos de desempleo:")
print(unrate.tail())
Datos Financieros con `yfinance`
Para datos de mercados financieros (precios de acciones, índices, ETFs), la librería yfinance
es una herramienta excepcional. Permite descargar datos históricos directamente desde Yahoo! Finance con apenas unas líneas de código.
!pip install yfinance
import yfinance as yf
import matplotlib.pyplot as plt
# Crear un objeto "Ticker" para el índice S&P 500
sp500 = yf.Ticker("^GSPC")
# Obtener el historial de precios para los últimos 5 años
hist_sp500 = sp500.history(period="5y")
# Graficar la serie de precios de cierre para replicar el gráfico
plt.figure(figsize=(10, 6))
hist_sp500['Close'].plot(title="Historial de Precios S&P 500 (Últimos 5 años)")
plt.ylabel("Precio de Cierre (USD)")
plt.xlabel("Fecha")
plt.grid(True)
plt.show()
Visualización de Datos Económicos
Visualización Exploratoria con Seaborn
La visualización es clave para descubrir patrones, tendencias y relaciones. Seaborn, construida sobre Matplotlib, permite crear gráficos estadísticos complejos con poco código, integrándose perfectamente con Pandas. A continuación, se visualiza una serie simulada del PIB.
import seaborn as sns
import matplotlib.pyplot as plt
import pandas as pd
# Suponiendo que 'df_pib' tiene un DatetimeIndex y una columna 'Valor'
plt.figure(figsize=(10, 6))
sns.lineplot(data=df_pib, x=df_pib.index, y='Valor')
plt.title('Evolución del PIB Simulado')
plt.xlabel('Fecha')
plt.ylabel('Valor (en millones)')
plt.grid(True)
plt.show()
Pruebas de Hipótesis en Economía
Las pruebas de hipótesis nos permiten tomar decisiones basadas en datos para validar afirmaciones económicas. Una de las más comunes es la prueba t para muestras independientes, que se usa para comparar las medias de dos grupos. Por ejemplo: ¿un programa de capacitación laboral aumentó significativamente el ingreso promedio de los participantes en comparación con un grupo de control?
Usamos la biblioteca scipy.stats
para realizar estas pruebas. La clave es interpretar el p-valor: si es bajo (típicamente < 0.05), rechazamos la hipótesis nula (de que no hay diferencia) y concluimos que la diferencia observada es estadísticamente significativa.
import numpy as np
from scipy import stats
# Ingresos de dos grupos (ej. con y sin programa de capacitación)
grupo_control = np.array([25000, 27000, 26500, 24000, 28000])
grupo_tratamiento = np.array([28000, 31000, 29500, 30000, 32000])
# Realizar la prueba t para muestras independientes
t_stat, p_valor = stats.ttest_ind(grupo_tratamiento, grupo_control)
print(f"Estadístico t: {t_stat:.2f}")
print(f"P-valor: {p_valor:.4f}")
if p_valor < 0.05:
print("La diferencia es estadísticamente significativa.")
else:
print("No hay evidencia de una diferencia significativa.")
Análisis de Regresión con Statsmodels
La regresión lineal es quizás la herramienta más fundamental en econometría. Nos permite modelar la relación entre una variable dependiente (Y) y una o más variables independientes (X). Por ejemplo, podemos estimar cómo la tasa de interés (X) afecta la inversión (Y).
La biblioteca statsmodels
ofrece una sintaxis de fórmula muy intuitiva (similar a R) para definir y estimar estos modelos. El resultado principal es la tabla de resumen, que nos da los coeficientes estimados, su significancia estadística (P>|t|
) y medidas de ajuste del modelo como el R-cuadrado.
import pandas as pd
import statsmodels.formula.api as smf
# Datos simulados de consumo e ingreso
data = {'ingreso': [10, 12, 15, 18, 22, 25],
'consumo': [8, 9, 11, 15, 18, 20]}
df = pd.DataFrame(data)
# Definir y ajustar el modelo de regresión lineal
# La fórmula 'consumo ~ ingreso' significa "explicar consumo en función de ingreso"
modelo = smf.ols('consumo ~ ingreso', data=df).fit()
# Imprimir el resumen con los resultados
print(modelo.summary())
Visualizar la relación con un diagrama de dispersión y la línea de regresión ajustada es un paso crucial para interpretar los resultados.
Análisis de Series Temporales
Índices de Tiempo y Transformaciones
El pilar del análisis de series temporales en Pandas es el DatetimeIndex
. Permite operaciones potentes como el remuestreo (.resample()
) para cambiar la frecuencia y las ventanas móviles (.rolling()
) para suavizar las series y revelar tendencias.
import pandas as pd
# df es un DataFrame con un DatetimeIndex
# Suavizar la serie con una media móvil de 7 días
df['valor_suavizado'] = df['valor'].rolling(window=7).mean()
# Cambiar la frecuencia de diaria a mensual
df_mensual = df['valor'].resample('M').mean()
Modelo ARIMA
Descomposición y Autocorrelación
Antes de modelar, descomponemos una serie en Tendencia, Estacionalidad y Residuo. Luego, usamos los gráficos de la Función de Autocorrelación (ACF) y Parcial (PACF) para entender la "memoria" de la serie, lo cual es fundamental para especificar modelos como ARIMA.
from statsmodels.graphics.tsaplots import plot_acf, plot_pacf
import matplotlib.pyplot as plt
# Suponiendo que 'serie_estacionaria' es una Serie de Pandas
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(14, 5))
plot_acf(serie_estacionaria, ax=ax1, lags=20)
ax1.set_title('Función de Autocorrelación (ACF)')
plot_pacf(serie_estacionaria, ax=ax2, lags=20)
ax2.set_title('Función de Autocorrelación Parcial (PACF)')
plt.show()
Modelos de Suavizado: SMA y SES
Los modelos de suavizado son técnicas intuitivas para pronosticar. La Media Móvil Simple (SMA) promedia observaciones pasadas, mientras que el Suavizado Exponencial Simple (SES) asigna pesos que decrecen exponencialmente.
from statsmodels.tsa.api import SimpleExpSmoothing
# df_ventas es una Serie de Pandas
modelo_ses = SimpleExpSmoothing(df_ventas, initialization_method="estimated").fit()
pronostico = modelo_ses.forecast(3) # Pronosticar 3 períodos
print("Pronóstico SES:", pronostico)
Modelos ARIMA para Pronósticos
Los modelos ARIMA (Autoregressive Integrated Moving Average) son una de las herramientas más poderosas para el pronóstico de series de tiempo. Modelan la próxima observación como una función lineal de las observaciones pasadas (AR), errores pasados (MA) y diferenciaciones para hacer la serie estacionaria (I).
La elección de los órdenes (p, d, q) del modelo se guía por el análisis de los gráficos ACF y PACF. Una vez ajustado el modelo, podemos usarlo para generar pronósticos fuera de la muestra con intervalos de confianza.
from statsmodels.tsa.arima.model import ARIMA
import pandas as pd
# Suponiendo que 'serie_pbi' es una serie de tiempo de Pandas
# Ajustamos un modelo ARIMA(p=1, d=1, q=1)
modelo = ARIMA(serie_pbi, order=(1, 1, 1))
resultado = modelo.fit()
# Generar un pronóstico para los próximos 4 trimestres
pronostico = resultado.forecast(steps=4)
print("Pronóstico PBI (próximos 4 trimestres):")
print(pronostico)
Modelado Econométrico Avanzado
Una vez dominadas las bases, podemos explorar técnicas econométricas más sofisticadas que nos permiten capturar dinámicas complejas en los datos, como la volatilidad variable en el tiempo y las interdependencias entre múltiples variables.
Estadística Profunda: Pruebas de Estacionariedad
La mayoría de los modelos de series de tiempo requieren que los datos sean estacionarios (que su media, varianza y autocorrelación no cambien con el tiempo). Una serie no estacionaria puede llevar a regresiones espurias y conclusiones erróneas. La prueba más común para verificar la estacionariedad es la Prueba de Dickey-Fuller Aumentada (ADF).
La hipótesis nula de la prueba ADF es que la serie tiene una raíz unitaria (es decir, no es estacionaria). Si el p-valor es menor a 0.05, rechazamos la hipótesis nula y concluimos que la serie es estacionaria.
from statsmodels.tsa.stattools import adfuller
# Suponiendo que 'serie_pbi' es una serie de Pandas
resultado_adf = adfuller(serie_pbi.dropna())
print(f'Estadístico ADF: {resultado_adf[0]:.2f}')
print(f'p-valor: {resultado_adf[1]:.4f}')
if resultado_adf[1] < 0.05:
print('Resultado: La serie es estacionaria.')
else:
print('Resultado: La serie no es estacionaria.')
Modelos GARCH para Volatilidad
En finanzas, es común observar "clusters de volatilidad": períodos de alta volatilidad seguidos por más alta volatilidad, y viceversa. Los modelos GARCH (Generalized Autoregressive Conditional Heteroskedasticity) están diseñados para capturar esta dinámica, modelando la varianza condicional de la serie.
Son fundamentales para la gestión de riesgos, la valoración de opciones y el análisis de mercados financieros. La biblioteca arch
es el estándar en Python para estos modelos.
from arch import arch_model
# 'retornos' es una serie de Pandas de retornos de un activo
# Ajustamos un modelo GARCH(1,1) estándar
modelo_garch = arch_model(retornos, vol='Garch', p=1, q=1)
resultado_garch = modelo_garch.fit(disp='off') # disp='off' para no imprimir el output de convergencia
print(resultado_garch.summary())
Modelos VAR para Múltiples Series
Cuando queremos analizar las interdependencias dinámicas entre varias series de tiempo (ej. cómo se afectan mutuamente la inflación, el PBI y la tasa de interés), usamos Vectores Autorregresivos (VAR). Un modelo VAR trata a cada variable como una función lineal de sus propios valores pasados y de los valores pasados de todas las demás variables en el sistema.
Son muy utilizados en macroeconomía para análisis de impulso-respuesta y pronósticos conjuntos.
from statsmodels.tsa.api import VAR
# 'df_macro' es un DataFrame con columnas 'inflacion', 'pbi', 'interes'
# Es crucial que las series sean estacionarias antes de usar VAR
modelo_var = VAR(df_macro_estacionario)
resultado_var = modelo_var.fit(maxlags=4, ic='aic') # Selecciona el lag óptimo
# Pronosticar 5 períodos hacia adelante
pronostico_var = resultado_var.forecast(df_macro_estacionario.values[-resultado_var.k_ar:], steps=5)
print(pronostico_var)
Estadística Profunda: Causalidad de Granger
La prueba de Causalidad de Granger es una prueba de hipótesis estadística para determinar si una serie de tiempo es útil para pronosticar otra. Si el conocimiento pasado de la serie X reduce el error de pronóstico de la serie Y, entonces decimos que "X Granger-causa a Y".
Es importante no interpretar esto como causalidad en el sentido filosófico, sino como una medida de predictibilidad. Un p-valor bajo (< 0.05) sugiere la presencia de Causalidad de Granger.
from statsmodels.tsa.stattools import grangercausalitytests
# 'df_causal' es un DataFrame con dos columnas, ej. 'gasto_publico' e 'pbi'
max_lags = 4
resultado_granger = grangercausalitytests(df_causal[['pbi', 'gasto_publico']], maxlag=max_lags, verbose=False)
# Analizar el p-valor para cada lag
for lag in range(1, max_lags + 1):
p_valor = resultado_granger[lag][0]['ssr_ftest'][1]
print(f'Lag {lag}: P-valor = {p_valor:.4f}')
Introducción al Machine Learning para Pronósticos
Preparando Datos para Modelos de ML
A diferencia de los modelos ARIMA que entienden la estructura temporal de forma inherente, los modelos de Machine Learning (ML) como los bosques aleatorios (`Random Forest`) requieren que transformemos la serie de tiempo en un problema de aprendizaje supervisado. Esto se logra creando un "feature matrix" donde las columnas son los rezagos de la variable, que actuarán como predictores, y la variable objetivo es el valor actual.
# Función para crear características (rezagos) y el objetivo
def crear_features_series_tiempo(serie, n_lags=5):
df = pd.DataFrame()
for i in range(n_lags, 0, -1):
df[f'lag_{i}'] = serie.shift(i)
df['target'] = serie
return df.dropna()
datos_ml = crear_features_series_tiempo(unrate['UNRATE'], n_lags=5)
X = datos_ml.drop('target', axis=1) # Predictores (rezagos)
y = datos_ml['target'] # Objetivo (valor actual)
print(X.head())
Entrenando un `RandomForestRegressor` con Scikit-Learn
Scikit-Learn es la librería por excelencia para el Machine Learning en Python. Su API es uniforme y fácil de usar: instanciamos un modelo, lo entrenamos con .fit(X, y)
y hacemos predicciones con .predict(X_nuevos)
.
Los modelos como `RandomForestRegressor` son muy potentes porque pueden capturar relaciones no lineales complejas entre los predictores y la variable objetivo, a menudo superando a los modelos lineales clásicos en tareas de pronóstico puro.
from sklearn.ensemble import RandomForestRegressor
from sklearn.model_selection import train_test_split
# Dividir los datos en entrenamiento y prueba (respetando el orden temporal)
train_size = int(len(X) * 0.8)
X_train, X_test = X[:train_size], X[train_size:]
y_train, y_test = y[:train_size], y[train_size:]
# Instanciar y entrenar el modelo
modelo_rf = RandomForestRegressor(n_estimators=100, random_state=42)
modelo_rf.fit(X_train, y_train)
# Hacer predicciones en el conjunto de prueba
predicciones_rf = modelo_rf.predict(X_test)
# Comparar predicciones con valores reales
df_comparacion = pd.DataFrame({'real': y_test, 'prediccion_rf': predicciones_rf})
print(df_comparacion.head())
Caso Aplicado: Análisis de la Coyuntura Económica Argentina
Fase 1: Obtención y Preparación de Datos
El primer paso es recolectar y preparar los datos. En un proyecto real, usaríamos pd.read_csv()
o APIs. Para este ejemplo, crearemos un DataFrame con datos mensuales simulados de indicadores clave: Estimador Mensual de Actividad Económica (EMAE), Inflación (IPC) y el tipo de cambio Dólar CCL.
import pandas as pd
import numpy as np
# 1. Creación de datos simulados realistas
fechas = pd.date_range('2022-01-01', '2024-12-01', freq='MS')
n = len(fechas)
emae = 145 + np.cumsum(np.random.randn(n) * 0.5) # Base 145, con tendencia
ipc = 6 + np.sin(np.arange(n) * 0.5) * 2 + np.random.rand(n) * 2 # Base 6% con estacionalidad
ccl = 200 * np.exp(np.cumsum(np.random.randn(n) * 0.05)) # Crecimiento exponencial
df = pd.DataFrame({'EMAE': emae, 'IPC': ipc, 'CCL': ccl}, index=fechas)
# 2. Calcular variaciones mensuales para análisis
df['EMAE_var'] = df['EMAE'].pct_change() * 100
df['CCL_var'] = df['CCL'].pct_change() * 100
print("Últimos 5 meses de datos preparados:")
print(df.tail())
Fase 2: Análisis Exploratorio y Visualización
Visualizamos las series para entender su comportamiento inicial. Graficamos los niveles originales y también una matriz de correlación de sus variaciones para detectar posibles relaciones.
import seaborn as sns
import matplotlib.pyplot as plt
# Graficar la evolución de las variaciones
df[['EMAE_var', 'IPC', 'CCL_var']].plot(
figsize=(12, 7),
title='Evolución de Indicadores Mensuales Clave',
subplots=True, # Cada variable en su propio subgráfico
layout=(3, 1),
grid=True,
legend=True
)
plt.tight_layout() # Ajusta el espaciado
plt.show()
# Matriz de Correlación
plt.figure(figsize=(8, 6))
sns.heatmap(df[['EMAE_var', 'IPC', 'CCL_var']].corr(), annot=True, cmap='viridis', fmt='.2f')
plt.title('Matriz de Correlación de Variaciones Mensuales')
plt.show()
Fase 3: Modelado y Pronóstico
Ahora, aplicamos un modelo ARIMA para pronosticar la inflación (IPC). El proceso incluye: 1) Verificar estacionariedad con la prueba ADF, 2) Analizar ACF/PACF para elegir órdenes (p,d,q), 3) Ajustar el modelo ARIMA y 4) Generar un pronóstico.
from statsmodels.tsa.stattools import adfuller
from statsmodels.tsa.arima.model import ARIMA
from statsmodels.graphics.tsaplots import plot_acf, plot_pacf
# 1. Verificar estacionariedad de la inflación (IPC)
ipc_series = df['IPC'].dropna()
adf_test = adfuller(ipc_series)
print(f'ADF p-valor para IPC: {adf_test[1]:.4f}') # Si > 0.05, no es estacionaria
# Suponiendo que no es estacionaria, la diferenciamos
ipc_diff = ipc_series.diff().dropna()
# 2. Analizar ACF y PACF para elegir p y q (d=1 por la diferenciación)
# plot_acf(ipc_diff), plot_pacf(ipc_diff) ... (código visual omitido)
# Basado en el análisis (hipotético), elegimos un ARIMA(1,1,1)
# 3. Ajustar el modelo ARIMA
modelo_ipc = ARIMA(ipc_series, order=(1, 1, 1)).fit()
print(modelo_ipc.summary())
# 4. Generar y graficar el pronóstico
pronostico = modelo_ipc.get_forecast(steps=6)
pronostico_df = pronostico.conf_int(alpha=0.05)
pronostico_df['mean'] = pronostico.predicted_mean
plt.figure(figsize=(10, 6))
plt.plot(ipc_series, label='Observado')
plt.plot(pronostico_df['mean'], label='Pronóstico', color='red')
plt.fill_between(pronostico_df.index, pronostico_df['lower IPC'], pronostico_df['upper IPC'], color='red', alpha=0.1)
plt.title('Pronóstico de Inflación (IPC) con ARIMA')
plt.legend()
plt.show()
Herramientas y Próximos Pasos
Google Colab: Mejores Prácticas
Google Colab es un entorno ideal para comenzar. Permite escribir y ejecutar código Python en la nube sin configuración. Es compatible con ipywidgets
, una biblioteca para construir interfaces interactivas.
Mueve el control deslizante para ver un ejemplo de interactividad, cambiando la amplitud de la onda senoidal en tiempo real.
from ipywidgets import interact
import numpy as np
import matplotlib.pyplot as plt
def plot_sine(amplitud=1.0):
x = np.linspace(0, 10, 100)
y = amplitud * np.sin(x)
plt.figure(figsize=(8, 4))
plt.plot(x, y)
plt.ylim(-5.5, 5.5)
plt.title(f'Onda Senoidal con Amplitud {amplitud:.1f}')
plt.show()
# Esto crearía el widget interactivo en Jupyter/Colab
interact(plot_sine, amplitud=(0.1, 5.0, 0.1));
Gestión de Paquetes con `pip` en Notebooks
Para poder usar librerías como Pandas, Statsmodels o Seaborn, primero deben estar instaladas en tu entorno de Python. La herramienta estándar para esto es `pip`, el gestor de paquetes de Python.
En entornos de notebook como Jupyter o Google Colab, puedes ejecutar comandos de la terminal directamente en una celda de código si los precedes con un signo de exclamación (!
). Esta es la forma más sencilla de gestionar paquetes sin salir de tu análisis.
Los comandos más importantes son:
- Instalar un paquete:
!pip install nombre_del_paquete
- Instalar una versión específica:
!pip install nombre_del_paquete==1.2.3
(¡clave para la reproducibilidad!) - Actualizar un paquete:
!pip install --upgrade nombre_del_paquete
- Listar paquetes instalados:
!pip list
(muy útil para depurar y ver qué versiones tienes)
# Instalar la librería para modelos GARCH
!pip install arch
# Instalar una versión específica de statsmodels para asegurar la compatibilidad
!pip install statsmodels==0.14.0
# Actualizar pandas a su última versión
!pip install --upgrade pandas
# Mostrar los paquetes instalados en el entorno
!pip list
Vías para un Aprendizaje Adicional
Este curso es solo el comienzo. El campo del análisis econométrico es vasto y apasionante. Te animamos a explorar temas más avanzados para continuar tu desarrollo:
- Modelos Avanzados de ST: Profundiza en modelos SARIMA (para estacionalidad compleja), VAR/VECM (para relaciones de cointegración), y modelos de Espacio de Estados (como Unobserved Components).
- Adquisición Automatizada de Datos: Aprende a usar APIs de fuentes como el Banco Mundial, FMI, FRED, o librerías como
yfinance
para obtener datos financieros en tiempo real. El web scraping es otra habilidad valiosa. - Estadística Profunda: Además de las pruebas vistas, investiga sobre pruebas de normalidad de residuos, heterocedasticidad (como Breusch-Pagan), y de cointegración (como la prueba de Johansen).
- Machine Learning para Pronósticos: Explora cómo algoritmos como Random Forest, Gradient Boosting (XGBoost, LightGBM) y redes neuronales (LSTM, GRU) pueden aplicarse a problemas de pronóstico económico, a menudo superando a los modelos clásicos.