Title: | Unit Tests for MC Methods |
---|---|
Description: | Unit testing for Monte Carlo methods, particularly Markov Chain Monte Carlo (MCMC) methods, are implemented as extensions of the 'testthat' package. The MCMC methods check whether the MCMC chain has the correct invariant distribution. They do not check other properties of successful samplers such as whether the chain can reach all points, i.e. whether is recurrent. The tests require the ability to sample from the prior and to run steps of the MCMC chain. The methodology is described in Gandy and Scott (2020) <arXiv:2001.06465>. |
Authors: | Axel Gandy [aut, cre], James Scott [aut] |
Maintainer: | Axel Gandy <[email protected]> |
License: | GPL-3 |
Version: | 0.3.4 |
Built: | 2025-03-07 03:34:55 UTC |
Source: | https://bitbucket.org/agandy/mcunit |
Test if the success probability of a Bernoulli experiment lies within a desired 'bucket'. This used the sequential procedure described in Gandy et al. (2019).
expect_bernoulli(object, J, ok, epsilon = 0.001, ...)
expect_bernoulli(object, J, ok, epsilon = 0.001, ...)
object |
Function that performs one sampling step. Returns 0 or 1. |
J |
Buckets to use. A matrix with two rows, each column describes an interval bucket. Column names give names for the bucket(s). |
ok |
Name of bucket(s) that pass the Unit test. |
epsilon |
Error bound. |
... |
Further parameters to be passed on to 'mctest'. |
The first argument, invisibly, to allow chaining of expectations.
Gandy A, Hahn G, Ding D (2019). “Implementing Monte Carlo Tests with P-value Buckets.” Scandinavian Journal of Statistics. doi:10.1111/sjos.12434, Accepted for publication, 1703.09305, https://arxiv.org/abs/1703.09305.
J <- matrix(nrow=2,c(0,0.945, 0.94,0.96, 0.955,1)) colnames(J) <- c("low","ok","high") gen <- function() as.numeric(runif(1)<0.95) expect_bernoulli(gen,J=J,ok="ok")
J <- matrix(nrow=2,c(0,0.945, 0.94,0.96, 0.955,1)) colnames(J) <- c("low","ok","high") gen <- function() as.numeric(runif(1)<0.95) expect_bernoulli(gen,J=J,ok="ok")
Test if samples are behaving like an iid sample from a given distribution via the chisq test and a sequential approach. Only works for discrete distributions taking finitely many values.
expect_mc_iid_chisq(object, prob, control = NULL)
expect_mc_iid_chisq(object, prob, control = NULL)
object |
A function taking one argument - that generates n univariate iid samples. |
prob |
A vector of probabilities for finitely many consecutive integers from 0 onward. |
control |
a list controlling the algorithm
|
The first argument, invisibly, to allow chaining of expectations.
sampler <- function(n) rbinom(n,prob=0.6,size=5) expect_mc_iid_chisq(sampler, dbinom(0:5,prob=0.6,size=5)) testthat::expect_error(expect_mc_iid_chisq(sampler, dbinom(0:5,prob=0.63,size=5)))
sampler <- function(n) rbinom(n,prob=0.6,size=5) expect_mc_iid_chisq(sampler, dbinom(0:5,prob=0.6,size=5)) testthat::expect_error(expect_mc_iid_chisq(sampler, dbinom(0:5,prob=0.63,size=5)))
Test if samples are behaving like an iid sample from a given CDF via the KS test and a sequential approach. Only works for continuous CDFs. Will report a warning if values are discrete
expect_mc_iid_ks(object, cdf, control = NULL)
expect_mc_iid_ks(object, cdf, control = NULL)
object |
A function taking one argument - that generates n univariate iid samples. |
cdf |
A univariate cumulative distribution function, taking exactly one argument. |
control |
a list controlling the algorithm
|
The first argument, invisibly, to allow chaining of expectations.
sampler <- function(n) rnorm(n) expect_mc_iid_ks(sampler, pnorm)
sampler <- function(n) rnorm(n) expect_mc_iid_ks(sampler, pnorm)
Test if samples are coming from a specific mean. Not guaranteed to be exact, as it estimates the standard error from the sample.
expect_mc_iid_mean(object, mean, control = NULL)
expect_mc_iid_mean(object, mean, control = NULL)
object |
A function taking one argument - that generates n univariate iid samples. |
mean |
The expected mean of the samples returned from object. |
control |
a list controlling the algorithm
|
The first argument, invisibly, to allow chaining of expectations.
sampler <- function(n) rbinom(n,prob=0.6,size=5) expect_mc_iid_mean(sampler, mean=3) testthat::expect_error(expect_mc_iid_mean(sampler, mean=2))
sampler <- function(n) rbinom(n,prob=0.6,size=5) expect_mc_iid_mean(sampler, mean=3) testthat::expect_error(expect_mc_iid_mean(sampler, mean=2))
Requires as input a generic test that for a given sample size provides a vector of p-values. Aims to reject if these are not from the null. Guarantees a bound on the type I error rate.
expect_mc_test(object, control = NULL, npval = 1)
expect_mc_test(object, control = NULL, npval = 1)
object |
A function taking one argument n, which should be the sample size to use for the test. The function should return a named list with at least one element, "pvals", which is a vector of p-values. |
control |
a list controlling the algorithm
|
npval |
number of p-values returned by the test. A Bonferroni correction is applied if >1. Default: 1. |
The first argument is returned, invisibly, to allow chaining of expectations within testthat (if control$returnsamples==FALSE). Otherwise, a named list containing outputs form the sequential tests, for example samples and pvalues. Each element is itself a list, of length equal to the number of sequential stages performed.
pvalsampler <- function(n) { x <- sample.int(11,size=n,replace=TRUE)-1; list(pvals=chisq.test(tabulate(x+1,nbins=11), p=rep(1/11,11))$p.value) } expect_mc_test(pvalsampler)
pvalsampler <- function(n) { x <- sample.int(11,size=n,replace=TRUE)-1; list(pvals=chisq.test(tabulate(x+1,nbins=11), p=rep(1/11,11))$p.value) } expect_mc_test(pvalsampler)
Test of MCMC steps having the correct stationary distribution assuming reversibility of the chain. Uses ideas from Besag and Clifford (1989) as extended to possible ties in Gandy and Scott (2020).
expect_mcmc(object, control = NULL, thinning = NULL, joint = FALSE)
expect_mcmc(object, control = NULL, thinning = NULL, joint = FALSE)
object |
A list describing the MCMC sampler with the following elements:
|
control |
a list controlling the algorithm
|
thinning |
Amount of thinning for the MCMC chain. 1 corresponds to no thinning. Default: automatically computed to ensure an autocorrelation of at most 0.5 at lag 1. |
joint |
If TRUE, then the MCMC uses systematic scan of both data and parameters, rather than just updating parameters with the sampler to be tested. Default: FALSE. |
The first argument, invisibly, to allow chaining of expectations.
Besag J, Clifford P (1989).
“Generalized Monte Carlo significance tests.”
Biometrika, 76(4), 633–642.
doi:10.1093/biomet/76.4.633.
Gandy A, Scott J (2020).
“Unit Testing for MCMC and other Monte Carlo Methods.”
arXiv:2001.06465, https://arxiv.org/abs/2001.06465.
test_mcmc, expect_mcmc_reversible, sample_direct, sample_indirect
object <- list(genprior=function() rnorm(1), gendata=function(theta) rnorm(5,theta), stepMCMC=function(theta,data,thinning) { f <- function(x) prod(dnorm(data,x))*dnorm(x) for (i in 1:thinning) { thetanew = rnorm(1,mean=theta,sd=1) if (runif(1)<f(thetanew)/f(theta)) theta <- thetanew } theta } ) expect_mcmc(object)
object <- list(genprior=function() rnorm(1), gendata=function(theta) rnorm(5,theta), stepMCMC=function(theta,data,thinning) { f <- function(x) prod(dnorm(data,x))*dnorm(x) for (i in 1:thinning) { thetanew = rnorm(1,mean=theta,sd=1) if (runif(1)<f(thetanew)/f(theta)) theta <- thetanew } theta } ) expect_mcmc(object)
Test of MCMC steps having the correct stationary distribution assuming reversibility of the chain. Uses ideas from Besag and Clifford (1989) as extended to possible ties in Gandy and Scott (2020).
expect_mcmc_reversible( object, control = NULL, thinning = NULL, nsteps = 10, p = 1, tolerance = 1e-08 )
expect_mcmc_reversible( object, control = NULL, thinning = NULL, nsteps = 10, p = 1, tolerance = 1e-08 )
object |
A list describing the MCMC sampler with the following elements:
|
control |
a list controlling the algorithm
|
thinning |
Amount of thinning for the MCMC chain. 1 corresponds to no thinning. Default: automatically computed to ensure an autocorrelation of at most 0.5 at lag 1. |
nsteps |
Number of steps of the chain to use. Default: 10. |
p |
The probability with which the MCMC updates the parameter as opposed to the data in a given step. If less than 1.0, then the MCMC is a random scan on both data and parameters. Default: 1.0. |
tolerance |
Absolute error where value of the samplers are treated as equal. Default: 1e-8. |
The first argument, invisibly, to allow chaining of expectations.
Besag J, Clifford P (1989).
“Generalized Monte Carlo significance tests.”
Biometrika, 76(4), 633–642.
doi:10.1093/biomet/76.4.633.
Gandy A, Scott J (2020).
“Unit Testing for MCMC and other Monte Carlo Methods.”
arXiv:2001.06465, https://arxiv.org/abs/2001.06465.
expect_mcmc, test_mcmc_reversible, sample_rank
object <- list(genprior=function() rnorm(1), gendata=function(theta) rnorm(5,theta), stepMCMC=function(theta,data) { f <- function(x) prod(dnorm(data,x))*dnorm(x) thetanew = rnorm(1,mean=theta,sd=1) if (runif(1)<f(thetanew)/f(theta)) theta <- thetanew theta }, test=function(x) x ) expect_mcmc_reversible(object)
object <- list(genprior=function() rnorm(1), gendata=function(theta) rnorm(5,theta), stepMCMC=function(theta,data) { f <- function(x) prod(dnorm(data,x))*dnorm(x) thetanew = rnorm(1,mean=theta,sd=1) if (runif(1)<f(thetanew)/f(theta)) theta <- thetanew theta }, test=function(x) x ) expect_mcmc_reversible(object)
Requires as input a generic test that for a given sample size provides a vector of p-values. Aims to reject if these are not from the null. Guarantees a bound on the type I error rate.
mc_test(object, control = NULL, npval = 1)
mc_test(object, control = NULL, npval = 1)
object |
A function taking one argument n, which should be the sample size to use for the test. The function should return a named list with at least one element, "pvals", which is a vector of p-values. |
control |
a list controlling the algorithm
|
npval |
number of p-values returned by the test. A Bonferroni correction is applied if >1. Default: 1. |
A named list containing data about the sequential tests, for example samples and pvalues. Each element is itself a list, of length equal to the number of sequential stages performed.
pvalsampler <- function(n) { x <- sample.int(11,size=n,replace=TRUE)-1; list(pvals=chisq.test(tabulate(x+1,nbins=11), p=rep(1/11,11))$p.value) } mc_test(pvalsampler)
pvalsampler <- function(n) { x <- sample.int(11,size=n,replace=TRUE)-1; list(pvals=chisq.test(tabulate(x+1,nbins=11), p=rep(1/11,11))$p.value) } mc_test(pvalsampler)
Uses sample_acfs()
to estimate autocorrelation as a function of lag.
This is done for a number of different sample parameters and data. The resulting
estimates are then plotted.
plot_sample_acfs( object, paths = 50, alpha = 0.3, steps = 500, thinning = 1, ... )
plot_sample_acfs( object, paths = 50, alpha = 0.3, steps = 500, thinning = 1, ... )
object |
A list describing the MCMC sampler with the following elements:
|
paths |
Number of MCMC chains on which to estimate autocorrelation |
alpha |
Passes to |
steps |
Number of steps to take within each chain |
thinning |
Amount of thinning for the MCMC chain. 1 corresponds to no thinning. Default: automatically computed to ensure an autocorrelation of at most 0.5 at lag 1. |
... |
Additional arguments to pass to |
A ggplot
object
expect_mc_iid_mean
Creates a plot for graphical testing of uniformity of rank statistics. This procedure was first described in XXX.
## S3 method for class 'mcunit_mc_iid_mean' plot(x, ...)
## S3 method for class 'mcunit_mc_iid_mean' plot(x, ...)
x |
An object of class |
... |
other parameters to satisify S3 method consistency - will be ignored. |
An object of class "ggplot"
, which can be further modified.
expect_mcmc_reversible
Creates a plot for graphical testing of uniformity of rank statistics. This procedure was first described in XXX.
## S3 method for class 'mcunit_ranktest' plot(x, stage = length(x$ranks), ...)
## S3 method for class 'mcunit_ranktest' plot(x, stage = length(x$ranks), ...)
x |
An object of class |
stage |
|
... |
other parameters to satisify S3 method consistency - will be ignored. |
An object of class "ggplot"
, which can be further modified.
Printing results from function 'mc_test'.
## S3 method for class 'mcunit_mc_test' print(x, ...)
## S3 method for class 'mcunit_mc_test' print(x, ...)
x |
object to be printed |
... |
additional parameters passed to the function |
Estimate autocorrelation for one chain applied to one sample of parameters and data
sample_acfs(object, paths = 50, steps = 500, thinning = 1, ...)
sample_acfs(object, paths = 50, steps = 500, thinning = 1, ...)
object |
A list describing the MCMC sampler with the following elements:
|
paths |
Number of MCMC chains on which to estimate autocorrelation |
steps |
Number of steps to take within each chain |
thinning |
Amount of thinning for the MCMC chain. 1 corresponds to no thinning. Default: automatically computed to ensure an autocorrelation of at most 0.5 at lag 1. |
... |
Additional arguments to pass to |
A dataframe giving estimated autocorrelation per chain, per test statistic
Sample one realisation of the test statistics by drawing data and paramaters directly from generative model, then applying the test statistics.
sample_direct(object)
sample_direct(object)
object |
A list describing the MCMC sampler with the following elements:
|
A vector-valued sample from the test statistic
sample_indirect, test_mcmc, expect_mcmc
Sample one realisation of the test statistics indirectly by first drawing data and paramaters from the generative model, then applying MCMC to propagate the sample.
sample_indirect(object, thinning, joint)
sample_indirect(object, thinning, joint)
object |
A list describing the MCMC sampler with the following elements:
|
thinning |
Amount of thinning for the MCMC chain. 1 corresponds to no thinning. Default: automatically computed to ensure an autocorrelation of at most 0.5 at lag 1. |
joint |
If TRUE, then the MCMC uses systematic scan of both data and parameters, rather than just updating parameters with the sampler to be tested. Default: FALSE. |
A vector-valued sample from the test statistic
sample_direct, test_mcmc, expect_mcmc
Used by test_mcmc_reversible
to formally test uniformity of rank
statistics.
sample_rank(object, nsteps = 10, thinning = 1, p = 1, tolerance = 1e-08)
sample_rank(object, nsteps = 10, thinning = 1, p = 1, tolerance = 1e-08)
object |
A list describing the MCMC sampler with the following elements:
|
nsteps |
Number of steps of the chain to use. Default: 10. |
thinning |
Amount of thinning for the MCMC chain. 1 corresponds to no thinning. Default: automatically computed to ensure an autocorrelation of at most 0.5 at lag 1. |
p |
The probability with which the MCMC updates the parameter as opposed to the data in a given step. If less than 1.0, then the MCMC is a random scan on both data and parameters. Default: 1.0. |
tolerance |
Absolute error where value of the samplers are treated as equal. Default: 1e-8. |
An integer between 1 and nsteps
Gandy A, Scott J (2020). “Unit Testing for MCMC and other Monte Carlo Methods.” arXiv:2001.06465, https://arxiv.org/abs/2001.06465.
test_mcmc_reversible, expect_mcmc_reversible
Test of MCMC steps having the correct stationary distribution without assuming reversibility of the chain. Details of this are in Gandy and Scott (2020); it uses ideas described in the appendix of Gandy and Veraart (2017).
test_mcmc(object, control = NULL, thinning = NULL, joint = FALSE)
test_mcmc(object, control = NULL, thinning = NULL, joint = FALSE)
object |
A list describing the MCMC sampler with the following elements:
|
control |
a list controlling the algorithm
|
thinning |
Amount of thinning for the MCMC chain. 1 corresponds to no thinning. Default: automatically computed to ensure an autocorrelation of at most 0.5 at lag 1. |
joint |
If TRUE, then the MCMC uses systematic scan of both data and parameters, rather than just updating parameters with the sampler to be tested. Default: FALSE. |
The first argument, invisibly, to allow chaining of expectations.
Gandy A, Scott J (2020).
“Unit Testing for MCMC and other Monte Carlo Methods.”
arXiv:2001.06465, https://arxiv.org/abs/2001.06465.
Gandy A, Veraart LAM (2017).
“A Bayesian Methodology for Systemic Risk Assessment in Financial Networks.”
Management Science, 63(12), 4428–4446.
doi:10.1287/mnsc.2016.2546.
expect_mcmc, test_mcmc_reversible, sample_direct, sample_indirect
Test of MCMC steps having the correct stationary distribution assuming reversibility of the chain. Uses ideas from Besag and Clifford (1989) as extended to possible ties in Gandy and Scott (2020).
test_mcmc_reversible( object, control = NULL, thinning = NULL, nsteps = 10, p = 1, tolerance = 1e-08 )
test_mcmc_reversible( object, control = NULL, thinning = NULL, nsteps = 10, p = 1, tolerance = 1e-08 )
object |
A list describing the MCMC sampler with the following elements:
|
control |
a list controlling the algorithm
|
thinning |
Amount of thinning for the MCMC chain. 1 corresponds to no thinning. Default: automatically computed to ensure an autocorrelation of at most 0.5 at lag 1. |
nsteps |
Number of steps of the chain to use. Default: 10. |
p |
The probability with which the MCMC updates the parameter as opposed to the data in a given step. If less than 1.0, then the MCMC is a random scan on both data and parameters. Default: 1.0. |
tolerance |
Absolute error where value of the samplers are treated as equal. Default: 1e-8. |
The first argument, invisibly, to allow chaining of expectations.
Besag J, Clifford P (1989).
“Generalized Monte Carlo significance tests.”
Biometrika, 76(4), 633–642.
doi:10.1093/biomet/76.4.633.
Gandy A, Scott J (2020).
“Unit Testing for MCMC and other Monte Carlo Methods.”
arXiv:2001.06465, https://arxiv.org/abs/2001.06465.
test_mcmc, expect_mcmc_reversible, sample_rank
object <- list(genprior=function() rnorm(1), gendata=function(theta) rnorm(5,theta), stepMCMC=function(theta,data,thinning) { f <- function(x) prod(dnorm(data,x))*dnorm(x) for (i in 1:thinning) { thetanew = rnorm(1,mean=theta,sd=1) if (runif(1)<f(thetanew)/f(theta)) theta <- thetanew } theta }, test=function(x) x ) expect_mcmc_reversible(object) ## without thinning object$stepMCMC = function(theta,data){ f <- function(x) prod(dnorm(data,x))*dnorm(x) thetanew = rnorm(1,mean=theta,sd=1) if (runif(1)<f(thetanew)/f(theta)) theta <- thetanew theta } expect_mcmc_reversible(object)
object <- list(genprior=function() rnorm(1), gendata=function(theta) rnorm(5,theta), stepMCMC=function(theta,data,thinning) { f <- function(x) prod(dnorm(data,x))*dnorm(x) for (i in 1:thinning) { thetanew = rnorm(1,mean=theta,sd=1) if (runif(1)<f(thetanew)/f(theta)) theta <- thetanew } theta }, test=function(x) x ) expect_mcmc_reversible(object) ## without thinning object$stepMCMC = function(theta,data){ f <- function(x) prod(dnorm(data,x))*dnorm(x) thetanew = rnorm(1,mean=theta,sd=1) if (runif(1)<f(thetanew)/f(theta)) theta <- thetanew theta } expect_mcmc_reversible(object)