-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathREADME.Rmd
165 lines (130 loc) · 7.13 KB
/
README.Rmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
---
output:
github_document:
fig_width: 3
---
<!-- [![Coverage status](https://codecov.io/gh/martakarass/adept/branch/master/graph/badge.svg)](https://codecov.io/github/martakarass/adept?branch=master) -->
[![CRAN status](https://www.r-pkg.org/badges/version/adept)](https://CRAN.R-project.org/package=adept)
[![](https://cranlogs.r-pkg.org/badges/grand-total/adept)](https://cran.r-project.org/package=adept)
[![](https://cranlogs.r-pkg.org/badges/last-month/adept)](https://cran.r-project.org/package=adept)
[![R build status](https://github.com/martakarass/adept/workflows/R-CMD-check/badge.svg)](https://github.com/martakarass/adept/actions)
[![Codecov test coverage](https://codecov.io/gh/martakarass/adept/branch/master/graph/badge.svg)](https://codecov.io/gh/martakarass/adept?branch=master)
```{r setup, include = FALSE}
knitr::opts_chunk$set(
collapse = TRUE,
comment = "#>",
fig.path = "man/figures/README-",
out.width = "100%"
)
```
### Overview
The `adept` package implements ADaptive Empirical Pattern Transformation (ADEPT) method^[Karas, M., Straczkiewicz, M., Fadel, W., Harezlak, J., Crainiceanu, C., Urbanek, J.K. *Adaptive empirical pattern transformation (ADEPT) with application to walking stride segmentation*, Submitted to *Biostatistics*, 2018.] for pattern segmentation from a time-series. ADEPT is optimized to perform fast, accurate walking strides segmentation from high-density data collected with a wearable accelerometer during walking. The method was validated using data collected with sensors worn at left wrist, left hip and both ankles.
### Installation
Install `adept` package from GitHub.
```{r, eval = FALSE}
# install.packages("devtools")
devtools::install_github("martakarass/adept")
```
### Example 1
We simulate a time-series `x`. We assume that `x` is collected at a frequency of 100 Hz, there is one shape of a pattern within `x`, each pattern lasts 1 second, and there is no noise in collected data.
```{r, fig.width=10, fig.height=4}
true.pattern <- cos(seq(0, 2 * pi, length.out = 100))
x <- c(true.pattern[1], replicate(10, true.pattern[-1]))
par(mfrow = c(1,2), cex = 1)
plot(true.pattern, type = "l", xlab = "", ylab = "", main = "Pattern")
plot(x, type = "l", xlab = "", ylab = "", main = "Time-series x")
```
We segment pattern from data. We assume that a perfect template is available. We use a grid of potential pattern durations of {0.9, 0.95, 1.03, 1.1} seconds; the grid is imperfect in a sense it does not contain the duration of the true pattern used in `x` simulation.
```{r, fig.width=2.5, fig.height=2.3}
library(adept)
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)
```
The segmentation result is a data frame, where 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 template and `x`,
* `template_i` - index of a template best matched to a time-series `x` (here: one template was used, hence all `template_i`'s equal 1).
We then assume a grid of potential pattern durations which contains the duration of the true pattern used in data simulation. A perfect match (`sim_i = 1`) between a time-series `x` and a template is obtained.
```{r, fig.width=2.5, fig.height=2.3}
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)
```
### Example 2
We simulate a time-series `x`. We assume that `x` is collected at a frequency of 100 Hz, there are two shapes of a pattern within `x`, patterns have various duration, and there is no noise in collected data.
Then, we generate `x2` as a noisy version of `x`.
```{r, fig.width=10, fig.height=4}
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)
}
set.seed(1)
x2 <- x + rnorm(length(x), sd = 0.5)
par(mfrow = c(1,2), cex = 1)
plot(true.pattern.1, type = "l", xlab = "", ylab = "", main = "Pattern 1")
plot(true.pattern.2, type = "l", xlab = "", ylab = "", main = "Pattern 2")
par(mfrow = c(1,1), cex = 1)
plot(x, type = "l", xlab = "", ylab = "", main = "Time-series x")
plot(x2, type = "l", xlab = "", ylab = "", main = "Time-series x2")
```
We segment `x`. We assume a perfect grid of potential pattern duration, {0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3} seconds.
```{r}
segmentPattern(
x = x,
x.fs = 100,
template = list(true.pattern.1, true.pattern.2),
pattern.dur.seq = seq(0.7, 1.3, by = 0.1),
similarity.measure = "cor",
compute.template.idx = TRUE)
```
We segment `x2`.
```{r}
segmentPattern(
x = x2,
x.fs = 100,
template = list(true.pattern.1, true.pattern.2),
pattern.dur.seq = seq(0.7, 1.3, by = 0.1),
similarity.measure = "cor",
compute.template.idx = TRUE)
```
We now use `x.adept.ma.W` argument to smooth `x2` before similarity matrix computation in the segmentation procedure (see `?segmentPattern` for details). We also assume a more dense grid of potential pattern duration. We observe that `sim_i` values obtained are higher than in the previous segmentation case.
```{r, fig.width=10, fig.height=4}
par(mfrow = c(1,1), cex = 1)
plot(windowSmooth(x = x2, x.fs = 100, W = 0.1),
type = "l", xlab = "", ylab = "", main = "Time-series x2 smoothed")
segmentPattern(
x = x2,
x.fs = 100,
template = list(true.pattern.1, true.pattern.2),
pattern.dur.seq = 70:130 * 0.01,
similarity.measure = "cor",
x.adept.ma.W = 0.1,
compute.template.idx = TRUE)
```
### Vignettes
Vignettes are available to better demonstrate package methods usage.
1. Vignette [Introduction to adept package](https://martakarass.github.io/adept/articles/adept-intro.html) introduces ADEPT algorithm and demonstrates the usage of `segmentPattern` function which implements ADEPT approach. Here, we focus on examples with simulated data.
2. Vignette [Walking strides segmentation with adept](https://martakarass.github.io/adept/articles/adept-strides-segmentation.html) provides an example of segmentation of walking strides (two consecutive steps) in sub-second accelerometry data with `adept` package. The exemplary dataset is a part of the `adeptdata` package. We demonstrate that ADEPT can be used to perform automatic and precise walking stride segmentation from data collected during a combination of running, walking and resting exercises. We introduce how to segment data:
1. with the use of stride templates that were pre-computed based on data from an external study (attached to `adeptdata` package),
2. by deriving new stride templates in a semi-manual manner.
### References