Nothing
options(mc.cores = 1)
test_that("Test loo_subsampling and loo_approx with radon data", {
skip_on_cran() # avoid going over time limit for tests
load(test_path("data-for-tests/test_radon_laplace_loo.rda"))
# Rename to spot variable leaking errors
llfun_test <- llfun
log_p_test <- log_p
log_g_test <- log_q
draws_test <- draws
data_test <- data
rm(llfun, log_p, log_q, draws, data)
set.seed(134)
expect_silent(
full_loo <- loo(
llfun_test,
draws = draws_test,
data = data_test,
r_eff = rep(1, nrow(data_test))
)
)
expect_s3_class(full_loo, "psis_loo")
set.seed(134)
expect_silent(
loo_ss <- loo_subsample(
x = llfun_test,
draws = draws_test,
data = data_test,
observations = 200,
loo_approximation = "plpd",
r_eff = rep(1, nrow(data_test))
)
)
expect_s3_class(loo_ss, "psis_loo_ss")
set.seed(134)
expect_silent(
loo_ap_ss <- loo_subsample(
x = llfun_test,
draws = draws_test,
data = data_test,
log_p = log_p_test,
log_g = log_g_test,
observations = 200,
loo_approximation = "plpd",
r_eff = rep(1, nrow(data_test))
)
)
expect_s3_class(loo_ap_ss, "psis_loo_ss")
expect_s3_class(loo_ap_ss, "psis_loo_ap")
expect_silent(
loo_ap_ss_full <- loo_subsample(
x = llfun_test,
log_p = log_p_test,
log_g = log_g_test,
draws = draws_test,
data = data_test,
observations = NULL,
loo_approximation = "plpd",
r_eff = rep(1, nrow(data_test))
)
)
expect_failure(expect_s3_class(loo_ap_ss_full, "psis_loo_ss"))
expect_s3_class(loo_ap_ss_full, "psis_loo_ap")
# Expect similar results
z <- 2
expect_lte(
loo_ss$estimates["elpd_loo", "Estimate"] -
z * loo_ss$estimates["elpd_loo", "subsampling SE"],
full_loo$estimates["elpd_loo", "Estimate"]
)
expect_gte(
loo_ss$estimates["elpd_loo", "Estimate"] +
z * loo_ss$estimates["elpd_loo", "subsampling SE"],
full_loo$estimates["elpd_loo", "Estimate"]
)
expect_lte(
loo_ss$estimates["p_loo", "Estimate"] -
z * loo_ss$estimates["p_loo", "subsampling SE"],
full_loo$estimates["p_loo", "Estimate"]
)
expect_gte(
loo_ss$estimates["p_loo", "Estimate"] +
z * loo_ss$estimates["p_loo", "subsampling SE"],
full_loo$estimates["p_loo", "Estimate"]
)
expect_lte(
loo_ss$estimates["looic", "Estimate"] -
z * loo_ss$estimates["looic", "subsampling SE"],
full_loo$estimates["looic", "Estimate"]
)
expect_gte(
loo_ss$estimates["looic", "Estimate"] +
z * loo_ss$estimates["looic", "subsampling SE"],
full_loo$estimates["looic", "Estimate"]
)
expect_failure(expect_equal(
full_loo$estimates["elpd_loo", "Estimate"],
loo_ss$estimates["elpd_loo", "Estimate"],
tolerance = 0.00000001
))
expect_failure(expect_equal(
full_loo$estimates["p_loo", "Estimate"],
loo_ss$estimates["p_loo", "Estimate"],
tolerance = 0.00000001
))
expect_failure(expect_equal(
full_loo$estimates["looic", "Estimate"],
loo_ss$estimates["looic", "Estimate"],
tolerance = 0.00000001
))
z <- 2
expect_lte(
loo_ap_ss$estimates["elpd_loo", "Estimate"] -
z * loo_ap_ss$estimates["elpd_loo", "subsampling SE"],
loo_ap_ss_full$estimates["elpd_loo", "Estimate"]
)
expect_gte(
loo_ap_ss$estimates["elpd_loo", "Estimate"] +
z * loo_ap_ss$estimates["elpd_loo", "subsampling SE"],
loo_ap_ss_full$estimates["elpd_loo", "Estimate"]
)
expect_lte(
loo_ap_ss$estimates["p_loo", "Estimate"] -
z * loo_ap_ss$estimates["p_loo", "subsampling SE"],
loo_ap_ss_full$estimates["p_loo", "Estimate"]
)
expect_gte(
loo_ap_ss$estimates["p_loo", "Estimate"] +
z * loo_ap_ss$estimates["p_loo", "subsampling SE"],
loo_ap_ss_full$estimates["p_loo", "Estimate"]
)
expect_lte(
loo_ap_ss$estimates["looic", "Estimate"] -
z * loo_ap_ss$estimates["looic", "subsampling SE"],
loo_ap_ss_full$estimates["looic", "Estimate"]
)
expect_gte(
loo_ap_ss$estimates["looic", "Estimate"] +
z * loo_ap_ss$estimates["looic", "subsampling SE"],
loo_ap_ss_full$estimates["looic", "Estimate"]
)
expect_failure(expect_equal(
loo_ap_ss_full$estimates["elpd_loo", "Estimate"],
loo_ap_ss$estimates["elpd_loo", "Estimate"],
tolerance = 0.00000001
))
expect_failure(expect_equal(
loo_ap_ss_full$estimates["p_loo", "Estimate"],
loo_ap_ss$estimates["p_loo", "Estimate"],
tolerance = 0.00000001
))
expect_failure(expect_equal(
loo_ap_ss_full$estimates["looic", "Estimate"],
loo_ap_ss$estimates["looic", "Estimate"],
tolerance = 0.00000001
))
# Correct printout
expect_failure(expect_output(
print(full_loo),
"Posterior approximation correction used\\."
))
expect_failure(expect_output(
print(full_loo),
"subsampled log-likelihood\nvalues"
))
expect_failure(expect_output(
print(loo_ss),
"Posterior approximation correction used\\."
))
expect_output(print(loo_ss), "subsampled log-likelihood\nvalues")
expect_output(print(loo_ap_ss), "Posterior approximation correction used\\.")
expect_output(print(loo_ap_ss), "subsampled log-likelihood\nvalues")
expect_output(
print(loo_ap_ss_full),
"Posterior approximation correction used\\."
)
expect_failure(expect_output(
print(loo_ap_ss_full),
"subsampled log-likelihood\nvalues"
))
# Test conversion of objects
expect_silent(loo_ap_full <- loo:::as.psis_loo.psis_loo(loo_ap_ss_full))
expect_s3_class(loo_ap_full, "psis_loo_ap")
expect_silent(loo_ap_full_ss <- loo:::as.psis_loo_ss.psis_loo(loo_ap_full))
expect_s3_class(loo_ap_full_ss, "psis_loo_ss")
expect_s3_class(loo_ap_full_ss, "psis_loo_ap")
expect_silent(loo_ap_full2 <- loo:::as.psis_loo.psis_loo_ss(loo_ap_full_ss))
expect_s3_class(loo_ap_full2, "psis_loo_ap")
expect_failure(expect_s3_class(loo_ap_full2, "psis_loo_ss"))
expect_equal(loo_ap_full2, loo_ap_full)
# Test update
set.seed(4712)
expect_silent(
loo_ss2 <- update(
loo_ss,
draws = draws_test,
data = data_test,
observations = 1000,
r_eff = rep(1, nrow(data_test))
)
)
expect_gt(dim(loo_ss2)[2], dim(loo_ss)[2])
expect_gt(dim(loo_ss2$pointwise)[1], dim(loo_ss$pointwise)[1])
expect_equal(nobs(loo_ss), 200)
expect_equal(nobs(loo_ss2), 1000)
for (i in 1:nrow(loo_ss2$estimates)) {
expect_lt(
loo_ss2$estimates[i, "subsampling SE"],
loo_ss$estimates[i, "subsampling SE"]
)
}
set.seed(4712)
expect_silent(
loo_ap_ss2 <- update(
object = loo_ap_ss,
draws = draws_test,
data = data_test,
observations = 2000
)
)
expect_gt(dim(loo_ap_ss2)[2], dim(loo_ap_ss)[2])
expect_gt(dim(loo_ap_ss2$pointwise)[1], dim(loo_ap_ss$pointwise)[1])
expect_equal(nobs(loo_ap_ss), 200)
expect_equal(nobs(loo_ap_ss2), 2000)
for (i in 1:nrow(loo_ap_ss2$estimates)) {
expect_lt(
loo_ap_ss2$estimates[i, "subsampling SE"],
loo_ap_ss$estimates[i, "subsampling SE"]
)
}
expect_equal(round(full_loo$estimates), round(loo_ap_ss_full$estimates))
expect_failure(expect_equal(full_loo$estimates, loo_ap_ss_full$estimates))
expect_equal(dim(full_loo), dim(loo_ap_ss_full))
expect_s3_class(loo_ap_ss_full, "psis_loo_ap")
})
test_that("Test the vignette", {
skip_on_cran()
# NOTE
# If any of these test fails, the vignette probably needs to be updated
if (FALSE) {
# Generate vignette test case
library("rstan")
stan_code <- "
data {
int<lower=0> N; // number of data points
int<lower=0> P; // number of predictors (including intercept)
matrix[N,P] X; // predictors (including 1s for intercept)
int<lower=0,upper=1> y[N]; // binary outcome
}
parameters {
vector[P] beta;
}
model {
beta ~ normal(0, 1);
y ~ bernoulli_logit(X * beta);
}
"
# logistic <- function(x) {1 / (1 + exp(-x))}
# logit <- function(x) {log(x) - log(1-x)}
llfun_logistic <- function(data_i, draws) {
x_i <- as.matrix(data_i[,
which(grepl(colnames(data_i), pattern = "X")),
drop = FALSE
])
y_pred <- draws %*% t(x_i)
dbinom(x = data_i$y, size = 1, prob = 1 / (1 + exp(-y_pred)), log = TRUE)
}
# Prepare data
url <- "http://stat.columbia.edu/~gelman/arm/examples/arsenic/wells.dat"
wells <- read.table(url)
wells$dist100 <- with(wells, dist / 100)
X <- model.matrix(~ dist100 + arsenic, wells)
standata <- list(y = wells$switch, X = X, N = nrow(X), P = ncol(X))
# Fit model
set.seed(4711)
fit_1 <- stan(model_code = stan_code, data = standata, seed = 4711)
print(fit_1, pars = "beta")
parameter_draws <- extract(fit_1)$beta
stan_df <- as.data.frame(standata)
loo_i(1, llfun_logistic, data = stan_df, draws = parameter_draws)
sm <- stan_model(model_code = stan_code)
set.seed(4711)
fit_laplace <- optimizing(sm, data = standata, draws = 2000, seed = 42)
parameter_draws_laplace <- fit_laplace$theta_tilde
log_p <- fit_laplace$log_p # The log density of the posterior
log_g <- fit_laplace$log_g # The log density of the approximation
# For comparisons
standata$X[, "arsenic"] <- log(standata$X[, "arsenic"])
stan_df2 <- as.data.frame(standata)
set.seed(4711)
fit_2 <- stan(fit = fit_1, data = standata, seed = 4711)
parameter_draws_2 <- extract(fit_2)$beta
save(
llfun_logistic,
stan_df,
stan_df2,
parameter_draws,
parameter_draws_laplace,
parameter_draws_2,
log_p,
log_g,
file = test_path("data-for-tests/loo_subsample_vignette.rda"),
compression_level = 9
)
} else {
load(test_path("data-for-tests/loo_subsample_vignette.rda"))
}
set.seed(4711)
expect_no_warning(
looss_1 <- loo_subsample(
llfun_logistic,
draws = parameter_draws,
data = stan_df,
observations = 100
)
)
expect_snapshot(print(looss_1))
expect_s3_class(looss_1, c("psis_loo_ss", "psis_loo", "loo"))
set.seed(4711)
expect_no_warning(
looss_1b <- update(
looss_1,
draws = parameter_draws,
data = stan_df,
observations = 200
)
)
expect_snapshot(print(looss_1b))
expect_s3_class(looss_1b, c("psis_loo_ss", "psis_loo", "loo"))
set.seed(4711)
expect_no_warning(
looss_2 <- loo_subsample(
x = llfun_logistic,
draws = parameter_draws,
data = stan_df,
observations = 100,
estimator = "hh_pps",
loo_approximation = "lpd",
loo_approximation_draws = 100
)
)
expect_output(
print(looss_2),
"Computed from 4000 by 100 subsampled log-likelihood"
)
expect_output(print(looss_2), "values from 3020 total observations.")
expect_output(
print(looss_2),
"MCSE and ESS estimates assume independent draws"
)
# Currently failing
# expect_output(print(looss_2), "elpd_loo -1968.9 15.4 0.5")
# expect_output(print(looss_2), "p_loo 3.5 0.2 0.5")
expect_s3_class(looss_2, c("psis_loo_ss", "psis_loo", "loo"))
set.seed(4711)
expect_no_warning(
aploo_1 <- loo_approximate_posterior(
llfun_logistic,
draws = parameter_draws_laplace,
data = stan_df,
log_p = log_p,
log_g = log_g
)
)
expect_snapshot(print(aploo_1))
expect_equal(length(pareto_k_ids(aploo_1, threshold = 0.5)), 31)
expect_s3_class(aploo_1, c("psis_loo_ap", "psis_loo", "loo"))
set.seed(4711)
expect_no_warning(
looapss_1 <- loo_subsample(
llfun_logistic,
draws = parameter_draws_laplace,
data = stan_df,
log_p = log_p,
log_g = log_g,
observations = 100
)
)
expect_snapshot(print(looapss_1))
expect_equal(length(pareto_k_ids(looapss_1, threshold = 0.5)), 3)
# Loo compare
set.seed(4711)
expect_no_warning(
looss_1 <- loo_subsample(
llfun_logistic,
draws = parameter_draws,
data = stan_df,
observations = 100
)
)
set.seed(4712)
expect_no_warning(
looss_2 <- loo_subsample(
x = llfun_logistic,
draws = parameter_draws_2,
data = stan_df2,
observations = 100
)
)
expect_snapshot(print(looss_2))
expect_warning(
comp <- loo_compare(looss_1, looss_2),
"Different subsamples in 'model2' and 'model1'. Naive diff SE is used."
)
expect_snapshot(print(comp))
set.seed(4712)
expect_no_warning(
looss_2_m <- loo_subsample(
x = llfun_logistic,
draws = parameter_draws_2,
data = stan_df2,
observations = looss_1
)
)
expect_message(
looss_2_m <- suppressWarnings(loo_subsample(
x = llfun_logistic,
draws = parameter_draws_2,
data = stan_df2,
observations = obs_idx(looss_1)
)),
"Simple random sampling with replacement assumed."
)
expect_silent(comp <- loo_compare(looss_1, looss_2_m))
expect_snapshot(print(comp))
set.seed(4712)
expect_no_warning(
looss_1 <- update(
looss_1,
draws = parameter_draws,
data = stan_df,
observations = 200
)
)
expect_no_warning(
looss_2_m <- update(
looss_2_m,
draws = parameter_draws_2,
data = stan_df2,
observations = looss_1
)
)
expect_silent(comp2 <- loo_compare(looss_1, looss_2_m))
expect_snapshot(print(comp2))
expect_no_warning(
looss_2_full <- loo(
x = llfun_logistic,
draws = parameter_draws_2,
data = stan_df2
)
)
expect_message(
comp3 <- loo_compare(x = list(looss_1, looss_2_full)),
"Estimated elpd_diff using observations included in loo calculations for all models."
)
expect_snapshot(print(comp3))
})
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.