Skip to contents

Overview

Experimental companion functionality. The local IV-GMM layer exists for ongoing companion-paper development; its API and theorem alignment may change before the GMM paper is released. It is not at the maturity level of np_dnn(), cate_dnn(), or plqr_dnn().

This vignette shows the local IV-GMM workflow built on gmm_dnn(). The example uses the doubly robust IV moment model created by gmm_model_dr_iv() and the IV simulation DGPs exposed through sim_iv_data().

These synthetic IV examples are experimental benchmarks. The current affine paper replication is described in Affine paper replication.

One Local IV Dataset

sim_iv_data() returns a data frame with observed variables, oracle nuisance columns, the target point x0, and the true local IV target theta_x0.

iv <- sim_iv_data(
  design = "dgp2_iv_homog_overid",
  n = 160L,
  kx = 2L,
  q = 2L,
  seed = 1L
)

head(iv$data[, c("X1", "X2", "Z1", "Z2", "D", "Y")])
#>           X1         X2 Z1 Z2 D           Y
#> 1 -0.6264538  0.4251004  1  1 1 -0.25030342
#> 2  0.1836433 -0.2386471  0  1 0  0.97721039
#> 3 -0.8356286  1.0584830  1  1 1  0.09061671
#> 4  1.5952808  0.8864227  1  0 0  1.47933239
#> 5  0.3295078 -0.6192430  0  1 0  1.00297300
#> 6 -0.8204684  2.2061025  0  0 0 -0.44669891
iv$theta_x0
#> [1] 1.211738

Fitting the DR-IV GMM Model

The DR-IV model factory records which columns contain the outcome, treatment, instruments, and nuisance estimates. In this example the nuisance columns are oracle values generated by the DGP.

model_iv <- gmm_model_dr_iv(
  y_col = "Y",
  d_col = "D",
  z_cols = c("Z1", "Z2"),
  pi_cols = c("piZ1_oracle", "piZ2_oracle"),
  muY_col = "muY_oracle",
  muD_col = "muD_oracle"
)

fit_iv <- gmm_dnn(
  data = iv$data,
  x_cols = c("X1", "X2"),
  x0 = iv$x0,
  model = model_iv,
  k = 1L,
  s = 12L,
  se = TRUE,
  return = "ess"
)

fit_iv$theta
#>       target_1
#> theta  0.51562
fit_iv$se
#>        target_1
#> theta 0.7900163
fit_iv$J
#>   target_1 
#> 0.09635039
fit_iv$pval_J
#>  target_1 
#> 0.7562541
fit_iv$neff
#> target_1 
#> 24.67559

summary() and confint() expose the same fitted object in reporting form:

summary(fit_iv)
#> <summary.gmm_result>
#>   model  : dr_iv
#>   targets: 1
#>     target  term estimate std.error statistic p.value conf.low conf.high
#> 1 target_1 theta   0.5156      0.79    0.6527   0.514   -1.033     2.064
#> 
#> Overidentification diagnostics:
#>     target       J df p.value  neff
#> 1 target_1 0.09635  1  0.7563 24.68
confint(fit_iv)
#>     target  term  conf.low conf.high
#> 1 target_1 theta -1.032784  2.064023

Small IV Simulation

sim_iv_run() expands a grid over designs, sample sizes, covariate dimensions, instrument counts, and Monte Carlo replications. The just-identified design dgp1_iv_justid_linear is always run only once with realized q = 1.

raw_iv <- sim_iv_run(
  designs = c("dgp1_iv_justid_linear", "dgp2_iv_homog_overid"),
  n_vals = 120L,
  kx_vals = 2L,
  q_vals = 2L,
  n_reps = 2L,
  master_seed = 42L,
  k = 1L,
  s_fn = function(n, kx) 10L,
  methods = "iv_oracle",
  verbose = FALSE
)

head(raw_iv)
#>                  design   n kx q  s  seed    method  theta_hat   theta0
#> 1 dgp1_iv_justid_linear 120  2 1 10 61413 iv_oracle  0.2303256 0.000000
#> 2 dgp1_iv_justid_linear 120  2 1 10 54425 iv_oracle -0.3883279 0.000000
#> 3  dgp2_iv_homog_overid 120  2 2 10 61413 iv_oracle  2.3101378 1.211738
#> 4  dgp2_iv_homog_overid 120  2 2 10 54425 iv_oracle  1.1725896 1.211738
#>          bias     sq_err        se cover   ci_len     neff         J df
#> 1  0.23032556 0.05304987 0.5357276     1 2.100013 21.94304        NA NA
#> 2 -0.38832789 0.15079855 1.4282239     1 5.598535 21.94304        NA NA
#> 3  1.09839935 1.20648114 0.6245025     1 2.448005 21.94304 6.0438458  1
#> 4 -0.03914882 0.00153263 0.6264744     1 2.455734 21.94304 0.2041706  1
#>       pval_J reject_J
#> 1         NA       NA
#> 2         NA       NA
#> 3 0.01395485        1
#> 4 0.65137533        0

summarise_iv_results() aggregates to one row per (method, design, n, kx, q) cell and includes local overidentification diagnostics when q > 1.

tab_iv <- summarise_iv_results(raw_iv)
print(tab_iv, digits = 3)
#>      method                design   n kx q n_reps n_failed   bias  rmse se_mean
#> 1 iv_oracle dgp1_iv_justid_linear 120  2 1      2        0 -0.079 0.319   0.982
#> 2 iv_oracle  dgp2_iv_homog_overid 120  2 2      2        0  0.530 0.777   0.625
#>   cover ci_len neff J_median pval_J_median reject_J
#> 1     1   3.85 21.9       NA            NA       NA
#> 2     1   2.45 21.9     3.12         0.333      0.5