Tests whether a sample is consistent with a target distribution p, where
p is supplied through its score \(\nabla_x \log p(x)\) rather than a
reference sample. The statistic is the (unbiased) kernel Stein discrepancy
(KSD); calibration uses a wild bootstrap of the degenerate U-statistic
null. Because only the score enters, the target may be known up to an
unknown normalising constant.
Usage
ksd_test(
x,
score = NULL,
kernel = c("imq", "rbf"),
beta = -0.5,
bandwidth = "median",
n_boot = 1000L,
alpha = 0.05,
seed = NULL,
n_exact_max = 5000L
)Arguments
- x
Numeric vector, matrix, or data.frame. The
n x dsample to test, one observation per row. At least five rows are required.- score
Either
NULLor a function. WhenNULL(default) the target is the standard multivariate normal, with score \(-x\). When a function, it must accept then x dsample matrix and return then x dmatrix of scores \(\nabla_x \log p(x)\) evaluated row-wise; seegaussian_score()for the multivariate-normal factory.- kernel
Character. Base kernel for the Stein kernel:
"imq"(inverse multi-quadric, default) or"rbf"(Gaussian).- beta
Numeric in
(-1, 0). Exponent of the IMQ kernel; ignored whenkernel = "rbf". Default-0.5.- bandwidth
Numeric or
"median". The IMQ offsetcor the RBF bandwidthh."median"(default) uses the median-heuristic bandwidth of the sample.- n_boot
Integer. Number of wild-bootstrap replicates for the null. Default
1000.- alpha
Numeric in
(0, 1). Significance level for the verdict. Default0.05.- seed
Integer or
NULL. Random seed for reproducibility.- n_exact_max
Integer or
Inf. Sample-size ceiling for the exactO(n^2)test. Above it, the call is delegated toksd_test_nystrom()(with a message; the verdict object recordsapproximation = "nystrom").Infforces the exact test at any size. Default5000L.
Value
An object of class c("ksd_test", "kernel_test_result") carrying
the standard kernel_test_result fields plus:
- statistic
The unbiased KSD U-statistic.
- p_value
Upper-tail wild-bootstrap p-value (with
+1correction).- stein_kernel
Base kernel used (
"imq"or"rbf").- beta
IMQ exponent, or
NAfor the RBF kernel.- bandwidth
Resolved IMQ offset or RBF bandwidth.
- surprise_bits
Shannon-information surprise
-log2(p_value).- alpha, reject
Verdict level and
p_value <= alpha.
Details
KSD is the score-based, one-sample complement to mmd_test(): where MMD
compares two samples, KSD compares a sample against a density. The
calibration framing is direct – given posterior or ensemble draws and the
score of the distribution they claim to represent, KSD asks whether the
draws actually follow that distribution. It is sensitive to mean,
variance, and tail mis-specification.
The default base kernel is the inverse multi-quadric (IMQ),
\(k(x, y) = (c^2 + \lVert x - y \rVert^2)^\beta\) with
\(\beta \in (-1, 0)\). Gorham & Mackey (2017) show the IMQ Stein
discrepancy detects non-convergence in regimes where the Gaussian (RBF)
Stein discrepancy is blind, particularly as dimension grows; the RBF base
kernel remains available via kernel = "rbf". The offset c (IMQ) and
bandwidth h (RBF) default to the median heuristic over the sample.
Reproducibility: the wild-bootstrap multipliers are drawn through R's RNG,
so a non-NULL seed makes the p-value reproducible under the active RNG
kind (the R default Mersenne-Twister unless changed by the caller).
The exact test materialises the n x n Stein-kernel matrix, so memory and
compute scale as O(n^2). To keep large samples tractable without a silent
loss of exactness, a sample with more than n_exact_max rows is delegated
to ksd_test_nystrom() – a low-rank approximation that is announced by a
message and recorded in the returned object's approximation and m
fields, so the result stays reproducible from the object. Set
n_exact_max = Inf to force the exact O(n^2) test at any size, or call
ksd_test_nystrom() directly to control the approximation rank m.
References
Liu, Q., Lee, J. D., & Jordan, M. I. (2016). A kernelized Stein discrepancy for goodness-of-fit tests. Proceedings of the 33rd International Conference on Machine Learning, PMLR 48, 276-284.
Chwialkowski, K., Strathmann, H., & Gretton, A. (2016). A kernel test of goodness of fit. Proceedings of the 33rd International Conference on Machine Learning, PMLR 48, 2606-2615.
Gorham, J., & Mackey, L. (2017). Measuring sample quality with kernels. Proceedings of the 34th International Conference on Machine Learning, PMLR 70, 1292-1301.
See also
mmd_test(), mmd_ppc(), gaussian_score()
Other goodness-of-fit tests:
calibration_suite(),
concordance_test(),
concordance_test_nystrom(),
coverage_test(),
gaussian_score(),
joint_coverage_test(),
ksd_test_nystrom(),
numeric_score()
Author
Max Moldovan, max.moldovan@adelaide.edu.au
Examples
set.seed(1)
# Well-specified: standard-normal sample against standard-normal target
x_ok <- matrix(stats::rnorm(400L), ncol = 2L)
fit_ok <- ksd_test(x_ok, n_boot = 199L, seed = 1L)
fit_ok
#>
#> KSD Test
#>
#> Statistic: -0.00225082
#> P-value: 0.6300
#> N: 200
#> Perms: 199
#> Kernel X: imq
#>
#> Goodness-of-fit verdict
#> Stein kernel: imq (beta = -0.5)
#> Bandwidth: 1.608 (median heuristic)
#> Bootstrap: wild, B = 199
#> Surprise: 0.667 bits
#> Verdict: consistent with target
#>
# Mis-specified: mean-shifted sample against the same target
x_bad <- x_ok + 1
fit_bad <- ksd_test(x_bad, n_boot = 199L, seed = 1L)
fit_bad
#>
#> KSD Test
#>
#> Statistic: 0.946639
#> P-value: 0.0050
#> N: 200
#> Perms: 199
#> Kernel X: imq
#>
#> Goodness-of-fit verdict
#> Stein kernel: imq (beta = -0.5)
#> Bandwidth: 1.608 (median heuristic)
#> Bootstrap: wild, B = 199
#> Surprise: 7.644 bits
#> Verdict: REJECT (sample inconsistent with target)
#>
# Explicit non-standard target via the Gaussian score factory
sig <- matrix(c(1, 0.6, 0.6, 1), nrow = 2L)
x_cor <- x_ok %*% chol(sig)
ksd_test(x_cor, score = gaussian_score(sigma = sig),
n_boot = 199L, seed = 1L)
#>
#> KSD Test
#>
#> Statistic: -0.00438649
#> P-value: 0.6050
#> N: 200
#> Perms: 199
#> Kernel X: imq
#>
#> Goodness-of-fit verdict
#> Stein kernel: imq (beta = -0.5)
#> Bandwidth: 1.472 (median heuristic)
#> Bootstrap: wild, B = 199
#> Surprise: 0.725 bits
#> Verdict: consistent with target
#>
