test_msel function

Tests and confidence intervals for the parameters estimated by the msel function

Tests and confidence intervals for the parameters estimated by the msel function

This function conducts various statistical tests and calculates confidence intervals for the parameters of the model estimated via the msel function.

test_msel( object, fn, fn_args = list(), test = "t", method = "classic", ci = "classic", cl = 0.95, se_type = "dm", trim = 0, vcov = object$cov, iter = 100, generator = rnorm, bootstrap = NULL, par_ind = 1:object$control_lnL$n_par, eps = max(1e-04, sqrt(.Machine$double.eps) * 10), n_sim = 1000, n_cores = 1 )

Arguments

  • object: an object of class 'msel'. It also may be a list of two objects. Then object[[1]] and object[[2]] are supplied to the arguments model1 and model2 of the lrtest_msel function.

  • fn: a function which returns a numeric vector and should depend on the elements of object. These elements should be accessed via coef.msel or predict.msel functions. The first argument of fn should be an object. Therefore coef and predict functions in fn should also depend on object.

  • fn_args: a list of additional arguments of fn.

  • test: a character representing the test to be used. If test = "t" then t-test is used. If test = "wald" then Wald test is applied.

  • method: a character representing a method used to conduct a test. If test = "t" or test = "wald" and method = "classic"

    then p-values are calculated by using the quantiles of the standard normal distribution. If test = "t" or test = "wald" and method = "bootstrap"

    then p-values are calculated by using the bootstrap as described in Hansen (2022). If test = "wald" and method = "score" then score bootstrap Wald test of P. Kline and A. Santos (2012) is used.

  • ci: a character representing the type of the confidence interval used. Available only if test = "t". If ci = "classic" then quantiles of the standard normal distribution are used to build an asymptotic confidence interval. If ci = "percentile" then percentile bootstrap interval is applied. If ci = "bc" then the function constructs a bias-corrected percentile bootstrap confidence interval of Efron (1982) as described in Hansen (2022).

  • cl: a numeric value between 0 and 1 representing a confidence level of the confidence interval.

  • se_type: a character representing a method used to estimate the standard errors of the outputs of fn. If se_type = "dm" then delta method is used. If se_type = "bootstrap" then bootstrap is applied.

  • trim: a numeric value between 0 and 1 representing the share of bootstrap estimates to be nullified when standard errors are estimated for se_type = "bootstrap".

  • vcov: an estimate of the asymptotic covariance matrix of the parameters of the model.

  • iter: the number of iterations used by the score bootstrap Wald test.

  • generator: function which is used by the score bootstrap to generate random weights. It should have an argument n representing the number of random weights to generate. Other arguments are ignored.

  • bootstrap: an object of class 'bootstrap_msel' which is an output of the bootstrap_msel function. This object is used to retrieve the estimates of the bootstrap samples.

  • par_ind: a vector of indexes of the model parameters used in the calculation of fn. If only necessary indexes are included then in some cases estimation time may greatly decrease. Set ind = TRUE

    in summary.msel to see the indexes of the model parameters. If eps is a vector then eps[i] determines the increment used to differentiate fn respect to the parameter with par_ind[i]-th index.

  • eps: a positive numeric value representing the increment used for the numeric differentiation of fn. It may also be a numeric vector such that eps[i] is an increment used to differentiate the fn respect to the par_ind[i]-th parameter of the model. Set ind = TRUE in summary.msel, to see the indexes of the model parameters. If eps[i] = 0 then derivative of fn respect to par_ind[i]-th parameter is assumed to be zero.

  • n_sim: the value passed to the n_sim argument of the msel function.

  • n_cores: the value passed to the n_cores argument of the msel function.

Returns

This function returns an object of class 'test_msel' which is a list. It may have the following elements:

  • tbl - a list with the elements described below.
  • is_bootstrap - a logical value which equals TRUE if bootstrap has been used.
  • is_ci - a logical value which equals TRUE if confidence intervals were used.
  • test - the same as the input argument test.
  • method - the same as the input argument method.
  • se_type - the same as the input argument method.
  • ci - the same as the input argument ci.
  • cl - the same as the input argument cl.
  • iter - the same as the input argument iter.
  • n_bootstrap - an integer representing the number of the bootstrap iterations used.
  • n_val - the length of the vector returned by fn.

A list tbl may have the following elements:

  • val - an output of the fn function.
  • se - a numeric vector such that se[i] represents a standard error associated with val[i].
  • p_value - a numeric vector of p-values.
  • lwr - a numeric vector such that lwr[i] is the realization of the lower (left) bound of the confidence interval for the true value of val[i].
  • upr - a numeric vector such that upr[i] is the realization of the upper (right) bound of the confidence interval for the true value of val[i].
  • stat - a numeric vector of values of the test statistics.

An object of class 'test_msel' has an implementation of the summary method summary.test_msel.

In a special case when object is a list of length 2 the function returns an object of class 'lrtest_msel' since the function lrtest_msel is called internally.

Details

Suppose that θ\theta is a vector of parameters of the model estimated via the msel function and g(θ)g(\theta) is a differentiable function representing fn which returns a mm-dimensional vector of real values:

g(θ)=(g1(θ),...,gm(θ))T. g(\theta) = (g_{1}(\theta),...,g_{m}(\theta))^{T}.

Classic and bootstrap t-test

If test = "t" then for each j{1,...,m}j\in \{1,...,m\} the following hypotheses is tested:

H0:gj(θ)=0,H1:gj(θ)0. H_{0}:g_{j}(\theta) = 0,\qquad H_{1}:g_{j}(\theta)\ne 0.

The test statistic is:

T=gj(θ^)/σ^j, T = g_{j}(\hat{\theta})/\hat{\sigma}_{j},

where σ^\hat{\sigma} is a standard error of gj(θ^)g_{j}(\hat{\theta}).

If se_type = "dm" then delta method is used to estimate this standard error:

σ^j=gj(θ^)TAs.Cov^(θ^)gj(θ^), \hat{\sigma}_{j} = \sqrt{\nabla g_{j}(\hat{\theta})^{T}\widehat{As.Cov}(\hat{\theta})\nabla g_{j}(\hat{\theta})},

where gj(θ^)\nabla g_{j}(\hat{\theta}) is a gradient as a column vector and the estimate of the asymptotic covariance matrix of the estimates As.Cov^(θ^)\widehat{As.Cov}(\hat{\theta}) is provided via the vcov

argument. Numeric differentiation is used to calculate gj(θ^)\nabla g_{j}(\hat{\theta}).

If se_type = "bootstrap" then bootstrap is applied to estimate the standard error:

σ^j=1B1b=1B(gj(θ^(b))gj(θ^(b)))2, \hat{\sigma}_{j} = \sqrt{\frac{1}{B - 1}\sum\limits_{b = 1}^{B}(g_{j}(\hat{\theta}^{(b)}) - \overline{g_{j}(\hat{\theta}^{(b)}}))^2},

where BB is the number of the bootstrap iterations bootstrap$iter, θ^(b)\hat{\theta}^{(b)} is the estimate associated with the bb-th of these iterations bootstrap$par[b, ], and gj(θ^(b))g_{j}(\overline{\hat{\theta}^{(b)}}) is a sample mean of the bootstrap estimates:

gj(θ^(b))=1Bb=1Bgj(θ^(b)). \overline{g_{j}(\hat{\theta}^{(b)}}) =\frac{1}{B}\sum\limits_{b = 1}^{B}g_{j}(\hat{\theta}^{(b)}).

If method = "classic" it is assumed that if the null hypothesis is true then the asymptotic distribution of the test statistic is standard normal. This distribution is used for the calculation of the p-value:

pvalue=2min(Φ(T),1Φ(T)), p-value = 2\min(\Phi(T), 1 - \Phi(T)),

where Φ()\Phi() is a cumulative distribution function of the standard normal distribution.

If method = "bootstrap" then p-value is calculated via the bootstrap as suggested by Hansen (2022):

pvalue=1Bb=1BI(TbT>T), p-value = \frac{1}{B}\sum\limits_{b=1}^{B} I(|T_{b} - T| > |T|),

where Tb=gj(θ^(b))/σ^jT_{b} = g_{j}(\hat{\theta}^{(b)})/\hat{\sigma}_{j} is the value of the test statistic estimated on the b-th bootstrap sample and I(q)I(q) is an indicator function which equals 11 when qq is a true statement and 00 - otherwise.

Classic and bootstrap Wald test

Suppose that method = "classic" or method = "bootstrap". If test = "wald" then the null hypothesis is:

H0:{g1(θ)=0g2(θ)=0gm(θ)=0. H_{0}:\begin{cases}g_{1}(\theta) = 0\\g_{2}(\theta) = 0\\\vdots\\g_{m}(\theta) = 0\\\end{cases}.

The alternative hypothesis is that there is such j{1,...,m}j\in\{1,...,m\} that:

H1:gj(θ)0. H_{1}:g_{j}(\theta)\ne 0.

The test statistic is:

T=g(θ^)TAs.Cov^(g(θ^))1g(θ^), T = g(\hat{\theta})^{T}\widehat{As.Cov}(g(\hat{\theta}))^{-1}g(\hat{\theta}),

where As.Cov^(g(θ^))\widehat{As.Cov}(g(\hat{\theta})) is the estimate of the asymptotic covariance matrix of g(θ^)g(\hat{\theta}).

If se_type = "dm" then delta method is used to estimate this matrix:

As.Cov^(g(θ^))=g(θ^)As.Cov^(θ^)g(θ^)T, \widehat{As.Cov}(g(\hat{\theta}))= g'(\hat{\theta})\widehat{As.Cov}(\hat{\theta}) g'(\hat{\theta})^{T},

where g(θ^)g'(\hat{\theta}) is a Jacobian matrix. A numeric differentiation is used to calculate its elements:

g(θ^)ij=gi(θ)θjθ=θ^. g'(\hat{\theta})_{ij} =\frac{\partial g_{i}(\theta)}{\partial \theta_{j}}|_{\theta = \hat{\theta}}.

If se_type = "bootstrap" then bootstrap is used to estimate this matrix:

As.Cov^(g(θ^))=1B1i=1BqbqbT, \widehat{As.Cov}(g(\hat{\theta}))=\frac{1}{B-1}\sum\limits_{i=1}^{B}q_{b}q_{b}^{T},

where:

qb=(g(θ^(b))g(θ^(b))), q_{b} = (g(\hat{\theta}^{(b)}) -\overline{g(\hat{\theta}^{(b)})}), g(θ^(b))=1Bi=1Bg(θ^(b)). \overline{g(\hat{\theta}^{(b)})} = \frac{1}{B}\sum\limits_{i=1}^{B}g(\hat{\theta}^{(b)}).

If method = "classic" then it is assumed that if the null hypothesis is true then the asymptotic distribution of the test statistic is chi-squared with mm degrees of freedom. This distribution is used for the calculation of the p-value:

pvalue=1Fm(T), p-value = 1 - F_{m}(T),

where FmF_{m} is a cumulative distribution function of the chi-squared distribution with mm degrees of freedom.

If method = "bootstrap" then p-value is calculated via the bootstrap as suggested by Hansen (2022):

pvalue=1Bb=1BI(Tb>T), p-value = \frac{1}{B}\sum\limits_{b=1}^{B} I(T_{b} > T),

where:

Tb=sbTAs.Cov^(g(θ^))1sb, T_{b} = s_{b}^{T}\widehat{As.Cov}(g(\hat{\theta}))^{-1}s_{b}, sb=g(θ^(b))g(θ^). s_{b} = g(\hat{\theta}^{(b)}) - g(\hat{\theta}).

Score bootstrap Wald test

If method = "score" and test = "Wald" then score bootstrap Wald test of Kline and Santos (2012) is used.

Consider BB independent samples of nn independent identically distributed random weights with zero mean and unit variance. Let wibw_{ib} denote the ii-th weight of the bb-th sample. Argument generator is used to supply a function which generates these weights wibw_{ib} and iter argument represents BB. Also nn is the number of observations in the model object$other$n_obs.

Let JJ denote a matrix of sample scores object$J. Further, denote by JbJ_{b} a matrix such that its bb-th row is a product of the wibw_{ib} and the bb-th row of JJ. Also, denote by HH a matrix of mean values of the derivatives of sample scores respect to the estimated parameters object$H.

In addition consider the following notations:

A=g(θ)H1,Sb=AJb(c), A = g'(\theta) H^{-1}, \qquad S_{b} = A J^{(c)}_{b},

where Jb(c)J^{(c)}_{b} is a vector of the column sums of JbJ_{b}.

The test statistic is as follows:

T=g(θ^)T(ACov^(J)AT)1g(θ^)/n, T = g(\hat{\theta})^{T}(A\widehat{Cov}(J)A^{T})^{-1}g(\hat{\theta}) / n,

where Cov^(J)\widehat{Cov}(J) is a sample covariance matrix of the sample scores of the model cov(object$J).

The test statistic on the bb-th bootstrap sample is similar:

Tb=ST(ACov^(Jb)AT)1S/n. T_{b} = S^{T}(A\widehat{Cov}(J_{b})A^{T})^{-1}S / n.

The p-value is estimated as follows:

pvalue=1Bb=1BI(TbT). p-value = \frac{1}{B}\sum\limits_{b=1}^{B} I(T_{b} \geq T).

Confidence intervals

If test = "t" then the function also returns the realizations of the lower and upper bounds of the 100×100 \timescl percent symmetric asymptotic confidence interval of gj(θ)g_{j}(\theta).

If ci = "classic" then classic confidence interval is used which assumes asymptotic normality of gj(θ^)g_{j}(\hat{\theta}):

(gj(θ^)+z(1cl)/2σ^j,gj(θ^)+z1(1cl)/2σ^j), (g_{j}(\hat{\theta}) + z_{(1 - cl) / 2}\hat{\sigma}_{j},g_{j}(\hat{\theta}) + z_{1 - (1 - cl) / 2}\hat{\sigma}_{j}),

where zqz_{q} is a qq-th quantile of the standard normal distribution and clcl is a confidence level cl. The method used to estimate σ^j\hat{\sigma}_{j} depends on the se_type argument as described above.

If ci = "percentile" then percentile bootstrap confidence interval is used. Therefore the sample quantiles of gj(θ^(b))g_{j}(\hat{\theta}^{(b)})

are used as the realizations of the lower and upper bounds of the confidence interval.

If ci = "bc" then bias corrected percentile bootstrap confidence interval of Efron (1982) is used as described in Hansen (2022). The default percentile bootstrap confidence interval uses sample quantiles of levels (1cl)/2(1 - cl)/2 and 1(1cl)/21 - (1 - cl)/2. Bias corrected version uses the sample quantiles of the following levels:

(1cl)/2+Φ(Φ1((1cl)/2)+s), (1 - cl)/2 + \Phi(\Phi^{-1}((1 - cl)/2) + s), 1(1cl)/2+Φ(Φ1(1(1cl)/2)+s), 1 - (1 - cl)/2 + \Phi(\Phi^{-1}(1 - (1 - cl)/2) + s),

where:

s=2Φ1(1Bb=1BI(gj(θ^(b))gj(θ^))). s = 2\Phi^{-1}(\frac{1}{B}\sum\limits_{b = 1}^{B}I(g_{j}(\hat{\theta}^{(b)})\leq g_{j}(\hat{\theta}))).

Trimming

If se_type = "bootstrap" and trim > 0 then trimming is used as described in Hansen (2022) to estimate σ^j\hat{\sigma}_{j} and As.Cov^(g(θ^))\widehat{As.Cov}(g(\hat{\theta})). The algorithm is as follows. First, nullify 100trim percent of g(θ^(b))g(\hat{\theta}^{(b)}) with the greatest values of the L2-norm of qbq_{b} (defined above). Then use this 'trimmed' sample to estimate the standard error and the asymptotic covariance matrix.

Examples

# ------------------------------- # CPS data example # ------------------------------- # Set seed for reproducibility set.seed(123) # Upload the data data(cps) # Estimate the employment model model <- msel(work ~ age + I(age ^ 2) + bachelor + master, data = cps) summary(model) # Use Wald test to test the hypothesis that age has no # effect on the conditional probability of employment: # H0: coef age = 0 # coef age ^ 2 = 0 age_fn <- function(object) { lwage_coef <- coef(object, type = "coef")[[1]] val <- c(lwage_coef["age"], lwage_coef["I(age^2)"]) return(val) } age_test <- test_msel(object = model, fn = age_fn, test = "wald") summary(age_test) # Use t-test to test for each individual the hypothesis: # P(work = 1 | x) = 0.8 prob_fn <- function(object) { prob <- predict(object, group = 1, type = "prob") val <- prob - 0.8 return(val) } prob_test <- test_msel(object = model, fn = prob_fn, test = "t") summary(prob_test) # ------------------------------- # Simulated data example # Model with continuous outcome # and ordinal selection # ------------------------------- # --- # Step 1 # Simulation of the data # --- # Set seed for reproducibility set.seed(123) # Load required package library("mnorm") # The number of observations n <- 10000 # Regressors (covariates) s1 <- runif(n = n, min = -1, max = 1) s2 <- runif(n = n, min = -1, max = 1) s3 <- runif(n = n, min = -1, max = 1) s4 <- runif(n = n, min = -1, max = 1) # Random errors sigma <- matrix(c(1, 0.4, 0.45, 0.7, 0.4, 1, 0.54, 0.8, 0.45, 0.54, 0.81, 0.81, 0.7, 0.8, 0.81, 1), nrow = 4) errors <- mnorm::rmnorm(n = n, mean = c(0, 0, 0, 0), sigma = sigma) u1 <- errors[, 1] u2 <- errors[, 2] eps0 <- errors[, 3] eps1 <- errors[, 4] # Coefficients gamma1 <- c(-1, 2) gamma2 <- c(1, 1) gamma1_het <- c(0.5, -1) beta0 <- c(1, -1, 1, -1.2) beta1 <- c(2, -1.5, 0.5, 1.2) # Linear index of the ordinal equations # mean part li1 <- gamma1[1] * s1 + gamma1[2] * s2 li2 <- gamma2[1] * s1 + gamma2[2] * s3 # variance part li1_het <- gamma1_het[1] * s2 + gamma1_het[2] * s3 # Linear index of the continuous equation # regime 0 li_y0 <- beta0[1] + beta0[2] * s1 + beta0[3] * s3 + beta0[4] * s4 # regime 1 li_y1 <- beta1[1] + beta1[2] * s1 + beta1[3] * s3 + beta1[4] * s4 # Latent variables z1_star <- li1 + u1 * exp(li1_het) z2_star <- li2 + u2 y0_star <- li_y0 + eps0 y1_star <- li_y1 + eps1 # Cuts cuts1 <- c(-1) cuts2 <- c(0, 1) # Observable ordinal outcome # first z1 <- rep(0, n) z1[z1_star > cuts1[1]] <- 1 # second z2 <- rep(0, n) z2[(z2_star > cuts2[1]) & (z2_star <= cuts2[2])] <- 1 z2[z2_star > cuts2[2]] <- 2 z2[z1 == 0] <- NA # Observable continuous outcome y <- rep(NA, n) y[which(z2 == 0)] <- y0_star[which(z2 == 0)] y[which(z2 != 0)] <- y1_star[which(z2 != 0)] y[which(z1 == 0)] <- NA # Data data <- data.frame(s1 = s1, s2 = s2, s3 = s3, s4 = s4, z1 = z1, z2 = z2, y = y) # --- # Step 2 # Estimation of the parameters # --- # Assign the groups groups <- matrix(c(1, 2, 1, 1, 1, 0, 0, -1), byrow = TRUE, ncol = 2) groups2 <- matrix(c(1, 1, 0, -1), ncol = 1) # Estimate the model model <- msel(list(z1 ~ s1 + s2 | s2 + s3, z2 ~ s1 + s3), list(y ~ s1 + s3 + s4), groups = groups, groups2 = groups2, data = data) # --- # Step 3 # Hypotheses testing # --- # Use t-test to test for each observation the hypothesis # H0: P(z1 = 0, z2 = 2 | Xi) = 0 prob02_fn <- function(object) { val <- predict(object, group = c(1, 0)) return(val) } prob02_test <- test_msel(object = model, fn = prob02_fn, test = "t") summary(prob02_test) # Use t-test to test the hypothesis # H0: E(y1|z1=0, z2=2) - E(y0|z1=0, z2=2) ATE_fn <- function(object) { val1 <- predict(object, group = c(0, 2), group2 = 1) val0 <- predict(object, group = c(0, 2), group2 = 0) val <- mean(val1 - val0) return(val) } ATE_test <- test_msel(object = model, fn = ATE_fn) summary(ATE_test) # Use Wald to test the hypothesis # H0: beta1 = beta0 coef_fn <- function(object) { coef1 <- coef(object, regime = 1, type = "coef2") coef0 <- coef(object, regime = 0, type = "coef2") coef_difference <- coef1 - coef0 return(coef_difference) } coef_test <- test_msel(object = model, fn = coef_fn, test = "wald") summary(coef_test) # Use t-test to test for each 'k' the hypothesis # H0: beta1k = beta0k coef_test2 <- test_msel(object = model, fn = coef_fn, test = "t") summary(coef_test2) # Use Wald test to test the hypothesis # H0: beta11 + beta12 - 0.5 = 0 # beta11 * beta13 - beta03 = 0 test_fn <- function(object) { coef1 <- coef(object, regime = 1, type = "coef2") coef0 <- coef(object, regime = 0, type = "coef2") val <- c(coef1[1] + coef1[2] - 0.5, coef1[1] * coef1[3] - coef0[3]) return(val) } # classic Wald test wald1 <- test_msel(object = model, fn = test_fn, test = "wald", method = "classic") summary(wald1) # score bootstrap Wald test wald2 <- test_msel(object = model, fn = test_fn, test = "wald", method = "score") summary(wald2) # Replicate the latter test with the 2-step estimator model2 <- msel(list(z1 ~ s1 + s2 | s2 + s3, z2 ~ s1 + s3), list(y ~ s1 + s3 + s4), groups = groups, groups2 = groups2, data = data, estimator = "2step") # classic Wald test wald1_2step <- test_msel(object = model2, fn = test_fn, test = "wald", method = "classic") summary(wald1_2step) # score bootstrap Wald test wald2_2step <- test_msel(object = model2, fn = test_fn, test = "wald", method = "score") summary(wald2_2step)

References

B. Efron (1982). The Jackknife, the Bootstrap, and Other Resampling Plans. Society for Industrial and Applied Mathematics.

B. Hansen (2022). Econometrics. Princeton University Press.

P. Kline, A. Santos (2012). A Score Based Approach to Wild Bootstrap Inference. Journal of Econometric Methods, vol. 67, no. 1, pages 23-41.

  • Maintainer: Bogdan Potanin
  • License: GPL (>= 2)
  • Last published: 2024-09-26

Useful links