Segment pattern from a time-series x via Adaptive Empirical Pattern Transformation (ADEPT).

segmentPattern(
  x,
  x.fs,
  template,
  pattern.dur.seq,
  similarity.measure = "cov",
  similarity.measure.thresh = 0,
  x.adept.ma.W = NULL,
  finetune = NULL,
  finetune.maxima.ma.W = NULL,
  finetune.maxima.nbh.W = NULL,
  run.parallel = FALSE,
  run.parallel.cores = 1L,
  x.cut = TRUE,
  x.cut.vl = 6000,
  compute.template.idx = FALSE
)

Arguments

x

A numeric vector. A time-series to segment pattern from.

x.fs

A numeric scalar. Frequency at which a time-series x is collected, expressed in a number of observations per second.

template

A list of numeric vectors, or a numeric vector. Each vector represents a distinct pattern template used in segmentation.

pattern.dur.seq

A numeric vector. A grid of potential pattern durations used in segmentation. Expressed in seconds. See: Details.

similarity.measure

A character scalar. Statistic used to compute similarity between a time-series x and pattern templates. Currently supported values:

  • "cov" - covariance,

  • "cor" - correlation,

Default is "cov".

similarity.measure.thresh

A numeric scalar. Threshold of minimal similarity value between a time-series x and a template below which the algorithm does not identify a pattern occurrence from x. Default is 0.

x.adept.ma.W

A numeric scalar. A length of a window used in moving average smoothing of a time-series x for similarity matrix computation. Expressed in seconds. Default is NULL (no smoothing applied).

finetune

A character scalar. A type of fine-tuning procedure employed in segmentation. Defaults to NULL (no fine-tuning procedure employed). Currently supported values:

  • "maxima" - tunes preliminarily identified beginning and end of a pattern so as they correspond to local maxima of time-series x (or smoothed version of x) found within neighbourhoods of preliminary locations.

finetune.maxima.ma.W

A numeric scalar. A length of a window used in moving average smoothing of a time-series x in "maxima" fine-tuning procedure. Expressed in seconds. Default is NULL (no smoothing applied).

finetune.maxima.nbh.W

A numeric scalar. A length of the two neighborhoods centered at preliminarily identified beginning and end of a pattern within which we search for local maxima of x (or smoothed version of x) in "maxima" fine-tuning procedure. Expressed in seconds. Default is NULL. Note: if the length provided corresponds to an even number of x vector indices, it will be rounded down so as the corresponding number of vector indices is its closest odd number.

run.parallel

A logical scalar. Whether or not to use parallel execution in the algorithm with parallel package. Default is FALSE. DOES NOT WORK ON WINDOWS.

run.parallel.cores

An integer scalar. The number of cores to use for parallel execution. Defaults to 1L (no parallel). DOES NOT WORK ON WINDOWS.

x.cut

A logical scalar. Whether or not to use time optimization procedure in which a time-series x is cut into parts and segmentation is performed for each part of x separately. Recommended for a time-series x of vector length above 30,000. Default is TRUE.

x.cut.vl

An integer scalar. Defines a vector length of parts that x vector is cut into during the execution time optimization procedure. Default is 6000 (recommended).

compute.template.idx

A logical scalar. Whether or not to compute and return information about which of the provided pattern templates yielded a similarity matrix value that corresponds to an identified pattern occurrence. Setting to TRUE may increase computation time. Default is FALSE.

Value

A data.frame with segmentation results. Each row describes one identified pattern occurrence:

  • tau_i - index of x where pattern starts,

  • T_i - pattern duration, expressed in x vector length,

  • sim_i - similarity between a pattern and x; note: if "maxima" fine-tune and/or x smoothing is employed, the similarity value between the final segmented pattern and a template may differ from the value in this table,

  • template_i - if compute.template.idx equals TRUE: index of a template best matched to x; if compute.template.idx equals FALSE: NA.

Details

Function implements Adaptive Empirical Pattern Transformation (ADEPT) method for pattern segmentation from a time-series x. ADEPT is optimized to perform fast, accurate walking strides segmentation from high-density data collected with a wearable accelerometer during walking.

ADEPT identifies patterns in a time-series x via maximization of chosen similarity statistic (correlation, covariance, etc.) between a time-series x and a pattern template(s). It accounts for variability in both (1) pattern duration and (2) pattern shape.

References

Karas, M., Straczkiewicz, M., Fadel, W., Harezlak, J., Crainiceanu, C.M., Urbanek, J.K. (2019). Adaptive empirical pattern transformation (ADEPT) with application to walking stride segmentation. Biostatistics. https://doi.org/10.1093/biostatistics/kxz033

Examples

## Example 1: Simulate a time-series `x`. Assume that ## - `x` is collected at a frequency of 100 Hz, ## - there is one shape of pattern present within `x`, ## - each pattern lasts 1 second, ## - there is no noise in the collected data. true.pattern <- cos(seq(0, 2 * pi, length.out = 100)) x <- c(true.pattern[1], replicate(10, true.pattern[-1])) ## Segment pattern from x. out <- segmentPattern( x = x, x.fs = 100, template = true.pattern, pattern.dur.seq = c(0.9, 0.95, 1.03, 1.1), similarity.measure = "cor", compute.template.idx = TRUE) out
#> tau_i T_i sim_i template_i #> 1 4 95 0.9987941 1 #> 2 98 103 0.9992482 1 #> 3 202 95 0.9987941 1 #> 4 296 103 0.9992482 1 #> 5 400 95 0.9987941 1 #> 6 494 103 0.9992482 1 #> 7 598 95 0.9987941 1 #> 8 692 103 0.9992482 1 #> 9 796 95 0.9987941 1 #> 10 895 95 0.9987941 1
## Segment pattern from x. Now assume a grid of potential pattern duratios ## contains true pattern duration out <- segmentPattern( x = x, x.fs = 100, template = true.pattern, pattern.dur.seq = c(0.9, 0.95, 1, 1.03, 1.1), similarity.measure = "cor", compute.template.idx = TRUE) out
#> tau_i T_i sim_i template_i #> 1 1 100 1 1 #> 2 100 100 1 1 #> 3 199 100 1 1 #> 4 298 100 1 1 #> 5 397 100 1 1 #> 6 496 100 1 1 #> 7 595 100 1 1 #> 8 694 100 1 1 #> 9 793 100 1 1 #> 10 892 100 1 1
## Example 2: Simulate a time-series `x`. Assume that ## - `x` is collected at a frequency of 100 Hz, ## - there are two shapes of pattern present within `x`, ## - patterns have various duration, ## - there is no noise in the collected data. true.pattern.1 <- cos(seq(0, 2 * pi, length.out = 200)) true.pattern.2 <- true.pattern.1 true.pattern.2[70:130] <- 2 * true.pattern.2[min(70:130)] + abs(true.pattern.2[70:130]) x <- numeric() for (vl in seq(70, 130, by = 10)){ true.pattern.1.s <- approx( seq(0, 1, length.out = 200), true.pattern.1, xout = seq(0, 1, length.out = vl))$y true.pattern.2.s <- approx( seq(0, 1, length.out = 200), true.pattern.2, xout = seq(0, 1, length.out = vl))$y x <- c(x, true.pattern.1.s[-1], true.pattern.2.s[-1]) if (vl == 70) x <- c(true.pattern.1.s[1], x) } ## Segment pattern from x. Use a `template` object consisting of both ## true patterns used in `x` simulation. out <- segmentPattern( x = x, x.fs = 100, template = list(true.pattern.1, true.pattern.2), pattern.dur.seq = 60:130 * 0.01, similarity.measure = "cor", compute.template.idx = TRUE) out
#> tau_i T_i sim_i template_i #> 1 1 70 1 1 #> 2 70 70 1 2 #> 3 139 80 1 1 #> 4 218 80 1 2 #> 5 297 90 1 1 #> 6 386 90 1 2 #> 7 475 100 1 1 #> 8 574 100 1 2 #> 9 673 110 1 1 #> 10 782 110 1 2 #> 11 891 120 1 1 #> 12 1010 120 1 2 #> 13 1129 130 1 1 #> 14 1258 130 1 2
## Example 3: Simulate a time-series `x`. Assume that ## - `x` is collected at a frequency of 100 Hz, ## - there are two shapes of a pattern present within `x`, ## - patterns have various duration, ## - there is noise in the collected data. set.seed(1) x <- x + rnorm(length(x), sd = 0.5) ## Segment pattern from x. out <- segmentPattern( x = x, x.fs = 100, template = list(true.pattern.1, true.pattern.2), pattern.dur.seq = 60:130 * 0.01, similarity.measure = "cor", compute.template.idx = TRUE) out
#> tau_i T_i sim_i template_i #> 1 4 63 0.8615665 1 #> 2 76 62 0.7351057 2 #> 3 137 84 0.7708233 1 #> 4 220 76 0.6768561 2 #> 5 295 92 0.8507212 1 #> 6 391 83 0.7404364 2 #> 7 473 106 0.8300020 1 #> 8 582 87 0.6515298 2 #> 9 668 118 0.8047385 1 #> 10 785 106 0.6958617 2 #> 11 890 123 0.7927484 1 #> 12 1015 113 0.6789908 1 #> 13 1129 130 0.7938183 1 #> 14 1265 123 0.7686607 2
## Segment pattern from x. Use `x.adept.ma.W` to define a length of a smoothing ## window to smooth `x` for similarity matrix computation. out <- segmentPattern( x = x, x.fs = 100, template = list(true.pattern.1, true.pattern.2), pattern.dur.seq = 60:130 * 0.01, similarity.measure = "cor", x.adept.ma.W = 0.1, compute.template.idx = TRUE) out
#> tau_i T_i sim_i template_i #> 1 4 63 0.9931174 1 #> 2 75 63 0.9683646 2 #> 3 139 79 0.9683054 1 #> 4 217 80 0.9748040 2 #> 5 296 94 0.9802473 1 #> 6 391 82 0.9462213 2 #> 7 472 106 0.9855837 1 #> 8 578 93 0.9608881 2 #> 9 670 115 0.9887225 1 #> 10 784 107 0.9562694 2 #> 11 896 113 0.9734575 1 #> 12 1008 127 0.9703118 1 #> 13 1134 116 0.9606235 1 #> 14 1266 122 0.9593345 2
## Segment pattern from x. Use `x.adept.ma.W` to define a length of a smoothing ## window to smooth `x` for similarity matrix computation. Employ a fine-tuning ## procedure for stride identification. out <- segmentPattern( x = x, x.fs = 100, template = list(true.pattern.1, true.pattern.2), pattern.dur.seq = 60:130 * 0.01, similarity.measure = "cor", x.adept.ma.W = 0.1, finetune = "maxima", finetune.maxima.nbh.W = 0.3, compute.template.idx = TRUE) out
#> tau_i T_i sim_i template_i #> 1 4 67 0.9931174 1 #> 2 70 78 0.9683646 2 #> 3 147 60 0.9060130 2 #> 4 206 98 0.9785617 2 #> 5 303 78 0.9802473 1 #> 6 380 107 0.9666486 2 #> 7 486 93 0.9855837 1 #> 8 578 93 0.9608881 2 #> 9 670 105 0.9887225 1 #> 10 774 113 0.9786236 2 #> 11 893 128 0.9734575 1 #> 12 1020 112 0.9453138 1 #> 13 1131 123 0.9661650 1 #> 14 1253 125 0.9593345 2
## Segment pattern from x. Employ a fine-tuning procedure for stride ## identification. Smooth `x` for both similarity matrix computation ## (set `x.adept.ma.W = 0.1`) and for fine-tune peak detection procedure ## (set `finetune.maxima.nbh.W = 0.3`). out <- segmentPattern( x = x, x.fs = 100, template = list(true.pattern.1, true.pattern.2), pattern.dur.seq = 60:130 * 0.01, similarity.measure = "cor", x.adept.ma.W = 0.1, finetune = "maxima", finetune.maxima.nbh.W = 0.3, compute.template.idx = TRUE) out
#> tau_i T_i sim_i template_i #> 1 4 67 0.9931174 1 #> 2 70 78 0.9683646 2 #> 3 147 60 0.9060130 2 #> 4 206 98 0.9785617 2 #> 5 303 78 0.9802473 1 #> 6 380 107 0.9666486 2 #> 7 486 93 0.9855837 1 #> 8 578 93 0.9608881 2 #> 9 670 105 0.9887225 1 #> 10 774 113 0.9786236 2 #> 11 893 128 0.9734575 1 #> 12 1020 112 0.9453138 1 #> 13 1131 123 0.9661650 1 #> 14 1253 125 0.9593345 2