def test_lower_bounds_inequalities(): """Test that the expected inequalities are verified.""" # Toy dataset rng = np.random.RandomState(42) n_samples_train, n_samples_test, n_timestamps = 20, 30, 60 window_size = 0.1 X_train = rng.randn(n_samples_train, n_timestamps) X_test = rng.randn(n_samples_test, n_timestamps) # DTW X_dtw = pairwise_distances(X_test, X_train, dtw) region = sakoe_chiba_band(n_timestamps, window_size=window_size) X_dtw_window = pairwise_distances(X_test, X_train, dtw_sakoechiba, window_size=window_size) # Lower bounds lb_yi = lower_bound_yi(X_train, X_test) lb_kim = lower_bound_kim(X_train, X_test) lb_keogh = lower_bound_keogh(X_train, X_test, region) lb_improved = lower_bound_improved(X_train, X_test, region) # Sanity check EPS = 1e-8 np.testing.assert_array_less(lb_yi, X_dtw + EPS) np.testing.assert_array_less(lb_kim, X_dtw + EPS) np.testing.assert_array_less(lb_keogh, X_dtw_window + EPS) np.testing.assert_array_less(lb_improved, X_dtw_window + EPS) np.testing.assert_array_less(lb_keogh, lb_improved + EPS)
def plot_sakoe_chiba(n_timestamps_1, n_timestamps_2, window_size=0.5, ax=None): """Plot the Sakoe-Chiba band.""" region = sakoe_chiba_band(n_timestamps_1, n_timestamps_2, window_size) scale, horizontal_shift, vertical_shift = \ _check_sakoe_chiba_params(n_timestamps_1, n_timestamps_2, window_size) mask = np.zeros((n_timestamps_2, n_timestamps_1)) for i, (j, k) in enumerate(region.T): mask[j:k, i] = 1. plt.imshow(mask, origin='lower', cmap='Wistia', vmin=0, vmax=1) sz = max(n_timestamps_1, n_timestamps_2) x = np.arange(-1, sz + 1) lower_bound = scale * (x - horizontal_shift) - vertical_shift upper_bound = scale * (x + horizontal_shift) + vertical_shift plt.plot(x, lower_bound, 'b', lw=2) plt.plot(x, upper_bound, 'g', lw=2) diag = (n_timestamps_2 - 1) / (n_timestamps_1 - 1) * np.arange(-1, sz + 1) plt.plot(x, diag, 'black', lw=1) for i in range(n_timestamps_1): for j in range(n_timestamps_2): plt.plot(i, j, 'o', color='green', ms=1) ax.set_xticks(np.arange(-.5, n_timestamps_1, 1), minor=True) ax.set_yticks(np.arange(-.5, n_timestamps_2, 1), minor=True) plt.grid(which='minor', color='b', linestyle='--', linewidth=1) plt.xticks(np.arange(0, n_timestamps_1, 2)) plt.yticks(np.arange(0, n_timestamps_2, 2)) plt.xlim((-0.5, n_timestamps_1 - 0.5)) plt.ylim((-0.5, n_timestamps_2 - 0.5))
def test_actual_results_sakoe_chiba_band(params, arr_desired): """Test that the actual results are the expected ones.""" arr_actual = sakoe_chiba_band(**params) np.testing.assert_allclose(arr_actual, arr_desired, atol=1e-5, rtol=0.)
def test_parameter_check_sakoe_chiba_band(params, error, err_msg): """Test parameter validation.""" with pytest.raises(error, match=re.escape(err_msg)): sakoe_chiba_band(**params)
plt.subplot(2, 2, 1) plt.pcolor(timestamps_1, timestamps_2, matrix_classic, edgecolors='k', cmap='Greys') plt.xlabel('x', fontsize=12) plt.ylabel('y', fontsize=12) plt.title("{0}\nDTW(x, y) = {1:.2f}".format('classic', dtw_classic), fontsize=14) # Dynamic Time Warping: sakoechiba window_size = 0.1 dtw_sakoechiba, path_sakoechiba = dtw( x, y, dist='square', method='sakoechiba', options={'window_size': window_size}, return_path=True ) band = sakoe_chiba_band(n_timestamps_1, n_timestamps_2, window_size=window_size) matrix_sakoechiba = np.zeros((n_timestamps_1 + 1, n_timestamps_2 + 1)) for i in range(n_timestamps_1): matrix_sakoechiba[i, np.arange(*band[:, i])] = 0.5 matrix_sakoechiba[tuple(path_sakoechiba)] = 1. plt.subplot(2, 2, 2) plt.pcolor(timestamps_1, timestamps_2, matrix_sakoechiba.T, edgecolors='k', cmap='Greys') plt.xlabel('x', fontsize=12) plt.ylabel('y', fontsize=12) plt.title("{0}\nDTW(x, y) = {1:.2f}".format('sakoechiba', dtw_sakoechiba), fontsize=14) # Dynamic Time Warping: itakura slope = 1.2
matrix_classic, edgecolors='k', cmap='Greys') plt.xlabel('x', fontsize=20, labelpad=-10) plt.ylabel('y', fontsize=20, labelpad=-10) plt.title("{0}\nDTW(x, y) = {1:.2f}".format('classic', dtw_classic), fontsize=16) # Dynamic Time Warping: sakoechiba dtw_sakoechiba, path_sakoechiba = dtw(x, y, dist='square', method='sakoechiba', options={'window_size': 5}, return_path=True) band = sakoe_chiba_band(n_timestamps, window_size=5) matrix_sakoechiba = np.zeros((n_timestamps + 1, n_timestamps + 1)) for i in range(n_timestamps): matrix_sakoechiba[i, np.arange(*band[:, i])] = 0.5 matrix_sakoechiba[tuple(path_sakoechiba)[::-1]] = 1. plt.subplot(2, 2, 2) plt.pcolor(timestamps, timestamps, matrix_sakoechiba, edgecolors='k', cmap='Greys') plt.xlabel('x', fontsize=20, labelpad=-10) plt.ylabel('y', fontsize=20, labelpad=-10) plt.title("{0}\nDTW(x, y) = {1:.2f}".format('sakoechiba', dtw_sakoechiba), fontsize=16)