Wraps the ocd package (Chen, Wang and Samworth, 2022): online
multiscale detection of a mean change in a high-dimensional stream, with
worst-case detection-delay guarantees and per-observation cost independent
of history. The detector assumes standardised data with known pre-change
mean; this wrapper estimates the baseline mean and standard deviation
from an initial training window, then monitors the remainder of the
series, resetting after each declaration so multiple changes can be
found.
Arguments
- x
A numeric matrix or data frame with one row per time point and at least two columns. The
ocddetector is inherently high-dimensional and cannot be constructed for a single coordinate, so univariate input is rejected; use a univariate engine (seecpt_methods()) for one series.- train
Number of initial observations used to estimate the baseline mean/sd (not monitored). Defaults to
max(20, floor(0.2 * n)), capped atn/2.- thresh
Threshold specification passed to
ocd::ChangepointDetector();"MC"(default) calibrates by Monte Carlo, which is what makes this the slowest wrapper (see the timing note below). Supplying the three thresholds directly, as a named numeric vectorc(diag =, off_d =, off_s =), skips calibration altogether.- patience
Target average run length to false alarm. Defaults to
5000.- beta
Assumed lower bound on the squared Euclidean norm of the mean change. Defaults to
1.- mc_reps
Monte Carlo repetitions for threshold calibration. Defaults to
100. The cost is linear in this and grows with the number of coordinates; see the timing note below.- ...
Additional arguments passed to
ocd::ChangepointDetector().
Value
A ggcpt object. Because the detector is online, reported
locations are declaration times (the changepoint plus the
detection delay). The declared_at column holds the same values
as cp, and deliberately: ocd declares a change without
also estimating where it began, so there is no separate location for
the second column to carry. Compare cpm_wrapper(),
whose engine supplies both, and whose cp is an estimated
location with detection_time strictly later.
How long this takes
Nearly all of the run time is ocd's Monte Carlo threshold
calibration, which happens before a single observation is read. It is
linear in mc_reps and grows with the number of coordinates. Timed
on one Linux x86-64 machine at mc_reps = 5, construction took
about 10 s at \(p = 3\), 22 s at \(p = 10\) and 113 s at
\(p = 50\); raising mc_reps scales it linearly, so at
\(p = 3\) it was 38 s at mc_reps = 20 and 189 s at the default
mc_reps = 100. The practical reading is that the default costs
minutes rather than seconds even for a handful of coordinates,
and better than half an hour at \(p = 50\). Another machine will give
different absolute numbers; the linearity in mc_reps is the part
to plan around. Monitoring the observations afterwards is cheap by
comparison: 0.37 s for a thousand of them at \(p = 3\). Lower
mc_reps while exploring (the example below uses 2, which
measures 3.8 s), or pass thresh directly to skip
calibration entirely, which brings the same fit down to a tenth of a
second.
References
Chen Y, Wang T, Samworth RJ (2022). “High-dimensional, multiscale online changepoint detection.” Journal of the Royal Statistical Society: Series B, 84(1), 234–266.
See also
Other changepoint engines:
bcp_wrapper(),
beast_wrapper(),
bfast_wrapper(),
binsegrcpp_wrapper(),
bocpd_wrapper(),
cpm_wrapper(),
cpop_wrapper(),
cpt_wrapper(),
decafs_wrapper(),
ecp_wrapper(),
envcpt_wrapper(),
esac_wrapper(),
fabisearch_wrapper(),
fastcpd_wrapper(),
fcov_wrapper(),
fmean_wrapper(),
fpop_wrapper(),
geomcp_wrapper(),
hdcov_wrapper(),
hdreg_wrapper(),
idetect_wrapper(),
inspect_wrapper(),
kcp_wrapper(),
kwc_wrapper(),
mcp_wrapper(),
mosum_wrapper(),
network_wrapper(),
not_wrapper(),
npmojo_wrapper(),
nsp_wrapper(),
pilliat_wrapper(),
segmented_wrapper(),
smuce_wrapper(),
sn_wrapper(),
strucchange_wrapper(),
taylor_wrapper(),
tguh_wrapper(),
trend_wrapper(),
var_wrapper(),
wbs2_wrapper(),
wbs_wrapper(),
wbsts_wrapper()
Examples
# \donttest{
set.seed(2026)
X <- rbind(matrix(rnorm(60 * 3), 60), matrix(rnorm(40 * 3, 3), 40))
# `mc_reps = 2`, not the default 100 and not the 5 this example used to
# pass: the calibration is linear in `mc_reps` and is nearly all of the
# cost, so 5 measured 9.7 s here against CRAN's 5 s budget and 2
# measures 3.8 s for the same answer. Neither is a calibration you
# would trust -- see the timing section above.
res <- ocd_wrapper(X, mc_reps = 2)
res$changepoints
#> # A tibble: 1 × 3
#> cp cp_value declared_at
#> <int> <dbl> <int>
#> 1 62 4.31 62
# }
