R 高效的多维动态时间扭曲实现

R 高效的多维动态时间扭曲实现,r,performance,image-processing,distance,R,Performance,Image Processing,Distance,以下是文献如何解释如何计算两个时间序列的多维动态时间扭曲: library(dtw) x<- cbind(1:10,1) y<- cbind(11:15,2) cxdist <-dist(x,y,method="euclidean") dtw(cxdist)$distance 库(dtw) X处理密集型计算时,始终要考虑 Rcpp 包。如果您想更快地获得欧几里德距离的距离矩阵,可以实现相应的Rcpp功能: library(Rcpp) library(inline)

以下是文献如何解释如何计算两个时间序列的多维动态时间扭曲:

 library(dtw)
 x<- cbind(1:10,1)
 y<- cbind(11:15,2)
 cxdist <-dist(x,y,method="euclidean")
 dtw(cxdist)$distance
库(dtw)

X

处理密集型计算时,始终要考虑<代码> Rcpp <代码>包。如果您想更快地获得欧几里德距离的距离矩阵,可以实现相应的

Rcpp
功能:

library(Rcpp)
library(inline)

# Rcpp function for euclidean distance
fastdist <- cxxfunction(signature(x="matrix", y="matrix"), plugin="Rcpp",
body='
  Rcpp::NumericMatrix dx(x);
  Rcpp::NumericMatrix dy(y);

  const int N = dx.nrow();
  const int M = dy.nrow();

  Rcpp::NumericMatrix res(N, M);

  for(int i=0; i<N; i++){
    for(int j=0; j<M; j++){
      res(i,j) = sqrt(sum((dx(i,_)-dy(j,_))*(dx(i,_)-dy(j,_))));
    }
  }

  return res;
')
现在我们可以转向文学的例子

library(dtw)

# EXAMPLE 1
x<- cbind(1:10,1)
y<- cbind(11:15,2)
# Check results
all.equal(fast.dist(x,y), dist(x,y,method="euclidean"), check.attributes=F)
# [1] "target is matrix, current is crossdist"
all.equal(fast.dist(x,y), matrix(dist(x,y,method="euclidean"), ncol=nrow(y)))
# [1] TRUE
我不能完全确定您的数据结构,但在任何情况下,您都可以根据需要准备变量

比较和基准:

library(rbenchmark)

all.equal(fast.dist(var1,var2), matrix(dist(var1,var2), ncol=N))
# [1] TRUE
benchmark(fast.dist(var1,var2), dist(var1,var2), order="relative")[,1:4]
#                    test replications elapsed relative
# 1 fast.dist(var1, var2)          100   0.081    1.000
# 2      dist(var1, var2)          100   0.246    3.037
fast。在这种情况下,dist
大约是
dist
的3倍。然而,当
N
增长时,相对速度将下降

还要注意的是,正如注释中提到的,
dtw
可以自己计算距离矩阵。然而,预先计算距离矩阵更有效。请参见下面的快速测试:

cxdist <- fast.dist(var1,var2)
benchmark(dtw(cxdist)$distance, dtw(var1,var2)$distance, order="relative")[,1:4]
#                       test replications elapsed relative
# 1     dtw(cxdist)$distance          100   0.476    1.000
# 2 dtw(var1, var2)$distance          100   0.736    1.546

cxdist那么,您需要高效地计算var1和var2之间的距离矩阵(欧几里德矩阵)(两者都是相同长度的三维数组)?例如,在
x之间,您能否澄清
inDf
与第一个示例的关系?是
var1t1
x
,还是
var2t1
y
,然后在其他两个时间段内再次重复?您是否希望在每个时间段计算每对变量的
dtw
距离?这些东西和图像有什么关系?除此之外,它看起来像是
dtw
计算
dist
本身,因此您不需要执行该步骤。第一个示例和第二个示例之间的差异是每个样本测量的变量数量。在第一种情况下,x和y都是同一唯一变量随时间变化的时间序列。在第二种情况下,每个x都有两个变量,两个时间序列。希望在第二个示例中更清楚,
cxdist
的维度是什么?据我所知,它们应该是
10x10
。因此,我们正在计算
var1
中10个三维点与
var2
中10个三维点之间的成对距离。这是正确的还是错误的?谢谢,回答得很好,很清楚。我不知道Rcpp。如果我想把这个应用到很多样品上,你有没有办法加快这个过程?@WAF谢谢。注意:如果您只对
$distance
感兴趣,则可以将
distance.only=T
传递到
dtw()
——这样可以提高速度。至于在大量样本上应用代码。似乎
dtw()
只使用一个内核,因此在多核系统或集群上批量运行处理可能会带来好处。请查看
foreach
软件包。
# EXAMPLE 2
set.seed(1234)
N <- 100
inDf <- data.frame(matrix(rnorm(6*N), ncol = 6))
colnames(inDf) <- c('var1t1','var2t1','var1t2','var2t2','var1t3','var2t3')

# Extracting variables
var1 <- inDf[,c("var1t1","var1t2","var1t3")]
var2 <- inDf[,c("var2t1","var2t2","var2t3")]
library(rbenchmark)

all.equal(fast.dist(var1,var2), matrix(dist(var1,var2), ncol=N))
# [1] TRUE
benchmark(fast.dist(var1,var2), dist(var1,var2), order="relative")[,1:4]
#                    test replications elapsed relative
# 1 fast.dist(var1, var2)          100   0.081    1.000
# 2      dist(var1, var2)          100   0.246    3.037
cxdist <- fast.dist(var1,var2)
benchmark(dtw(cxdist)$distance, dtw(var1,var2)$distance, order="relative")[,1:4]
#                       test replications elapsed relative
# 1     dtw(cxdist)$distance          100   0.476    1.000
# 2 dtw(var1, var2)$distance          100   0.736    1.546