Skip to content

RPVote/eiCalibrate

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

eiCalibrate

Empirical Bayes calibration for RxC ecological inference. Tune the Dirichlet prior in eiPack::ei.MD.bayes() against known benchmarks from a calibration election, then apply the calibrated prior to your target election.

Includes unified wrappers for:

  • eiPack RxC Bayesian (ei.MD.bayes)
  • eiCompare iterative 2x2 (ei_iter)
  • Goodman's ecological regression

Why

The default Dirichlet prior in ei.MD.bayes() (lambda1 = 4, lambda2 = 2) can over-shrink estimates toward the pooled mean when precinct-level data is limited or homogeneous, producing apparently non-polarized results even when voting is in fact polarized. Weakening the prior reduces shrinkage but, on weakly identified data, also increases variance. The principled fix is to calibrate the prior strength against ground truth from a separate benchmark election, then apply that setting to your target election.

Install

From GitHub:

# install.packages("devtools")
devtools::install_github("lorenc5/eiCalibrate")

Or from a local copy of the source tree:

devtools::install("path/to/eiCalibrate")

Dependencies you need installed separately:

install.packages(c("eiPack", "eiCompare", "coda"))

Quick start

library(eiCalibrate)

# 1. Calibration election with known truth (e.g. from exit polls)
calib_truth <- matrix(c(0.80, 0.20,
                        0.15, 0.85),
                      nrow = 2, byrow = TRUE,
                      dimnames = list(c("white", "black"),
                                      c("cand_A", "cand_B")))

calib_data <- simulate_election(n_precincts = 40,
                                true_support = calib_truth,
                                seed = 42)

# 2. Sweep prior strengths against the benchmark
#    1D calibration (tied lambda1 = lambda2):
calib_res <- calibrate_rxc(calib_data, calib_truth,
                           lambda_grid = c(0.1, 0.25, 0.5, 1, 2, 4))
calib_res$summary
calib_res$best_lambda1
calib_res$best_lambda2

#    2D joint calibration (independent lambda1, lambda2):
# calib_res <- calibrate_rxc(calib_data, calib_truth,
#                            lambda1_grid = c(0.1, 0.25, 0.5, 1, 2, 4),
#                            lambda2_grid = c(0.25, 0.5, 1, 2),
#                            n_reps = 3)

# 3. Apply the calibrated prior to your target election
target_fit <- fit_ei(target_data, method = "rxc",
                     lambda1 = calib_res$best_lambda1,
                     lambda2 = calib_res$best_lambda2)

# 4. Compare to default RxC, ei_iter, and Goodman ER as a robustness check
compare_methods(target_data,
                calibrated_lambda1 = calib_res$best_lambda1,
                calibrated_lambda2 = calib_res$best_lambda2)

See vignette("eiCalibrate-introduction") for the full walkthrough.

Methodological caveats

This package implements a tool; it does not replace methodological judgment.

  • Calibrate on a different election than the target. Tuning the prior to ground truth from the same election you intend to report is circular and not defensible.
  • The calibration is only as good as the benchmark. Exit polls, validated voter files, and homogeneous-precinct analyses are reasonable benchmarks; cherry-picked subsets are not.
  • Calibrated prior settings transfer best when elections are similar in time, geography, office, and political context. Crossing a 2020 federal race with a 2024 municipal race is risky.
  • Report the calibration procedure transparently in any expert report or paper. "We selected lambda = X to minimize RMSE against [benchmark]" is defensible; hiding the step is not.
  • Always report alongside ei_iter and the method of bounds. If they disagree, the data don't support a strong conclusion either way.
  • If calibration RMSE is still large at the best lambda, the underlying data don't identify the quantities you want and no prior tuning fixes that.

License

MIT

About

Empirical Bayes Calibration for Ecological Inference

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages