编辑/ Levenshtein与时间戳的距离 - 具有相似(最小)成本的不同路径

时间:2011-08-11 14:14:04

标签: algorithm levenshtein-distance

我使用Edit/Levenstein distance来衡量单词之间的相似性。与最简单的实现不同,我的字母有时间戳,比如样本数N = 0,1,2,...

我面临的问题是,我可以沿着成本矩阵获得不同的路径,这些路径以相同(最小)的成本结束,并且这些不同的路径与不同的目标字符串相关联。例如,如果我测量源字符串aa和目标字符串bab之间的距离,并且我假设源字符串在时间戳N = 0上开始,那么我有2条路径具有相同的成本2(一个加法和一个替换):

  1. 在N = -1时添加b,保留第一个a,然后用a替换第二个b
  2. a替换第一个b,保留第二个a,并在N = 2时添加b
  3. 在时间线上对齐,这两个结果是不同的:

    Time:    ... -1 0 1 2 3 ...
    Source:         a a
    Target1:      b a b
    Target2:        b a b
    

    我需要知道何时发生这种情况,因此我可以根据某些标准在两个可能的目标之间进行选择。除了跟踪路径并跟踪导致最低成本的所有可能路径之外,还有其他方法吗?

    我考虑使用Dynamic Time Warp代替,因为时间线首先是模型的一部分,但似乎因为成本矩阵被初始化为无穷大(除了[0,0] ])),第一步将始终将目标的第一帧与源的第一帧匹配,从而使目标从与源相同的时间戳开始。无论如何,使用DTW我仍然需要跟踪所有路径,导致相同的最低成本。

    欢迎任何帮助或见解。

1 个答案:

答案 0 :(得分:2)

更多地考虑你的问题,似乎有点误解了DTW或Levensthein。两种算法都试图挤压和扩展序列以使它们彼此匹配。因此,在DTW案例中,您的示例将具有以下解决方案:

Solution1:
  a a
 /| |
b a b

Solution2:
a a
| |\
b a b

Solution3:
a a
|\|\
b a b

如果您查看这些解决方案,您会注意到所有这些解决方案的成本都是2,即在所有情况下,2 b被分配为。这些示例的含义是,在第一个序列中,与第二个序列相比,一个时间戳被压缩在一起。例如,在第一个解决方案中,b a的前两个时间戳被压缩以形成对应于第二个序列的第一个a的单个时间步长(第二个序列正好相反,第三个解决方案更复杂)。 DTW旨在处理在某些部分以不同速度播放的序列,因此是“时间扭曲”类比。

如果您的时间步骤确实是固定的,并且您只需要对齐它们,而不考虑任何实际的扭曲,您可以尝试所有对齐并计算成本。

这样的事情(假设str2是较短的一个):

for i = 0 to length( str1 ) - length( str2 ) do
  shift str2 by i to the left
  calculate number of different position between shifted str2 and str1
done
return i with lowest difference

假设您既需要移位也需要变形(可能已添加到开头并且时间步长可能不匹配),则考虑后续DTW。为此你只需要放松边界条件。

假设您将字符串索引为1而不是零,则可以像这样编写DTW:

diff( x, y ) = 1 if str1 at x != str2 at x 
               0 otherwise

cost( 0, 0 ) = 0;
cost( 0, * ) = infinity;
cost( *, 0 ) = infinity;
cost( x, y ) = min( cost( x-1, y-1 ), cost( x-1, y ), cost( y, y-1) ) + diff( x, y )

DTW-Cost然后是cost( length( str1 ), length( str2 ) ),您的路径可以从那里追溯。对于子序列DTW,您只需更改此内容:

diff( x, y ) = 1 if str1 at x != str2 at x 
               0 otherwise

cost( 0, 0 ) = 0;
cost( 0, * ) = 0;
cost( *, 0 ) = infinity; // yes this is correct and needed
cost( x, y ) = min( cost( x-1, y-1 ), cost( x-1, y ), cost( y, y-1) ) + diff( x, y )

然后,您选择的DTW费用为min( cost( x, length( str2 ) ),并从argmin( cost( x, length( str2 ) )追溯。这假设您知道一个字符串是另一个字符串的子字符串。如果你不知道这一点并且两者可能只有一个共同的扭曲中间,你将不得不进行部分匹配,据我所知仍然是一个开放的研究课题,因为需要选择一个“最优”的概念,这个概念不能清楚定义。