Nothing
## ----setup, include=FALSE-----------------------------------------------------
knitr::opts_chunk$set(
collapse = TRUE,
comment = "#>",
message = FALSE,
warning = FALSE,
fig.width = 6,
fig.height = 3.5,
fig.align = "center"
)
## ----confidential-data--------------------------------------------------------
library(dapper)
library(ggplot2)
cells <- data.frame(
sex = c(1, 1, 0, 0),
status = c(1, 0, 1, 0)
)
counts <- c(1198, 1493, 557, 1278)
cnf_df <- cells[rep(seq_len(nrow(cells)), times = counts), ]
set.seed(1)
n <- 400
ix <- sample(seq_len(nrow(cnf_df)), n, replace = FALSE)
cnf_df <- cnf_df[ix, ]
## ----randomized-release-------------------------------------------------------
ri <- as.logical(rbinom(2 * n, 1, 1/2))
ra <- rbinom(sum(ri), 1, 1/2)
sdp <- c(as.matrix(cnf_df))
sdp[ri] <- ra
prv_df <- data.frame(sex = sdp[seq_len(n)], status = sdp[n + seq_len(n)])
## ----admission-tables---------------------------------------------------------
admission_table <- function(x) {
table(
Sex = factor(x$sex, levels = c(0, 1), labels = c("Female", "Male")),
Status = factor(x$status, levels = c(1, 0),
labels = c("Admitted", "Rejected"))
)
}
knitr::kable(admission_table(cnf_df), caption = "Confidential counts")
knitr::kable(admission_table(prv_df), caption = "Privatized counts")
## ----latent-component---------------------------------------------------------
latent_f <- function(theta) {
tl <- list(c(1, 1), c(1, 0), c(0, 1), c(0, 0))
rs <- sample(tl, n, replace = TRUE, prob = theta)
do.call(rbind, rs)
}
## ----posterior-component------------------------------------------------------
posterior_f <- function(dmat, theta) {
sex <- dmat[, 1]
status <- dmat[, 2]
x <- c(
sum(sex & status),
sum(sex & !status),
sum(!sex & status),
sum(!sex & !status)
)
t1 <- rgamma(4, shape = x + 1, rate = 1)
t1 / sum(t1)
}
## ----statistic-component------------------------------------------------------
statistic_f <- function(xi, sdp, i) {
n <- length(sdp) %/% 2
sum(xi == sdp[c(i, n + i)])
}
## ----mechanism-component------------------------------------------------------
mechanism_f <- function(sdp, sx) {
sx * log(3/4) + (length(sdp) - sx) * log(1/4)
}
## ----sample-posterior---------------------------------------------------------
dmod <- new_privacy(
posterior_f = posterior_f,
latent_f = latent_f,
mechanism_f = mechanism_f,
statistic_f = statistic_f,
npar = 4,
varnames = c("pi_11", "pi_10", "pi_01", "pi_00")
)
dp_out <- dapper_sample(
dmod,
sdp = sdp,
seed = 123,
niter = 6000,
warmup = 1000,
chains = 4,
init_par = rep(0.25, 4)
)
## ----parameter-summary--------------------------------------------------------
summary(dp_out)
## ----trace-plot, fig.height=4, fig.cap="Trace plots for the four cell probabilities. Colors distinguish the four chains.", fig.alt="Four panels show the sampled cell probabilities over iterations, with a different color for each chain."----
plot(dp_out) +
scale_color_manual(values = c("#00468B", "#ED0000", "#42B540", "#925E9F")) +
theme_bw(base_size = 11)
## ----odds-ratio---------------------------------------------------------------
odds_ratio_draws <- posterior::mutate_variables(
dp_out$chain,
odds_ratio = (pi_11 * pi_00) / (pi_10 * pi_01)
)
odds_ratio_draws <- posterior::subset_draws(
odds_ratio_draws, variable = "odds_ratio"
)
posterior::summarise_draws(odds_ratio_draws)
## ----odds-ratio-density, fig.height=2.8, fig.cap="Privacy-aware posterior distribution of the odds ratio, displayed from 0 to 10.", fig.alt="Posterior density of the odds ratio, with a shaded central 80 percent interval and a dashed vertical reference line at one."----
bayesplot::mcmc_areas(
odds_ratio_draws,
prob = 0.8,
prob_outer = 0.95,
point_est = "none"
) +
geom_vline(xintercept = 1, linetype = "dashed", linewidth = 0.5) +
coord_cartesian(xlim = c(0, 10)) +
labs(x = "Odds ratio", y = NULL) +
theme_bw(base_size = 11) +
theme(axis.text.y = element_blank(), axis.ticks.y = element_blank())
## ----comparison-draws---------------------------------------------------------
set.seed(1)
confidential_data <- as.matrix(cnf_df)
cps <- t(replicate(20000, posterior_f(confidential_data, NULL)))
odds_ratio_conf <- (cps[, 1] * cps[, 4]) / (cps[, 2] * cps[, 3])
set.seed(1)
noisy_data <- matrix(sdp, ncol = 2)
cps <- t(replicate(20000, posterior_f(noisy_data, NULL)))
odds_ratio_noisy <- (cps[, 1] * cps[, 4]) / (cps[, 2] * cps[, 3])
odds_ratio_private <- posterior::extract_variable(
odds_ratio_draws, "odds_ratio"
)
## ----comparison-densities-----------------------------------------------------
posterior_density <- function(draws, data, analysis) {
estimate <- density(draws, from = 0, to = 8)
data.frame(odds_ratio = estimate$x, density = estimate$y,
data = data, analysis = analysis)
}
comparison <- rbind(
posterior_density(odds_ratio_conf, "Confidential", "Privacy-aware"),
posterior_density(odds_ratio_private, "Privatized", "Privacy-aware"),
posterior_density(odds_ratio_conf, "Confidential", "Naïve"),
posterior_density(odds_ratio_noisy, "Privatized", "Naïve")
)
comparison$analysis <- factor(comparison$analysis,
levels = c("Privacy-aware", "Naïve"))
## ----posterior-comparison, fig.cap="Odds-ratio posteriors for confidential data (blue) and privatized data (red). The left panel accounts for randomized response; the right panel ignores it.", fig.alt="Two density panels compare confidential and privatized analyses. The privacy-aware posterior is wider, while the naïve posterior is concentrated closer to one."----
data_colors <- c(Confidential = "#00468B", Privatized = "#ED0000")
ggplot(comparison, aes(x = odds_ratio, y = density, fill = data, color = data)) +
geom_area(position = "identity", alpha = 0.2, color = NA) +
geom_line(linewidth = 0.6) +
facet_wrap(~ analysis) +
coord_cartesian(xlim = c(0, 8)) +
scale_fill_manual(name = "Data", values = data_colors) +
scale_color_manual(name = "Data", values = data_colors) +
labs(x = "Odds ratio", y = "Density") +
theme_bw(base_size = 11) +
theme(legend.position = "bottom")
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.