2013-05-08 69 views
0

我在Python中創建了一個動態時間扭曲的簡單實現,但覺得這有點破解。我實現了遞歸關係(或者至少我相信我做到了!),但是因爲在我的情況下,這涉及到一個numpy數組,所以我不得不將它包裝在一個類中以使得memoisation可以工作(numpy數組是可變的)。在Python中動態時間扭曲,如何記憶一個可變矩陣

維基鏈接到大田:Dynamic Time Warping

下面是代碼:

class DynamicTimeWarp(object): 
    def __init__(self, seq1, seq2): 
    self.warp_matrix = self.time_warp_matrix(seq1, seq2) 

    def time_warp_matrix(self, seq1, seq2): 
    output = np.zeros((len(seq1), len(seq2)), dtype=np.float64) 
    for i in range(len(seq1)): 
     for j in range(len(seq2)): 
     output[i][j] = np.sqrt((seq1[i] - seq2[j]) ** 2) 
    return output· 

    @lru_cache(maxsize=100) 
    def warp_path(self, i=None, j=None): 
    if (i is None) and (j is None): 
     i, j = self.warp_matrix.shape 
     i -= 1 
     j -= 1 

    distance = self.warp_matrix[i, j] 
    path = ((i, j),) 
    if i == j == 0: 
     return distance, path 

    potential = [] 

    if i - 1 >= 0: 
     potential.append(self.warp_path(i-1, j)) 

    if j - 1 >= 0: 
     potential.append(self.warp_path(i, j-1)) 

    if (j - 1 >= 0) and (i - 1 >=0): 
     potential.append(self.warp_path(i-1, j-1)) 

    if len(potential) > 0: 
     new_dist, new_path = min(potential, key = lambda x: x[0]) 
     distance   += new_dist 
     path    = new_path + path 

    return distance, path 

我的問題:

  1. 這是大田的有效實施,我相信嗎?

  2. 有沒有更好的方法來做到這一點,同時保持使用numpy陣列 和遞推關係?

  3. 如果我最終不得不使用一個類,然後希望重用一個類的實例(通過傳遞它的新序列並重新計算warp_matrix),我將不得不將某種虛擬值傳遞爲一個warp_path函數的參數 - 否則我想象lru_cache將錯誤地返回值。有沒有更好的解決這個問題的方法?

回答

1

雖然很容易將DTW想象成遞歸函數,但可以實現迭代版本。迭代版本通常快10到30倍。

eamonn