Segment costs and parameters
segment-costs-and-parameters.RmdThis chapter shows how to get the cost and parameter estimates of
each segment, either from a fitted segmentation
($segments()) or for any segment you choose, without
running a detection algorithm (costFactory).
Costs and parameters of each segment
After $predict(), $segments() returns a
list with one element per segment (available on binSeg,
Window, PELT and Dynp; the
example below uses PELT). Each element is a list with
Start, End, Cost and
Params, where the segment is (Start, End] with
the same 0-based convention as $eval(a, b).
Cost equals $eval(Start, End), and
Params is the same named list costFactory’s
$get_params() returns (see below).
set.seed(1)
tsMat = cbind(c(rnorm(100, 0), rnorm(100, 5, 5)))
PELTObj = PELT$new(minSize = 5L, costFunc = costFunc$new("SIGMA"))
PELTObj$fit(tsMat)
PELTObj$predict(pen = 50)
#> [1] 100 200
segs = PELTObj$segments()
segs[[2]]
#> $Start
#> [1] 100
#>
#> $End
#> [1] 200
#>
#> $Cost
#> [1] 312.2758
#>
#> $Params
#> $Params$mean
#> [1] 4.81096
#>
#> $Params$cov
#> [,1]
#> [1,] 22.70893For PELT, the segment costs add up to the optimal
penalised cost minus pen times the number of
change-points.
sapply(segs, `[[`, "Cost")
#> [1] -22.47755 312.27581Re-fitting (including through an active binding such as
$minSize or $costFunc) clears the segmentation
saved by the last $predict(), so $predict()
must be run again before calling $segments().
Costs without a detection algorithm
Sometimes you don’t need a detection algorithm at all, only fast cost
evaluation and parameter estimation for segments whose boundaries you
already have (e.g., cross-validating a pen value against
known change-points, or just querying a segment’s fitted parameters).
costFactory wraps the same C++ cost modules
used internally by
PELT/binSeg/Window/Dynp,
exposing only $eval(), $get_params() and
$segments(), with no segmentation logic.
set.seed(1)
tsMat = cbind(c(rnorm(100, 0), rnorm(100, 5, 5)))
cf = costFactory$new(costFunc$new("L2"))
cf$fit(tsMat)
cf$eval(0, 100)
#> [1] 79.86945
cf$get_params(0, 100)
#> $mean
#> [1] 0.1088874As with the segmentation classes, $costFunc is an active
binding: reassigning it after $fit() automatically re-fits
the underlying module against the same data.
cf$costFunc = costFunc$new("SIGMA")
#> `costFunc` has been updated. Re-fitting the model.
cf$eval(0, 100)
#> [1] -22.47755
cf$get_params(0, 100)
#> $mean
#> [1] 0.1088874
#>
#> $cov
#> [,1]
#> [1,] 0.7986955$get_params()’s return shape depends on the cost
function: median/mean for
"L1"/"L2", mean and
cov for "SIGMA", coef (intercept
first) for
"VAR"/"LinearL2"/"LinearL1",
coef and cov for "LinearSIGMA",
and params (whatever paramFun returns) for
"Custom". Both covs are biased estimates,
divided by the segment length n with no bias or
degrees-of-freedom correction, and include epsilon on the
diagonal if addSmallDiag = TRUE.
$segments(endPts) runs $eval() and
$get_params() over every segment of a given segmentation,
returning the same list as the segmentation classes’
$segments() (see above). endPts must end at
n, so the output of any $predict() can be
passed as is: