[英]Efficient multidimensional dynamic time warping implementation
以下是文獻如何解釋如何計算兩個時間序列的多維動態時間扭曲:
library(dtw)
x<- cbind(1:10,1)
y<- cbind(11:15,2)
cxdist <-dist(x,y,method="euclidean")
dtw(cxdist)$distance
實際上,它首先計算交叉距離矩陣,然后將其用作dtw函數中的輸入。
我想在具有相當大的圖像的圖像分類中使用多維動態時間扭曲。 圖像值存儲在數據框中,如下所示:
inDf <- data.frame(matrix(rnorm(60), ncol = 6))
colnames(inDf) <- c('var1t1','var2t1','var1t2','var2t2','var1t3','var2t3')
在此示例中,有兩個變量(var1和var2)被觀察三次。
問題是如何在計算強度方面盡可能多地獲得dtw距離矩陣?
以下是一些想法: - 迭代輸入圖像矩陣的每個值,將矢量重新整形為矩陣,以便能夠計算交叉距離,然后計算dtw距離並將其存儲在專用矩陣中。 這當然是計算密集度最高的解決方案
在處理密集計算時,總是考慮使用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;
')
它使用Rcpp
語法sugar
,以使代碼更緊湊和可讀。 但是,有時最好使用包裝函數來檢查類型,強制等等。沒有必要 - 你可以直接調用fastdist
。 但是,無論如何,包裝器看起來像這樣:
# Wrapper R function
fast.dist <- function(x, y){
stopifnot(class(x) %in% c("data.frame","matrix") &
class(y) %in% c("data.frame","matrix") &
ncol(x)==ncol(y))
fastdist(as.matrix(x), as.matrix(y))
}
現在我們可以轉向文學例子。
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
注意, dist
返回class crossdist
結果。 因此,為了進行比較,它應該被強制轉換為matrix
。
現在你的主要問題 - 我們首先生成數據:
# 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
在這種情況下, 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
此外,如果你只對$distance
感興趣,你可以將distance.only=T
傳遞給dtw()
- 它可以提高速度。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.