def test_precomputed_cost(method, n_timestamps_1, n_timestamps_2): rng = np.random.RandomState(42) x = rng.randn(n_timestamps_1) y = rng.randn(n_timestamps_2) squared_cost = (x[:, None] - y[None, :])**2 dtw_desired = dtw(x, y, method=method, dist="square") dtw_desired **= 2 dtw_precomputed = dtw(method=method, dist="precomputed", precomputed_cost=squared_cost) np.testing.assert_allclose(dtw_desired, dtw_precomputed)
def test_actual_results_dtw_diff_lengths(params, res_desired): """Test that the actual results are the expected ones.""" (dtw_actual, cost_mat_actual, acc_cost_mat_actual, path_actual) = dtw(x_long, y, **params_return, **params) np.testing.assert_allclose(dtw_actual, res_desired[0]) np.testing.assert_allclose(cost_mat_actual, res_desired[1]) np.testing.assert_allclose(acc_cost_mat_actual, res_desired[2]) np.testing.assert_allclose(path_actual, res_desired[3])
def dtw_search_sakoechiba(dictionary_image_features="test", index_chosen_image="test", window_size=0.1): """ This is a function that searches for a single word inside the manuscript and returns the dtw distance between the selected word and all other words in the sample. !!! DTW is not implemented here !!! :param dictionary_image_features: [dictionary] takes a dictionary as an input, that contains the filename of each image as key, and stores a list with numerical values inside that key. :param window_size: [float] sets the "sakoechiba" margins, which restrain the calculation space and speed up the dtw process. This is a FLOAT which represents a fraction of the length of the "search" vectors. Here we have 5 features, so a window size of 0.2 would mean that having a dtw distance of 1 would already cause the dtw path to hit the margin (not cancel tho, just hit afaik). :param index_chosen_image: [int] or [string] the index or key (filename) of the image we want to search for in our manuscript. :return: [list] [dictionary] returns a list with the distances of all words in the manuscript to the word of interest. also returns a dictionary containing the paths of the dtw with the corresponding key(filename) """ if dictionary_image_features == "test": # use made up data if none provided dictionary_image_features = {"im1": [9, 0, 4, 0.3, 0.5], # bullshit data i made up, not good for testing "im2": [9, 1, 8, 0.2, 0.3], # bullshit data i made up, not good for testing "im3": [9, 2, 6, 0.1, 0.4]} # bullshit data i made up, not good for testing # Create some helper-data-structures for iterating though dataset list_image_keys = [key for key in dictionary_image_features.keys()] list_image_indices = list(range(len(dictionary_image_features))) zip_image_indices_and_keys = zip(list_image_keys, list_image_indices) # initialization - choose image we want to search for in provided data if index_chosen_image == "test": # choose random image if none provided index_chosen_image = random.randint(0, len(dictionary_image_features) - 1) # random init print("chosen image is:", list_image_keys[index_chosen_image], "with index =", index_chosen_image) # rand-debug elif type(index_chosen_image) == type("This is a string"): index_chosen_image = list_image_keys.index(index_chosen_image) # Start DTW with Sakoechiba-Method x = dictionary_image_features[list_image_keys[index_chosen_image]] # vector we want to compare dictionary_image_dtw_paths = {} # just init, will be written while iterating list_image_dtw_values = [] # just init, will be written while iterating # iterate through all images in data - also with itself as a control for image_key, image_indices in zip_image_indices_and_keys: y = dictionary_image_features[image_key] dtw_sakoechiba, path_sakoechiba = dtw(x, y, dist='square', method='sakoechiba', options={'window_size': window_size}, return_path=True) dictionary_image_dtw_paths[image_key] = path_sakoechiba list_image_dtw_values.append(dtw_sakoechiba) return list_image_dtw_values, dictionary_image_dtw_paths
def _dtw_error(y, y_hat, score_window=10): """Compute dtw error between predicted and expected values. The computed error is calculated as the dynamic time warping distance between predicted and expected values with a smoothing factor. Args: y (ndarray): Ground truth. y_hat (ndarray): Predicted values. score_window (int): Optional. Size of the window over which the scores are calculated. If not given, 10 is used. Returns: ndarray: An array of dtw error. """ length_dtw = (score_window // 2) * 2 + 1 half_length_dtw = length_dtw // 2 # add padding y_pad = np.pad(y, (half_length_dtw, half_length_dtw), 'constant', constant_values=(0, 0)) y_hat_pad = np.pad(y_hat, (half_length_dtw, half_length_dtw), 'constant', constant_values=(0, 0)) i = 0 similarity_dtw = list() while i < len(y) - length_dtw: true_data = y_pad[i:i + length_dtw] true_data = true_data.flatten() pred_data = y_hat_pad[i:i + length_dtw] pred_data = pred_data.flatten() dist = dtw(true_data, pred_data) similarity_dtw.append(dist) i += 1 errors = ([0] * half_length_dtw + similarity_dtw + [0] * (len(y) - len(similarity_dtw) - half_length_dtw)) return errors
def test_dtw_methods(method, dtw_func): value_specific = dtw_func(x, y) value_generic = dtw(x, y, method=method) assert value_specific == value_generic
def test_precomputed_cost_error(method): error_match = "cannot be used with a precomputed cost" with pytest.raises(ValueError, match=error_match): dtw(method=method, dist="precomputed")
def test_parameter_check_dtw(params, err_msg): """Test parameter validation.""" with pytest.raises(ValueError, match=re.escape(err_msg)): dtw(x, y, **params)
X_test, y_test = fulltest[:, 1:], fulltest[:, 0] #Feature extraction DTW ''' DTW_train= cdist_dtw(X_train,X_train) DTW_test = cdist_dtw(X_test, X_train) ''' # Dynamic Time Warping: classic DTW_Classic_test = [] DTW_Classic_train = [] for i in range(len(X_test)): for j in range(len(X_train)): dtw_classic, path_classic = dtw(X_test[i], X_train[j], dist='square', method='classic', return_path=True) DTW_Classic_test.append(dtw_classic) for i in range(len(X_train)): for j in range(len(X_train)): dtw_classic, path_classic = dtw(X_train[i], X_train[j], dist='square', method='classic', return_path=True) DTW_Classic_train.append(dtw_classic) DTW_Classic_train = np.array(DTW_Classic_train) DTW_Classic_train.resize(y_train.shape[0],
# Parameters X, _, _, _ = load_gunpoint(return_X_y=True) x, y = X[0], X[1] # To compare time series of different lengths, we remove some observations mask = np.ones(x.size) mask[::5] = 0 y = y[mask.astype(bool)] n_timestamps_1, n_timestamps_2 = x.size, y.size plt.figure(figsize=(10, 8)) timestamps_1 = np.arange(n_timestamps_1 + 1) timestamps_2 = np.arange(n_timestamps_2 + 1) # Dynamic Time Warping: classic dtw_classic, path_classic = dtw(x, y, dist='square', method='classic', return_path=True) matrix_classic = np.zeros((n_timestamps_2 + 1, n_timestamps_1 + 1)) matrix_classic[tuple(path_classic)[::-1]] = 1. 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',
y_test = label[-int(test_size * len(label)):] clf = LogisticRegression(penalty='l2', C=1, fit_intercept=False, solver='liblinear', multi_class='ovr') #Feature extraction DTW # Dynamic Time Warping: classic DTW_Classic_test = [] DTW_Classic_train = [] for i in range(len(X_test)): for j in range(len(X_train)): dtw_classic, path_classic = dtw(X_test[i], X_train[j], dist='square', method='classic', return_path=True) DTW_Classic_test.append(dtw_classic) for i in range(len(X_train)): for j in range(len(X_train)): dtw_classic, path_classic = dtw(X_train[i], X_train[j], dist='square', method='classic', return_path=True) DTW_Classic_train.append(dtw_classic) DTW_Classic_train = np.array(DTW_Classic_train) DTW_Classic_train.resize(y_train.shape[0],