
Logistic Regression Inference for Incidence Responses
Source:R/inference_incidence_logit.R
InferenceIncidLogRegr.RdFits a logistic regression model for binary (incidence) responses:
\(\mathrm{logit}(P(Y_i = 1)) = \beta_0 + \beta_T W_i + X_i^\top \gamma\),
where \(W_i\) is the treatment indicator and \(X_i\) are optional
recorded covariates, by maximum likelihood
(fast_logistic_regression_cpp/
fast_logistic_regression_weighted_cpp). \(\hat\beta_T\) is
a log-odds-ratio: \(\exp(\hat\beta_T)\) is the estimated treatment odds
ratio. likelihood_tier = "full": Wald, score, gradient, and
likelihood-ratio tests are all available (via the shared
StandardModelCache model-caching contract), plus
parametric-likelihood-bootstrap calibration of the likelihood-ratio test.
A fit whose coefficients exceed
max_abs_reasonable_coef in magnitude (a proxy for near-perfect
separation) is cached as nonestimable rather than returned. Validity
requires the usual logistic-regression assumptions: correctly specified
linear predictor on the logit scale, independence across subjects
conditional on covariates, and no perfect/quasi-complete separation.
Estimand. Composes
MarginalEstimand
(set_estimand()/get_estimand()/get_supported_estimands()).
Under the default estimand = "conditional", \(\hat\beta_T\) is the
log-odds-ratio above. Under estimand = "marginal_mean_diff", the
reported quantity is instead the g-computation marginal risk difference
\(\frac{1}{n}\sum_i \{\mathrm{plogis}(\hat\beta_0 + \hat\beta_T + X_i^\top
\hat\gamma) - \mathrm{plogis}(\hat\beta_0 + X_i^\top \hat\gamma)\}\) — every
subject's covariates plugged in once under treatment and once under
control, averaged over the empirical covariate distribution. Under
estimand = "marginal_ratio", the log of the corresponding marginal
risk ratio. Because there is no latent submodel for this family (unlike
e.g. InferencePropZeroOneInflatedBetaRegr's
zero/one-inflation mixture), the marginal mean function is exactly the
model's own fitted mean; no separate standardization step beyond the
g-computation average is needed. Standard errors under a marginal estimand
use the delta method against the model's coefficient covariance (degrees
of freedom Inf); testing_type is restricted to "wald"
whenever the estimand is non-conditional (set_testing_type() errors
otherwise). The underlying model fit is identical regardless of estimand —
switching estimand is a pure post-fit transform, never a refit.
References
McCullagh, P., and Nelder, J. A. (1989). Generalized Linear Models (2nd ed.). Chapman and Hall/CRC, for the logistic regression model and its maximum-likelihood theory.
See also
Comparable Python API: statsmodels GLM. See also: Logistic regression (Wikipedia).
Super class
Inference -> InferenceIncidLogRegr
Methods
+ inherited public methods from Inference
Inference$capabilities()Inference$compute_exact_confidence_interval()Inference$compute_exact_two_sided_pval_for_treatment_effect()Inference$duplicate()Inference$get_analysis_data()Inference$get_covariates()Inference$get_design_object()Inference$get_model_formula()Inference$get_nonestimable_reason()Inference$get_nonestimable_stage()Inference$get_optimization_alg()Inference$get_response()Inference$get_response_type()Inference$get_treatment()Inference$initialize()Inference$is_nonestimable()Inference$set_optimization_alg()Inference$set_seed()Inference$supports()
InferenceIncidLogRegr$compute_estimate()
Fits the logistic regression model by maximum
likelihood. Under the default estimand = "conditional",
returns \(\hat\beta_T\), the treatment log-odds-ratio. Under
estimand = "marginal_mean_diff"/"marginal_ratio"
(set via set_estimand()), returns the g-computation
marginal risk difference/log-risk-ratio instead — see the
class-level @details for the formula. The underlying
model fit is identical either way (a pure post-fit transform of
the same cached fit, no refit).
InferenceIncidLogRegr$compute_asymp_confidence_interval()
Wald confidence interval, dispatched by
testing_type for the conditional estimand (score/gradient/
likelihood-ratio/Bartlett available); under a marginal estimand
testing_type is always "wald" (the only value
set_estimand() permits there), so this always resolves to
the delta-method interval. Calls self$compute_estimate()
first (not private$shared() directly) so the
estimand-aware cache is always current regardless of call order.
InferenceIncidLogRegr$compute_asymp_two_sided_pval()
Wald two-sided p-value, dispatched by
testing_type exactly as
compute_asymp_confidence_interval(); see that method's
description for the marginal-estimand always-Wald note.
Examples
# \donttest{
seq_des = DesignSeqOneByOneBernoulli$new(n = 10, response_type = 'incidence')
for (i in 1:10) {
seq_des$add_one_subject_to_experiment_and_assign(data.frame(x1 = rnorm(1)))
}
seq_des$add_all_subject_responses(rbinom(10, 1, 0.5))
inf = InferenceIncidLogRegr$new(seq_des)
inf$compute_estimate()
#> [1] -0.2267701
# }
# \donttest{
inf$set_seed(1)
inf$compute_lik_ratio_bootstrap_two_sided_pval(delta = 0, B = 9, show_progress = FALSE)
#> [1] 1
# }