library(changepoints)
This is a simple guide for offline multiple change points detection on univariate mean.
There are 3 methods implemented for this purpose:
In addition, function local.refine.univar performs local refinement for an initial change point estimation.
= 5 # 2*delta represents the minimum gap between boundaries
delta = 1 # error variance
sigma2
set.seed(1234)
= c(rep(0, 50), rep(2, 50), rep(0, 50), rep(-2, 50)) + rnorm(200, mean = 0, sd = sqrt(sigma2)) # univariate time series
y = c(50, 100, 150)
cpt_true = length(y) # sample size n
= c(0.01, 0.5, 1, 5, 10, 50) # a set of tuning parameters for DP
gamma_set = CV.search.DP.univar(y, gamma_set, delta) # grid search through cross-validation
DP_result = which.min(DP_result$test_error) # select gamma achieves the minimum validation error
min_idx = unlist(DP_result$cpt_hat[[min_idx]]) # estimated change points by DP
cpt_DP_hat
cpt_DP_hat#> [1] 53 99 149
Hausdorff.dist(cpt_DP_hat, cpt_true)
#> [1] 3
= local.refine.univar(cpt_DP_hat, y) # perform local refinement
cpt_DPlr_hat
cpt_DPlr_hat#> [1] 51 100 150
Hausdorff.dist(cpt_DPlr_hat, cpt_true)
#> [1] 1
= 4 # user specified threshold parameter for BS
tau_BS = BS.univar(y, 1, n, delta)
BS_object = thresholdBS(BS_object, tau_BS)
BS_result
BS_result#> $BS_tree_trimmed
#> levelName
#> 1 Binary Segmentation Tree Trimmed with tau = 4
#> 2 °--N150
#> 3 °--N51
#> 4 °--N100
#>
#> $cpt_hat
#> location value level
#> 1 150 15.408017 1
#> 2 51 8.753484 2
#> 3 100 10.720866 3
= sort(BS_result$cpt_hat[,1]) # estimated change points by BS
cpt_BS_hat
cpt_BS_hat#> [1] 51 100 150
Hausdorff.dist(cpt_BS_hat, cpt_true)
#> [1] 1
= local.refine.univar(cpt_BS_hat, y) # perform local refinement
cpt_BSlr_hat
cpt_BSlr_hat#> [1] 51 100 150
Hausdorff.dist(cpt_BSlr_hat, cpt_true)
#> [1] 1
= tuneBSunivar(BS_object, y)
BS_CPD_result $cpt
BS_CPD_result#> [1] 51 100 150
Hausdorff.dist(BS_CPD_result$cpt, cpt_true)
#> [1] 1
= local.refine.univar(BS_CPD_result$cpt, y)
BS_CPD_LR
BS_CPD_LR#> [1] 51 100 150
Hausdorff.dist(BS_CPD_LR, cpt_true)
#> [1] 1
= 4 # user specified threshold parameter for WBS
tau_WBS = WBS.intervals(M = 300, lower = 1, upper = n)
intervals = WBS.univar(y, 1, n, intervals$Alpha, intervals$Beta, delta)
WBS_object = thresholdBS(WBS_object, tau_WBS)
WBS_result
WBS_result#> $BS_tree_trimmed
#> levelName
#> 1 Binary Segmentation Tree Trimmed with tau = 4
#> 2 °--N100
#> 3 ¦--N51
#> 4 °--N150
#>
#> $cpt_hat
#> location value level
#> 1 100 17.456657 1
#> 2 51 12.785814 2
#> 3 150 9.520455 2
= sort(WBS_result$cpt_hat[,1]) # estimated change points by WBS
cpt_WBS_hat
cpt_WBS_hat#> [1] 51 100 150
Hausdorff.dist(cpt_WBS_hat, cpt_true)
#> [1] 1
= local.refine.univar(cpt_WBS_hat, y) # perform local refinement
cpt_WBSlr_hat
cpt_WBSlr_hat#> [1] 51 100 150
Hausdorff.dist(cpt_WBSlr_hat, cpt_true)
#> [1] 1
= tuneBSunivar(WBS_object, y)
WBS_CPD_result $cpt
WBS_CPD_result#> [1] 51 100 150
Hausdorff.dist(WBS_CPD_result$cpt, cpt_true)
#> [1] 1
= local.refine.univar(WBS_CPD_result$cpt, y)
WBS_CPD_LR
WBS_CPD_LR#> [1] 51 100 150
Hausdorff.dist(WBS_CPD_LR, cpt_true)
#> [1] 1