Mostrando entradas con la etiqueta DGSE. Mostrar todas las entradas
Mostrando entradas con la etiqueta DGSE. Mostrar todas las entradas

7 ago 2024

Simulación, calibración y estimación: ejemplos en AR(1) en R

 Las palabras simular, estimar, calibrar e identificar, aparecen de forma recurrente en la economía aplicada. Estas representan una extensión de la forma de pensar y el desarrollo de aplicaciones teóricas.  Es frecuente que la identificación y calibración se tomen como sub conjuntos de la estimación. Suponga observamos una serie y(t), sobre la que suponemos sigue un proceso ar(1). Por ejemplo:

 y(t)=phi_1* y(t-1)+ e(t)  e(t)~N(0,sigma)

Podemos a partir de ciertos supuestos simular una serie que cumpla con estas características, con el objetivo de estudiar sus propiedades o su comportamiento bajo ciertas modificaciones. Un caso distinto es intentar recuperar los coeficientes phi_1 y sigma de un AR(1), aquí entra la estimación, que permite obtenerlos a partir de algún procedimiento estadístico como el de Mínimo Cuadrados Ordinarios (MCO) o máxima verosimilitud (mle). Mientras que la calibración, también pretende recuperar los coeficientes del modelo, pero a partir de suposiciones o conocimientos previos, buscando que el valor calibrado permita obtener una variable y*(t) parecida al valor observado. 

 1.       Simular

 En la siguiente entrada se simula en R un autoregresivo ar(1):

 y(t)=0.8* y(t-1)+ e(t)  e(t)~N(0,1)

 Se muestra que la simulación de series temporales, y entre calibrar y estimar un modelo. “Simular datos implica generar una serie temporal sintética a partir de un modelo AR(1) con parámetros conocidos” (ChatGPT, 2024).

 # Cargar las librerías necesarias

library(ggplot2)
library(dplyr)
library(tidyr)
library(stats4)
 
# Simular ---------------------
# Parámetros del modelo AR(1)
phi <- 0.8
sigma <- 1
n <- 100
 
# Simular la serie temporal
set.seed(2)
y <- numeric(n)
y[1] <- rnorm(1, mean = 0, sd = sigma)
 
for (t in 2:n) {
  y[t] <-  phi * y[t-1] + rnorm(1, mean = 0, sd = sigma)
}
 
# Crear una secuencia de fechas
fechas <- seq.Date(from = as.Date("2000-01-01"), by = "days", length.out = n)
 
# Crear un data frame con la serie temporal simulada
data <- data.frame(fecha = fechas, y = y)
 
ggplot(data, aes(fechas, y)) +
  geom_line() +
  theme_minimal()

2.       Calibrar

“Calibrar un modelo implica ajustar los parámetros del modelo basándose en conocimientos previos o estimaciones empíricas sin realizar un proceso formal de estimación. Es una forma de "ajustar" el modelo para que sea razonable para la situación específica. La calibración se refiere ajustar los parámetros del modelo basándose en conocimientos previos o estimaciones empíricas sin un proceso formal de estimación. Utiliza datos observados pero no sigue un método estadístico forma” (ChatGPT, 2024).

En la práctica, consiste en seleccionar un conjunto de parámetros de preferencia a partir de las referencias disponibles en la teoría económica, con la intención de que los modelos imiten alguna característica histórica de los datos (Hoover, 1995). Es decir, “La calibración se realiza con mayor frecuencia probando distintos valores para los parámetros hasta que el modelo logre predicciones con la menor desviación posible de los datos o reproduzca otras características empíricas” (Stackexchange, 2020). Los modelos calibrados son una herramienta importante de la investigación económica, esta herramienta ha surgido como evolución y extensión de la capacidad de los economistas para teorizar (Cooley, 1997).

# Serie temporal observada (ejemplo)
y_obs <- y
 
# Calibración: Asumir un valor razonable para phi
phi_calibrado <- 0.8
 
phi_calibrado <- 0.8
y_calibrado <- numeric(n)
y_calibrado[1] <- y[1]
 
for (t in 2:n) {
  y_calibrado[t] <- phi_calibrado * y_calibrado[t-1] + rnorm(1, mean = 0, sd = sigma)
}
 
data$y_calibrado <- y_calibrado
 
ggplot(data) +
  geom_line(aes(fechas, y, color = "Obs")) +
  geom_line(aes(fechas, y_calibrado, color = "Calibrado")) +
  theme_minimal()

 

Algunas recomendaciones identificadas en la literatura:

 ·         No justificar el uso solo porque otros autores lo han utilizado (Cooley, 1997).

 3.       Estimar

 La estimación toma los datos como dados y los utilizan para determinar los parámetros del modelo a partir de un estadístico (que es una función de la muestra), buscando que este sea insesgado, consistente y eficiente. En este procedimiento, el valor de un estadístico se utiliza para estimar un parámetro, por tanto, la estimación “utiliza métodos estadísticos formales (como MLE) para determinar los parámetros del modelo a partir de los datos observados. Es un enfoque más riguroso que la calibración y proporciona estimaciones con propiedades estadísticas deseables” (ChatGPT, 2024). En otras palabras, se utiliza un procedimiento estadístico formal para la estimación de los coeficientes del modelo.

 # Estimación usando MLE
library(stats4)
 
# Log-verosimilitud de un modelo AR(1)
logLik_AR1 <- function(phi, sigma) {
  n <- length(y_obs)
  eps <- numeric(n)
  eps[1] <- y_obs[1] # inicializamos el primer error
 
  for (t in 2:n) {
    eps[t] <- y_obs[t] - phi * y_obs[t-1]
  }
 
  logLik <- -0.5 * n * log(2 * pi * sigma^2) - sum(eps^2) / (2 * sigma^2)
  return(logLik)
}
 
# Función de verosimilitud negativa para optimización
negLogLik_AR1 <- function(phi, sigma) {
  -logLik_AR1(phi, sigma)
}
 
# Optimizar para encontrar los parámetros MLE
mle_fit <- mle(negLogLik_AR1, start = list(phi = 0.5, sigma = 1))
 
# Resultados de la estimación
summary(mle_fit)
 
Maximum likelihood estimation
 
Call:
mle(minuslogl = negLogLik_AR1, start = list(phi = 0.5, sigma = 1))
 
Coefficients:
       Estimate Std. Error
phi   0.7218984 0.06979479
sigma 1.1476188 0.08114858
 
-2 log L: 311.3256

# -------------------------------------------------------------------------------------
# Obtener los parámetros estimados
phi_estimado <- coef(mle_fit)["phi"]
sigma_estimado <- coef(mle_fit)["sigma"]
 
# Generar la serie temporal con los parámetros estimados
y_estimado <- numeric(n)
y_estimado[1] <- y[1]
 
for (t in 2:n) {
  y_estimado[t] <- phi_estimado * y_estimado[t-1] + rnorm(1, mean = 0, sd = sigma_estimado)
}
 
data$y_estimado <- y_estimado
 
# Graficar los datos simulados, calibrados y estimados
data_long <- data %>%
  pivot_longer(cols = c(y, y_calibrado, y_estimado), names_to = "serie", values_to = "valor")
 
ggplot(data_long, aes(x = fecha, y = valor, color = serie)) +
  geom_line(size = 0.7) +
  theme_minimal() +
  labs(title = "Simulación, Calibración y Estimación de un Modelo AR(1)",
       x = "Fecha", y = "Valor",
       color = "Serie") +
scale_color_manual(values = c("y" = "black", "y_calibrado" = "green", "y_estimado" = "red")) +
  theme(plot.title = element_text(hjust = 0.5),
        legend.position = "bottom")

Bibliography

Cooley, T. (1997). Calibrated Models. University of Rochester.

Hoover, K. (1995). Facts and artifacts: calibration and the empirical assessment of real-business-cycle models. Oxford Economic Papers 47 (1), 24-44.

 

23 nov 2022

Modelo de análisis macroeconómico Bayesiano en IRIS

La siguiente entrada muestra como especificar un Modelo de Análisis Macroeconómico Bayesiano para la economía dominicana, disponible como serie de estudio en la pagina del Banco Central de la República Dominicana. Esta aplicación se realiza en IRIS (Macroeconomic Modeling Toolbox) un paquete desarrollado por el Fondo Monetario Internacional.

Posterior a instalar el paquete IRIS y anexarlo al path de MATLAB. En primer lugar es necesario desarrollar el archivo “.model”, que es un script en Matlab donde presentamos las variables, los parámetros y las ecuaciones del modelo. El detalle de esta estructura puede verse en el paper presentado por Franz Hanann y mencionado anteriormente.

!variables
"brecha del producto" y_gap
"brecha de tasa de interes real" r_gap
"inflacion trimestral anualizada" pic
"tasa de politica monetaria" tpm  
"inflacion interanual" picA 
"log pib" y    
"pib potencial" y_pot
"tasa de interes real" r  

!shocks
 
 "choque de brecha del producto" eta_y_gap
 "choque de oferta o costes" eta_pic
 "choque de politica monetaria" eta_tpm
 "choque de pib potencial" eta_y_pot
 
!parameters
 
%brecha del producto
"persistencia de la brecha del producto" bet_1
"componente prospectivo, expectativas" bet_2
"elasticidad de la brecha de tasa, pendiente curba IS" bet_3
 
%curva de Phillips
"inercia inflacionaria" alp_1
"componente prospectivo expectativas" alp_2
"pendiente curva de Phillips" alp_3 %mas pequeno, menos sensible es la inflacion a la brecha

% Regla de Taylor
"persistencia tpm" phi_tpm
"parametro de taylor" phi_pic
"brecha del producto" phi_y_gap
 
% parametros de largo plazo
"meta de tasa" meta_pic
"Tasa de interes neutral" i_neutral
"Tasa de interes real de largo plazo" r_neutral
"Crecimiento potencial" gA_pot
 
!equations
 
 %brecha del producto
 y_gap = bet_1*y_gap{-1}+ bet_2*y_gap{+1}-bet_3*r_gap + eta_y_gap;
   
 %curva de phillips
 pic = alp_1*pic{-1}+alp_2*pic{+1}+alp_3*y_gap+eta_pic;
   
 %regla de politica
 tpm = phi_tpm*tpm{-1}+(1-phi_tpm)*(i_neutral+phi_pic*(picA{-1}-meta_pic)+phi_y_gap*y_gap)+eta_tpm;

   
 % tasa de interes real
 r = tpm - pic{-1};
   
 %brecha de la tasa de interes real
 r_gap = r - r_neutral;
   
 %log pib
 y=y_gap+y_pot;
   
 %log pib pot
 y_pot=y_pot{-1} + eta_y_pot; %+ 0.25*gA_pot 
   
 %inflacion anual
 picA=0.25*(pic+pic{-1}+pic{-2}+pic{-3});

Posteriormente, una vez hayamos generado esta estructura, es necesario definir el valor de los parámetros y correr los programas que resuelven el modelo. Usamos la función Model.fromFile Que carga la estructura del modelo, colocado anteriormente en un scipt de extensión “.model”. Note que posteriormente asignamos el valor de estimación a los parámetros del modelo para posteriormente resolver el estado estacionario del modelo.

%% Clear workspace
clear;
close all;
clc;
%#ok<*NOPTS>
 
%% Load model file and create model object
 
m = Model.fromFile("EcnCerrada.model");
 
%% Assign parameters
 
%brecha del producto
m.bet_1 = 0.5;  %persistencia de la brecha del producto
m.bet_2 = 0.05; %componente prospectivo, expectativas
m.bet_3 = 0.20; %elasticidad de la brecha de tasa, pendiente curba IS
 
%curva de Phillips
m.alp_1 = 0.4;       %inercia inflacionaria
m.alp_2 = (1-m.alp_1); %componente prospectivo, expectativas
m.alp_3 = 0.10;     %pendiente curva de Phillips. mas pequeno, menos sensible es la inflacion a la brecha
 
% Regla de Taylor
m.phi_tpm = 0.7; %persistencia tpm
m.phi_pic = 1.5; %a mayor, mayor es la respuesta de la polibica a la infalcion. parametro de taylor (tema: este se puede estimar)
m.phi_y_gap = 0.5; %brecha del producto

% parametros de largo plazo
m.meta_pic = 4; %meta de tasa
m.i_neutral = 6; %promedio de la tasa entre 2013-2019
m.r_neutral = m.i_neutral-m.meta_pic; %tasa de interes real de largo plazo
m.gA_pot = 5.1;
 
%% Compute steady state
% * Calculate (stationary) steady state for given parameters
% * Make sure it is a valid steady state
% * Print a steady state table
 
m = steady(m);
checkSteady(m);
 
%% Show a steady state table
 
table(m, ["steadyLevel", "description"])
 
%% Calculate first-order solution matrices
%
% Run `solve()` to calculate a first-order expansion of the model
% equations around the steady state, and finds a first-order
% rational-expectations solution. The solution matrices (state-space
% matrices) are stored within the model object; they are examined in
% <know_all_about_solution>. The availability of a first-order solution is
% indicated the model object is displayed.
 
m = solve(m)

Ahora se generan la estructura de data para simular choques y recuperar impulso respuesta.  Aquí asignamos valores a los choques (d2.eta_tpm(1:5) = 1;) para posteriormente ver la repuesta del sistema a esta perturbación. Finalmente estudiamos gráficamente la respuesta de 4 variables ('y_gap', 'r_gap', 'y', 'pic') a este tipo de perturbación. Observándose, como es natural que los choques mas persistente tienen a tener un efecto mayor en la evolución de las variables.


%% Find steady state
% * Create a steady-state database
% * Enter a productivity shock
% * Display the input time series for the shock on the screen
 
d0 = steadydb(m, 1:40)
d = d0;
d.eta_tpm(1) = 1;
disp(d.eta_tpm);
 
%% Choque en la tasa de politica monetaria
d1 = d;
d1 = sstatedb(m, 1:40);
d1.eta_tpm(1) = 1;
disp(d1.eta_tpm)

s1 = simulate(m, d1, 1:40); %simula impulso respuesta choque
 
%choque mas persistente.
% Parte de un escenario nuevo
d2 = d;
d2.eta_tpm(1:5) = 1;
s2 = simulate(m, d2, 1:40);
 
% Gráfico de la variable de interes
s = s1 & s2;
dbplot(s, 0:40, {'y_gap', 'r_gap', 'y', 'pic'}, 'Tight=', true);
 
le = visual.hlegend('bottom', 'No Persistente', 'Persistente');
title(le, 'Choque tpm'); 

Podemos generar el mismo choque, pero en un contexto de mayor persistencia de la inflación, por lo que, modificamos el valor del coeficiente asociado a la persistencia. AL hacer esta modificación en el nivel de persistencia, es importante tener en cuenta el valor de otros coeficientes. Primero clonamos el modelo anterior, modificamos los parámetros y luego pasados a identificar el estado estacionario y solución del modelo en un nuevo objeto. Finalmente, simulamos el choque sobre este nuevo objeto.

m1 = m;

m1.alp_1 = m.alp_1*1.2;
m1.alp_2 = (1-m1.alp_1);
m1 = steady(m1);
m1 = solve(m1)
d3 = sstatedb(m1, 1:40);
d3.eta_tpm(1) = 1;
s3 = simulate(m1, d3, 1:40);
 
% Gráfico de la variable de interes
s = s1 & s3;
dbplot(s, 0:40, {'y_gap', 'r_gap', 'y', 'pic'}, 'Tight=', true);
 
le = visual.hlegend('bottom', 'No Persistente', 'Persistente');
title(le, 'Choque tpm');
 
% Comparar estados
table( ...
    [m, m1], ["steadyLevel", "steadyChange", "form", "description"] ...
    , "writeTable", "steady.xlsx" ...
)

Recodificación de Variables en R

  La recodificación de variables es una tarea esencial en el análisis de datos que nos permite transformar datos continuos en categorías más...