Cost functions
cost-functions.RmdThis chapter lists the cost functions built into
rupturesRcpp, their options, and how to supply your own
cost as an R function. A cost function measures how badly a single model
fits a segment; every segmentation class and costFactory
takes one as a costFunc object.
Built-in cost functions
Create a costFunc object by specifying the desired
(supported) cost function and optional parameters:
costFuncObj = costFunc$new("L2")
costFuncObj$pass() #output attributes corresponding to the specified cost function.
#> $costFunc
#> [1] "L2"The following table shows the list of supported cost functions
(pre-implemented ones are PELT-compatible; see Segmentation methods). Here,
n is the segment length, and the time complexity is that of
one segment query. For "LinearL1", p is the
number of features (columns of tsMat), J the
number of regression coefficients (covariates plus the intercept) and
maxIter the maximum number of IRLS iterations: every query
refits the regression on the segment’s rows, so it grows linearly in
n.
| Cost function | Description | Parameters/active bindings | Dimension | Time complexity |
|---|---|---|---|---|
"L1" |
Sum of L1 distances to the segment-wise median; robust
to outliers. |
costFunc |
multi |
O(nlog(n)) |
"L2" |
Sum of squared L2 distances to the segment-wise mean;
faster but less robust than L1. |
costFunc |
multi |
O(1) |
"SIGMA" |
Log-determinant of the empirical covariance (divided by
n, no bias correction); models varying
mean&variance. |
costFunc, addSmallDiag,
epsilon
|
multi |
O(1) |
"LinearL1" |
Sum of L1 residuals from a linear regression model, fit
via Iteratively Reweighted Least Squares (IRLS); robust to
outliers. |
costFunc, intercept, tol,
maxIter
|
multi |
O(p·n·J²·maxIter) |
"LinearL2" |
Sum of squared residuals from a linear regression model with constant noise variance. |
costFunc, intercept
|
multi |
O(1) |
"LinearSIGMA" |
Log-determinant of the residual covariance (divided by
n, no degrees-of-freedom correction) from a linear
regression model; models varying noise covariance around a regression
mean. |
costFunc, intercept,
addSmallDiag, epsilon
|
multi |
O(1) |
"VAR" |
Sum of squared residuals from a vector autoregressive model with constant noise variance. |
costFunc, pVAR
|
multi |
O(1) |
"Custom" |
User-defined cost, supplied as a plain R function (see User-defined cost functions below). |
costFunc, evalFun,
paramFun
|
multi |
depends on evalFun
|
Every covariance in the package, in the
"SIGMA"/"LinearSIGMA" costs and in the
cov returned by
$get_params()/$segments(), is the biased
maximum-likelihood estimate: divided by the segment length
n, with no Bessel (n - 1) or
degrees-of-freedom (n - q for q regression
coefficients) correction.
If active binding costFunc is modified by assigning to
costFuncObj$costFunc and the required parameters are
missing, the default parameters will be used. This does not apply to
"Custom": there is no sensible default
evalFun, so $pass()/$fit() will
error until one is set (see below).
costFuncObj$costFunc = "VAR"
costFuncObj$pass()
#> $costFunc
#> [1] "VAR"
#>
#> $pVAR
#> [1] 1User-defined cost functions
If none of the built-in cost functions fit,
costFunc = "Custom" lets you supply your own as a plain R
function, with no C++ required. It takes two active bindings:
-
evalFun(required): called asevalFun(segment, a, b), wheresegmentis the raw matrix of rows(a+1):bof the fittedtsMat, anda/bare the same 0-indexed(a,b]bounds$eval(a, b)uses. Must return a single numeric value. -
paramFun(optional, defaultNULL): same calling convention, used by internal parameter reporting; if omitted,"Custom"simply reports no parameters.
Passing a/b through, not just
segment, is what makes this more than a convenience
wrapper: evalFun can use them to align segment
against any other externally-captured, position-indexed data (e.g. an
exogenous series or weight vector) that the package itself is never told
about. Because each call crosses back into R, it is substantially slower
per call than the built-in costs, so prefer one of those when it
fits.
For example, "L2" re-implemented as a
"Custom" cost:
myL2eval = function(segment, a, b){
segment = as.matrix(segment)
cm = colMeans(segment)
sum(sweep(segment, 2, cm, FUN = "-")^2)
}
customCF = costFunc$new("Custom", evalFun = myL2eval)
customCF$pass()
#> $costFunc
#> [1] "Custom"
#>
#> $evalFun
#> function (segment, a, b)
#> {
#> segment = as.matrix(segment)
#> cm = colMeans(segment)
#> sum(sweep(segment, 2, cm, FUN = "-")^2)
#> }
#>
#> $paramFun
#> NULLRisk of data mismatch
The segmentation logic of existing modules only depends on being able
to compute the cost for an arbitrary segment (a,b]; it does
not depend on how the data are stored. Therefore, with a custom cost
function, a mismatch can occur if the function relies on external data
that are not part of the object passed to $fit(). The Custom cost
functions case study shows an example.
Using a cost function
A costFunc object is passed to a segmentation class or
to costFactory:
-
Segmentation
methods:
binSeg,Window,PELTandDynpsearch for change-points under the chosen cost. -
Segment
costs and parameters:
costFactoryevaluates segments you choose, without a detection. - Case studies: Change in mean and
variance (
"SIGMA"), Change in autoregressive dynamics ("VAR"), Tuning the penalty ("L2") and Custom cost functions ("Custom").