Подумав еще немного о вашей проблеме, немного кажется, что есть недопонимание DTW или Levensthein.Оба алгоритма пытаются сжать и расширить последовательности, чтобы сопоставить их друг с другом.Таким образом, в случае DTW ваш пример будет иметь следующие решения:
Solution1:
a a
/| |
b a b
Solution2:
a a
| |\
b a b
Solution3:
a a
|\|\
b a b
Если вы посмотрите на эти решения, вы заметите, что все они имеют стоимость 2, т.е. во всех случаях 2 b
s назначается как.Эти примеры означают, что в первой последовательности одна временная метка сжимается вместе по сравнению со второй последовательностью.Например, в первом решении первые две временные метки 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.Для этого вам просто нужно ослабить граничные условия.
Предполагая, что вы индексируете свою строку в единицу вместо нуля, вы можете написать 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 ) )
.Это предполагает, что вы знаете, что одна строка является подстрокой другой.Если вы этого не знаете, и у обоих может быть только общая искривленная середина, вам придется выполнить частичное сопоставление, которое, насколько я знаю, все еще остается открытой темой исследования, поскольку нужно выбрать понятие «оптимальности», которое не может четкобыть определенным.