如何在R中的多个时间序列上应用dtw算法?

时间:2017-08-29 18:11:49

标签: r dplyr dtw

问题

我有不同车辆速度的时间序列。我的最终目标是根据不同车辆的速度相似性对不同车辆进行分组。所以,我基本上需要产生一个距离矩阵,其中每个单元格包含一对车速时间序列之间的距离。我想使用动态时间扭曲(dtw)作为距离度量。因此,我想在每对速度时间序列上应用dtw。

数据

以下是一些样本数据,每辆车只包含8个观测值,只有3辆车:

> dput(c)
structure(list(file.ID2 = c("Cars_03", "Cars_03", "Cars_03", 
"Cars_03", "Cars_03", "Cars_03", "Cars_03", "Cars_03", "Cars_04", 
"Cars_04", "Cars_04", "Cars_04", "Cars_04", "Cars_04", "Cars_04", 
"Cars_04", "Cars_05", "Cars_05", "Cars_05", "Cars_05", "Cars_05", 
"Cars_05", "Cars_05", "Cars_05"), speed.kph.ED = c(129.3802848, 
129.4022304, 129.424176, 129.4461216, 129.4680672, 129.47904, 
129.5009856, 129.5229312, 127.8770112, 127.8221472, 127.7672832, 
127.7124192, 127.6575552, 127.6026912, 127.5478272, 127.4929632, 
134.1095616, 134.1205344, 134.1315072, 134.1534528, 134.1644256, 
134.1753984, 134.1863712, 134.197344)), row.names = c(NA, -24L
), class = c("tbl_df", "tbl", "data.frame"), .Names = c("file.ID2", 
"speed.kph.ED")) 

我尝试了什么

我可以找到一对dtw::dtw()距离如下:

    library(dplyr) 
    library(dtw) 
    c3 <- c %>% filter(file.ID2=="Cars_03")  
    c4 <- c %>% filter(file.ID2=="Cars_04")  
    query <- c4$speed.kph.ED  
    reference <- c3$speed.kph.ED  
    dtw_results <- dtw(x = query, y = reference)
    dtw_results$distance  

但我的问题是:有没有办法在每对之间自动找到dtw()$distance并生成距离矩阵?在这个例子中,它意味着这些对:

Cars_03 - Cars_03
Cars_03 - Cars_04
Cars_03 - Cars_05
Cars_04 - Cars_03
Cars_04 - Cars_04
Cars_04 - Cars_05
等等

我知道for loop是一种方法。但由于dtw本身需要大量RAM,for loop可能会进一步减慢进程。任何替代品?如果这是一个愚蠢的问题,我很抱歉,但我很擅长使用dtw

2 个答案:

答案 0 :(得分:1)

以下作品

file.ID2

将数据框拆分为列表
ds <- split(df, df$file.ID2)

使用expand.grid制作名称的所有组合,file.ID2和您的值

Names <- expand.grid(unique(df$file.ID2), unique(df$file.ID2))
Values <- expand.grid(ds, ds)

purrr:map_dbl遍历Values的所有行组合并返回双精度矢量

library(dtw)
library(purrr)
Dist <- map_dbl(1:nrow(Values), ~dtw(x = Values[.x,]$Var1[[1]]$speed.kph.ED, y = Values[.x,]$Var2[[1]]$speed.kph.ED)$distance)

绑定名称的答案

library(dplyr)
ans <- Names %>% 
          mutate(distance = Dist)

<强>输出

     Var1    Var2 distance
1 Cars_03 Cars_03  0.00000
2 Cars_04 Cars_03 25.66538
3 Cars_05 Cars_03 69.72117
4 Cars_03 Cars_04 25.66538
5 Cars_04 Cars_04  0.00000
6 Cars_05 Cars_04 96.00103
7 Cars_03 Cars_05 69.72117
8 Cars_04 Cars_05 96.00103
9 Cars_05 Cars_05  0.00000

答案 1 :(得分:0)

如果使用递归实现,DTW只会占用大量内存。如果使用迭代版本实现,则只需要O(1)空间开销。

使用变形窗口宽度约束,您可以在几分钟(最多)内构建一个300长度1,000个时间序列的矩阵。 如果您有更多数据,请尝试使用TADPOLE。

我建议你阅读本教程

http://www.cs.unm.edu/~mueen/DTW.pdf