def mutate_sequence(sequence, prob, mutation_scale=0.2): """ Randomly mutates each point in the sequence x to get a random value from the range [x(1-mutation_scale),(1+mutation_scale)x] The probability prob determines the probability of this mutation occuring. :param sequence: :param prob: :param mutation_scale: :return: """ sequence = np.asarray(sequence) length = no_nans_len(sequence) prob_adjusted = prob for i in range(length): mutate = np.random.choice([True, False], p=[prob_adjusted, 1 - prob_adjusted]) if mutate: x = sequence[i] mutation_ratio = np.random.uniform(1-mutation_scale, 1+mutation_scale) sequence[i] = x * mutation_ratio return sequence
def mutate_sequence(sequence, prob, mutation_scale=0.2): """ Randomly mutates each point in the sequence x to get a random value from the range [x(1-mutation_scale),(1+mutation_scale)x] The probability prob determines the probability of this mutation occuring. :param sequence: :param prob: :param mutation_scale: :return: """ sequence = np.asarray(sequence) length = no_nans_len(sequence) prob_adjusted = prob for i in range(length): mutate = np.random.choice([True, False], p=[prob_adjusted, 1 - prob_adjusted]) if mutate: x = sequence[i] mutation_ratio = np.random.uniform(1 - mutation_scale, 1 + mutation_scale) sequence[i] = x * mutation_ratio return sequence
def randomly_warp_sequence(sequence, max_number_of_extensions=10, max_number_of_shrinks=10, max_extend_length=4, max_shrink_length=4, may_reverse=True, mutation_prob=0.01): sequence = np.copy(sequence) n_ext = 0 n_shrinks = 0 number_of_extensions = random.randint(0, max_number_of_extensions) number_of_shrinks = random.randint(0, max_number_of_shrinks) while n_ext < number_of_extensions or n_shrinks < number_of_shrinks: if mutation_prob > 0: mutate_sequence(sequence, mutation_prob) length = no_nans_len(sequence) available_actions = [] if n_ext < number_of_extensions: available_actions.append('extend') if n_shrinks < number_of_shrinks: available_actions.append('shrink') if len(available_actions) == 1: action = available_actions[0] else: action = random.choice(available_actions) if action == 'extend': pos = random.randint( 0, length - 1 ) # minus one as the second number is inclusive in random.randint k = random.randint(2, max_extend_length) sequence = extend_point(sequence, pos, k) n_ext += 1 else: pos = random.randint(0, length - 1) k = random.randint(2, max_shrink_length) sequence = shrink_to_a_single_point(sequence, pos, k) n_shrinks += 1 if may_reverse: flip = random.choice([True, False]) if flip: sequence = reverse_sequence(sequence) return sequence
def extend_point(sequence, pos, extended_length): sequence = np.asarray(sequence) length = no_nans_len(sequence) new_seq = [] for i, v in enumerate(sequence): if i >= length: break if i == pos: new_seq.extend([v] * extended_length) else: new_seq.append(v) return np.asarray(new_seq)
def dtw_projection(sequence, base_sequence, dtw_function=dtw_std, path=None): """ Projects given sequence onto a base time series using Dynamic Time Warping :param sequence: the sequence that will be projected onto base_sequence :param base_sequence: base sequence to project onto :param dtw_function: DTW function to compute the path if it is set to None :param path: the pre-computed DTW warping path between sequence and base sequence. :return: new time series of length base containing x projected on it """ base_sequence = np.asarray(base_sequence) sequence = np.asarray(sequence) if not path: distance, cost, path = dtw_function(sequence, base_sequence, dist_only=False) path_other, path_base = path current_sums = np.zeros(base_sequence.shape) current_counts = np.zeros(base_sequence.shape) nnl = no_nans_len(base_sequence) try: filler = [np.nan] * base_sequence.shape[1] except IndexError: filler = np.nan for i in range(nnl, len(base_sequence)): current_sums[i] = filler current_counts[i] = filler for mapped_i, i in zip(path_base, path_other): # Go through the path and sum all points that map to the base location i together current_sums[mapped_i] += sequence[i] current_counts[mapped_i] += 1 current_average = current_sums / current_counts # Append NaNs as needed nans_count = len(base_sequence) - len(base_sequence) if nans_count: current_average = np.concatenate( (current_average, [[np.nan] * base_sequence.shape[-1]] * (nans_count))) return current_average
def dtw_projection(sequence, base_sequence, dtw_function=dtw_std, path=None): """ Projects given sequence onto a base time series using Dynamic Time Warping :param sequence: the sequence that will be projected onto base_sequence :param base_sequence: base sequence to project onto :param dtw_function: DTW function to compute the path if it is set to None :param path: the pre-computed DTW warping path between sequence and base sequence. :return: new time series of length base containing x projected on it """ base_sequence = np.asarray(base_sequence) sequence = np.asarray(sequence) if not path: distance, cost, path = dtw_function(sequence, base_sequence, dist_only=False) path_other, path_base = path current_sums = np.zeros(base_sequence.shape) current_counts = np.zeros(base_sequence.shape) nnl = no_nans_len(base_sequence) try: filler = [np.nan] * base_sequence.shape[1] except IndexError: filler = np.nan for i in range(nnl, len(base_sequence)): current_sums[i] = filler current_counts[i] = filler for mapped_i, i in zip(path_base, path_other): # Go through the path and sum all points that map to the base location i together current_sums[mapped_i] += sequence[i] current_counts[mapped_i] += 1 current_average = current_sums / current_counts # Append NaNs as needed nans_count = len(base_sequence) - len(base_sequence) if nans_count: current_average = np.concatenate((current_average, [[np.nan] * base_sequence.shape[-1]] * (nans_count))) return current_average
def randomly_warp_sequence(sequence, max_number_of_extensions=10, max_number_of_shrinks=10, max_extend_length=4, max_shrink_length=4, may_reverse=True, mutation_prob=0.01): sequence = np.copy(sequence) n_ext = 0 n_shrinks = 0 number_of_extensions = random.randint(0, max_number_of_extensions) number_of_shrinks = random.randint(0, max_number_of_shrinks) while n_ext < number_of_extensions or n_shrinks < number_of_shrinks: if mutation_prob > 0: mutate_sequence(sequence, mutation_prob) length = no_nans_len(sequence) available_actions = [] if n_ext < number_of_extensions: available_actions.append('extend') if n_shrinks < number_of_shrinks: available_actions.append('shrink') if len(available_actions) == 1: action = available_actions[0] else: action = random.choice(available_actions) if action == 'extend': pos = random.randint(0, length - 1) # minus one as the second number is inclusive in random.randint k = random.randint(2, max_extend_length) sequence = extend_point(sequence, pos, k) n_ext += 1 else: pos = random.randint(0, length - 1) k = random.randint(2, max_shrink_length) sequence = shrink_to_a_single_point(sequence, pos, k) n_shrinks += 1 if may_reverse: flip = random.choice([True, False]) if flip: sequence = reverse_sequence(sequence) return sequence
def shrink_to_a_single_point(sequence, pos, shrink_subset_len): sequence = np.asarray(sequence) length = no_nans_len(sequence) new_seq = [] shrinked_part = [] for i, v in enumerate(sequence): if i >= length: break if pos <= i < pos + shrink_subset_len: shrinked_part.append(v) elif i == pos + shrink_subset_len: new_seq.append(np.mean(shrinked_part, axis=0)) shrinked_part = [] new_seq.append(v) else: new_seq.append(v) if shrinked_part: new_seq.append(np.mean(shrinked_part, axis=0)) return np.asarray(new_seq)