| Title: | Change Point Detection with L0 Penalty |
|---|---|
| Description: | Under an L0 penalty framework, a computationally efficient implementation of change point detection is developed. By integrating active set algorithms with warm start initialization, the package achieves linear-time complexity for solving change point detection problems. References: Wen et al. (2020) <doi:10.18637/jss.v094.i04>; Zhu et al. (2020)<doi:10.1073/pnas.2014241117>. |
| Authors: | Tianhao Wang [aut, cre] |
| Maintainer: | Tianhao Wang <[email protected]> |
| License: | GPL (>= 3) |
| Version: | 0.2.0 |
| Built: | 2026-05-23 08:04:00 UTC |
| Source: | https://github.com/cran/L0cpt |
L0 penalty is useful for change point detection, commonly referred to as L0 penalized
and L0 constraint problems. The L0 penalized problem which applies the hyperparameter ,
is illustrated below:
In practice, rather than selecting within an appropriate range, the number of change points
(a positive integer ) is more feasible and convenient in the L0 constraint model:
For such L0 constraint problems, we employ a splicing-based approach to design algorithms for processing. This package has the following five main methods:
Fit a piecewise constant estimated trend
with a given number of change points.
Fit a piecewise constant estimated trend
with a maximum number of change points, and select the optimal estimated trend using appropriate
information criteria.
Generate piecewise constant data.
Print a summary of the change point detection and trend
estimation results.
Plot a summary of the trend estimation results.
_PACKAGE
Due to the connection between L0 constraint problems and L0 penalty problems, and considering
that the sparsity of change points is is more meaningful in practical applications than the selection
of the hyperparameter . We focus on the constraint that reflects our aim to achieve the
estimated trend and change-point estimator with a given number of change points.
Harchaoui Z and Lévy-Leduc C. Multiple change-point estimation with a total variation penalty. Journal of the American Statistical Association (2010).
Qian J and Su L. Shrinkage estimation of regression models with multiple structural. Econometric Theory (2016).
Extracts the coefficients of the estimated beta under the constraint of a given number of change points.
## S3 method for class 'L0cptfix' coef(object, ...)## S3 method for class 'L0cptfix' coef(object, ...)
object |
The output of L0cptfix |
... |
ignore |
The non-zero coefficient values of the vector beta in the process.
n = 500 sigma = 0.7 tau = c(0.1, 0.25, 0.3, 0.4, 0.7, 0.85, 0.95) h = c(-1, 5, 3, 0, -1, 2, 0, -1) seed = 50 blocksdata = SimuBlocks(n, sigma, seed, tau, h) k = 7 first = 0 last = 1 blocksdatafit_fix = L0cpt.fix(blocksdata$y, k, first, last) coef(blocksdatafit_fix)n = 500 sigma = 0.7 tau = c(0.1, 0.25, 0.3, 0.4, 0.7, 0.85, 0.95) h = c(-1, 5, 3, 0, -1, 2, 0, -1) seed = 50 blocksdata = SimuBlocks(n, sigma, seed, tau, h) k = 7 first = 0 last = 1 blocksdatafit_fix = L0cpt.fix(blocksdata$y, k, first, last) coef(blocksdatafit_fix)
Extracts the coefficients of the estimated beta under the optimal change points.
## S3 method for class 'L0cptopt' coef(object, ...)## S3 method for class 'L0cptopt' coef(object, ...)
object |
The output of L0cptopt |
... |
ignore |
The non-zero coefficient values of the vector beta in the process.
n = 500 sigma = 0.7 tau = c(0.1, 0.25, 0.3, 0.4, 0.7, 0.85, 0.95) h = c(-1, 5, 3, 0, -1, 2, 0, -1) seed = 50 blocksdata = SimuBlocks(n, sigma, seed, tau, h) kmax = 15 first = 0 last = 1 blocksdatafit_opt = L0cpt.opt(blocksdata$y, kmax, first, last, "bic") coef(blocksdatafit_opt)n = 500 sigma = 0.7 tau = c(0.1, 0.25, 0.3, 0.4, 0.7, 0.85, 0.95) h = c(-1, 5, 3, 0, -1, 2, 0, -1) seed = 50 blocksdata = SimuBlocks(n, sigma, seed, tau, h) kmax = 15 first = 0 last = 1 blocksdatafit_opt = L0cpt.opt(blocksdata$y, kmax, first, last, "bic") coef(blocksdatafit_opt)
Fit the input data points to a piecewise constant trend with a given number of change points.
L0cpt.fix(y = y, k = k, first = 0, last = 1, M = 5)L0cpt.fix(y = y, k = k, first = 0, last = 1, M = 5)
y |
The input data points |
k |
The given number of change points |
first |
The value ranges from 0 to 1. Represent the minimum percentile point where a change point may occur. If 'first' = 0.01, it means that change points cannot appear in the first 1% of the data points. If 'first' = 0, there is no constraint on the position of the change point. |
last |
The value ranges from 0 to 1. Represent the maximum percentile point where a change point may occur. If 'last' = 0.99, it means that change points cannot appear in the last 1% of the data points. If 'last' = 1, there is no constraint on the position of the change point. |
M |
The maximum number of exchange change-points in the splicing method. In the vast majority of cases, |
An S3 object of type "L0cptfix". A list containing the fitted trend results:
y |
The input data points |
betak |
The fitted |
yk |
The fitted trend with the number of change points being |
Ak |
The set of position indicators of the fitted change points with the number of change points being |
tau = c(0.1, 0.3, 0.4, 0.7, 0.85) h = c(-1, 5, 3, 0, -1, 2) BlocksData <- SimuBlocks(n = 350, sigma = 0.2, seed = 50, tau = tau ,h = h) res <- L0cpt.fix(y=BlocksData$y, k=5, first=0.01, last=1, M=5) print(res$Ak) print(BlocksData$setA) plot(BlocksData$x, BlocksData$y, xlab="", ylab="") lines(BlocksData$x, BlocksData$y0, col = "red") lines(BlocksData$x, res$yk, col = "lightgreen")tau = c(0.1, 0.3, 0.4, 0.7, 0.85) h = c(-1, 5, 3, 0, -1, 2) BlocksData <- SimuBlocks(n = 350, sigma = 0.2, seed = 50, tau = tau ,h = h) res <- L0cpt.fix(y=BlocksData$y, k=5, first=0.01, last=1, M=5) print(res$Ak) print(BlocksData$setA) plot(BlocksData$x, BlocksData$y, xlab="", ylab="") lines(BlocksData$x, BlocksData$y0, col = "red") lines(BlocksData$x, res$yk, col = "lightgreen")
Fit the input data points to a piecewise constant trend with optimal change points.
L0cpt.opt(y = y, kmax = kmax, first = 0, last = 1, penalty = "bic", M = 5)L0cpt.opt(y = y, kmax = kmax, first = 0, last = 1, penalty = "bic", M = 5)
y |
The input data points |
kmax |
The maximum number of change points |
first |
The value ranges from 0 to 1. Represent the minimum percentile point where a change point may occur. If 'first' = 0.01, it means that change points cannot appear in the first 1% of the data points. If 'first' = 0, there is no constraint on the position of the change point. |
last |
The value ranges from 0 to 1. Represent the maximum percentile point where a change point may occur. If 'last' = 0.99, it means that change points cannot appear in the last 1% of the data points. If 'last' = 1, there is no constraint on the position of the change point. |
penalty |
'sic' or 'bic' penalty |
M |
The maximum number of exchange change-points in the splicing method. In the vast majority of cases, |
Let the fitted trend be denoted as , then
and
The term represents the degrees of freedom for the estimated trend, where . Here, refers to the number of change points in the estimated trend.
An S3 object of type "L0cptopt". A list containing the fitted trend results:
y |
The input data points |
betaopt |
The fitted |
yopt |
The fitted trend with optimal change points |
Aopt |
The set of position indicators of the fitted change points with optimal change points |
kopt |
Optimal number of change points |
ic |
' |
kmax |
The maximum number of change points. |
tau = c(0.1, 0.3, 0.4, 0.7, 0.85) h = c(-1, 5, 3, 0, -1, 2) BlocksData <- SimuBlocks(n = 500, sigma = 0.2, seed = 50, tau = tau ,h = h) res <- L0cpt.opt(y=BlocksData$y, kmax=20, first=0.01, last=1, penalty="bic", M=5) print(res$Aopt) print(BlocksData$setA) plot(BlocksData$x, BlocksData$y, xlab="", ylab="") lines(BlocksData$x, BlocksData$y0, col = "red") lines(BlocksData$x, res$yopt, col = "lightgreen")tau = c(0.1, 0.3, 0.4, 0.7, 0.85) h = c(-1, 5, 3, 0, -1, 2) BlocksData <- SimuBlocks(n = 500, sigma = 0.2, seed = 50, tau = tau ,h = h) res <- L0cpt.opt(y=BlocksData$y, kmax=20, first=0.01, last=1, penalty="bic", M=5) print(res$Aopt) print(BlocksData$setA) plot(BlocksData$x, BlocksData$y, xlab="", ylab="") lines(BlocksData$x, BlocksData$y0, col = "red") lines(BlocksData$x, res$yopt, col = "lightgreen")
Plots the estimated trend of L0cptfix object.
## S3 method for class 'L0cptfix' plot(x, ...)## S3 method for class 'L0cptfix' plot(x, ...)
x |
The output of L0cptfix |
... |
ignore |
The vertical blue dashed line in the plot's x-axis represents the detected change point location.
Plots a "L0cptfix" object.
n = 500 sigma = 0.7 tau = c(0.1, 0.25, 0.3, 0.4, 0.7, 0.85, 0.95) h = c(-1, 5, 3, 0, -1, 2, 0, -1) seed = 50 blocksdata = SimuBlocks(n, sigma, seed, tau, h) k = 7 first = 0 last = 1 blocksdatafit_fix = L0cpt.fix(blocksdata$y, k, first, last) plot(blocksdatafit_fix)n = 500 sigma = 0.7 tau = c(0.1, 0.25, 0.3, 0.4, 0.7, 0.85, 0.95) h = c(-1, 5, 3, 0, -1, 2, 0, -1) seed = 50 blocksdata = SimuBlocks(n, sigma, seed, tau, h) k = 7 first = 0 last = 1 blocksdatafit_fix = L0cpt.fix(blocksdata$y, k, first, last) plot(blocksdatafit_fix)
Plots the optimal trend of L0cptopt object.
## S3 method for class 'L0cptopt' plot(x, ...)## S3 method for class 'L0cptopt' plot(x, ...)
x |
The output of L0cptopt |
... |
ignore |
The vertical blue dashed line in the plot's x-axis represents the detected change point location.
Plots a "L0cptopt" object.
n = 500 sigma = 0.7 tau = c(0.1, 0.25, 0.3, 0.4, 0.7, 0.85, 0.95) h = c(-1, 5, 3, 0, -1, 2, 0, -1) seed = 50 blocksdata = SimuBlocks(n, sigma, seed, tau, h) kmax = 15 first = 0 last = 1 blocksdatafit_opt = L0cpt.opt(blocksdata$y, kmax, first, last, "bic") plot(blocksdatafit_opt)n = 500 sigma = 0.7 tau = c(0.1, 0.25, 0.3, 0.4, 0.7, 0.85, 0.95) h = c(-1, 5, 3, 0, -1, 2, 0, -1) seed = 50 blocksdata = SimuBlocks(n, sigma, seed, tau, h) kmax = 15 first = 0 last = 1 blocksdatafit_opt = L0cpt.opt(blocksdata$y, kmax, first, last, "bic") plot(blocksdatafit_opt)
Outputs the detected change point detection results.
## S3 method for class 'L0cptfix' print(x, ...)## S3 method for class 'L0cptfix' print(x, ...)
x |
The output of L0cptfix |
... |
ignore |
For clarity of presentation, we retain only four decimal places for the fitted change point positions normalized to the interval [0, 1].
Prints a summary of the fitted change points in "L0cptfix" object.
n = 500 sigma = 0.7 tau = c(0.1, 0.25, 0.3, 0.4, 0.7, 0.85, 0.95) h = c(-1, 5, 3, 0, -1, 2, 0, -1) seed = 50 blocksdata = SimuBlocks(n, sigma, seed, tau, h) k = 7 first = 0 last = 1 blocksdatafit_fix = L0cpt.fix(blocksdata$y, k, first, last) print(blocksdatafit_fix)n = 500 sigma = 0.7 tau = c(0.1, 0.25, 0.3, 0.4, 0.7, 0.85, 0.95) h = c(-1, 5, 3, 0, -1, 2, 0, -1) seed = 50 blocksdata = SimuBlocks(n, sigma, seed, tau, h) k = 7 first = 0 last = 1 blocksdatafit_fix = L0cpt.fix(blocksdata$y, k, first, last) print(blocksdatafit_fix)
Outputs the optimal change point detection results.
## S3 method for class 'L0cptopt' print(x, ...)## S3 method for class 'L0cptopt' print(x, ...)
x |
The output of L0cptopt |
... |
ignore |
For clarity of presentation, we retain only four decimal places for the fitted change point positions normalized to the interval [0, 1].
Prints a summary of the fitted change points in "L0cptopt" object.
n = 500 sigma = 0.7 tau = c(0.1, 0.25, 0.3, 0.4, 0.7, 0.85, 0.95) h = c(-1, 5, 3, 0, -1, 2, 0, -1) seed = 50 blocksdata = SimuBlocks(n, sigma, seed, tau, h) kmax = 15 first = 0 last = 1 blocksdatafit_opt = L0cpt.opt(blocksdata$y, kmax, first, last, "bic") print(blocksdatafit_opt)n = 500 sigma = 0.7 tau = c(0.1, 0.25, 0.3, 0.4, 0.7, 0.85, 0.95) h = c(-1, 5, 3, 0, -1, 2, 0, -1) seed = 50 blocksdata = SimuBlocks(n, sigma, seed, tau, h) kmax = 15 first = 0 last = 1 blocksdatafit_opt = L0cpt.opt(blocksdata$y, kmax, first, last, "bic") print(blocksdatafit_opt)
This function generates data points of piecewise constant trends.
SimuBlocks(n, sigma, seed = NA, tau, h)SimuBlocks(n, sigma, seed = NA, tau, h)
n |
Number of data points |
sigma |
Standard deviation of the noise added to the signal |
seed |
An optional seed for random number generation to make results reproducible |
tau |
The locations of change points in the underlying trend |
h |
The constant values of the |
To simplify the analysis, normalize the change point positions to a range between 0 and 1.
Require that all elements of the input are within this range. Consequently, the change
point positions in simulated data forms a subset of the set { , ,
,..., 1}.
In fact, change points can divide the interval into
segments of constant function values. Therefore, ensure that the length of vector is
.
A list containing the piecewise constant simulated data and the underlying trend:
x |
The set { |
y |
The piecewise constant simulated data of length |
y0 |
The underlying trend of length |
setA |
The set of position indicators of change points in the simulated data |
tau |
The locations of change points in the underlying trend |
tau = c(0.1, 0.3, 0.4, 0.7, 0.85) h = c(-1, 5, 3, 0, -1, 2) BlocksData <- SimuBlocks(n = 350, sigma = 0.1, seed = 50, tau = tau ,h = h) plot(BlocksData$x, BlocksData$y, xlab="", ylab="", col="grey", lty="blank", type="p") lines(BlocksData$x, BlocksData$y0, col="black", lty="solid", type="l") print(BlocksData$setA) print(BlocksData$tau)tau = c(0.1, 0.3, 0.4, 0.7, 0.85) h = c(-1, 5, 3, 0, -1, 2) BlocksData <- SimuBlocks(n = 350, sigma = 0.1, seed = 50, tau = tau ,h = h) plot(BlocksData$x, BlocksData$y, xlab="", ylab="", col="grey", lty="blank", type="p") lines(BlocksData$x, BlocksData$y0, col="black", lty="solid", type="l") print(BlocksData$setA) print(BlocksData$tau)