Subsequence

Subsequence search is to match the best occurance of a short time serise in a longer series.

DTW subsequence alignment

Given a series:

Subsequence series

And a query:

Subsequence query

We can find the best occurence(s) as follows:

from dtaidistance.subsequence.dtw import subsequence_alignment
from dtaidistance import dtw_visualisation as dtwvis

sa = subsequence_alignment(query, series)
match = sa.best_match()
startidx, endidx = match.segment
dtwvis.plot_warpingpaths(query, series, sa.warping_paths(), match.path, figure=fig)

The resultig match is

Subsequence matching

If we compare the best match with the query we see they are similar. The best match is only a little bit compressed.

Subsequence best match

If you want to find all matches (or the k best):

fig, ax = dtwvis.plot_warpingpaths(query, series, sa.warping_paths(), path=-1)
for kmatch in sa.kbest_matches(9):
    dtwvis.plot_warpingpaths_addpath(ax, kmatch.path)
Subsequence alignment k-best matches

DTW Local Concurrences

In some case we are not interested in searching for a query but to find any or all subsequences that are similar between two series. This is used for example to identify that parts of two series are similar but not necessarily the entire series. Or when comparing a series to itself it produces subsequences (of arbitrary length) that frequenty reappear in the series.

For example below, we can see that one heartbeat in ECG is a common pattern. Sometimes a sequence a few heartbeats is similar to another sequence of heartbeats.

lc = local_concurrences(series, None, estimate_settings=0.7)  # second is None to compare to self
# The parameters tau, delta, delta_factor are estimated based on series
paths = []
for match in lc.kbest_matches(k=100, minlen=20, buffer=10):
    paths.append(match.path)
fig, ax = dtwvis.plot_warpingpaths(series, series, lc.wp, path=-1)
for path in paths:
    dtwvis.plot_warpingpaths_addpath(ax, path)
Local concurrences