def predict(self, pen): """Return the optimal breakpoints. Must be called after the fit method. The breakpoints are associated with the signal passed to [`fit()`][ruptures.detection.pelt.Pelt.fit]. Args: pen (float): penalty value (>0) Raises: BadSegmentationParameters: in case of impossible segmentation configuration Returns: list: sorted list of breakpoints """ # raise an exception in case of impossible segmentation configuration if not sanity_check( n_samples=self.cost.signal.shape[0], n_bkps=1, jump=self.jump, min_size=self.min_size, ): raise BadSegmentationParameters partition = self._seg(pen) bkps = sorted(e for s, e in partition.keys()) return bkps
def predict(self, n_bkps=None, pen=None, epsilon=None): """Return the optimal breakpoints. Must be called after the fit method. The breakpoints are associated with the signal passed to [`fit()`][ruptures.detection.binseg.Binseg.fit]. The stopping rule depends on the parameter passed to the function. Args: n_bkps (int): number of breakpoints to find before stopping. pen (float): penalty value (>0) epsilon (float): reconstruction budget (>0) Raises: AssertionError: if none of `n_bkps`, `pen`, `epsilon` is set. BadSegmentationParameters: in case of impossible segmentation configuration Returns: list: sorted list of breakpoints """ msg = "Give a parameter." assert any(param is not None for param in (n_bkps, pen, epsilon)), msg # raise an exception in case of impossible segmentation configuration if not sanity_check( n_samples=self.cost.signal.shape[0], n_bkps=1, jump=self.jump, min_size=self.min_size, ): raise BadSegmentationParameters partition = self._seg(n_bkps=n_bkps, pen=pen, epsilon=epsilon) bkps = sorted(e for s, e in partition.keys()) return bkps
def predict(self, n_bkps): """Return the optimal breakpoints. Must be called after the fit method. The breakpoints are associated with the signal passed to [`fit()`][ruptures.detection.dynp.Dynp.fit]. Args: n_bkps (int): number of breakpoints. Raises: BadSegmentationParameters: in case of impossible segmentation configuration Returns: list: sorted list of breakpoints """ # raise an exception in case of impossible segmentation configuration if not sanity_check( n_samples=self.cost.signal.shape[0], n_bkps=n_bkps, jump=self.jump, min_size=self.min_size, ): raise BadSegmentationParameters partition = self.seg(0, self.n_samples, n_bkps) bkps = sorted(e for s, e in partition.keys()) return bkps
def _seg(self, start, end, n_bkps): """Recurrence to find the optimal partition of signal[start:end]. This method is to be memoized and then used. Args: start (int): start of the segment (inclusive) end (int): end of the segment (exclusive) n_bkps (int): number of breakpoints Returns: dict: {(start, end): cost value, ...} """ jump, min_size = self.jump, self.min_size if n_bkps == 0: cost = self.cost.error(start, end) return {(start, end): cost} elif n_bkps > 0: # Let's fill the list of admissible last breakpoints multiple_of_jump = (k for k in range(start, end) if k % jump == 0) admissible_bkps = list() for bkp in multiple_of_jump: n_samples = bkp - start # first check if left subproblem is possible if sanity_check(n_samples, n_bkps, jump, min_size): # second check if the right subproblem has enough points if end - bkp >= min_size: admissible_bkps.append(bkp) assert len( admissible_bkps) > 0, "No admissible last breakpoints found.\ start, end: ({},{}), n_bkps: {}.".format(start, end, n_bkps) # Compute the subproblems sub_problems = list() for bkp in admissible_bkps: left_partition = self.seg(start, bkp, n_bkps - 1) right_partition = self.seg(bkp, end, 0) tmp_partition = dict(left_partition) tmp_partition[(bkp, end)] = right_partition[(bkp, end)] sub_problems.append(tmp_partition) #---------NEW PART----------from here #number of cost functions used in an ensemble number_of_costs = len(tmp_partition[(bkp, end)]) #ensembling array = np.array([[ sum([i[cost_number] for i in sub_pr.values()]) for cost_number in range(number_of_costs) ] for sub_pr in sub_problems]) # Find the optimal partition return sub_problems[np.argmin( selected_aggregation(self.ensembling)(array))]
def _seg(self, start, end, n_bkps): """Recurrence to find the optimal partition of signal[start:end]. This method is to be memoized and then used. Args: start (int): start of the segment (inclusive) end (int): end of the segment (exclusive) n_bkps (int): number of breakpoints Returns: dict: {(start, end): cost value, ...} """ jump, min_size = self.jump, self.min_size if n_bkps == 0: cost = self.cost.error(start, end) return {(start, end): cost} elif n_bkps > 0: # Let's fill the list of admissible last breakpoints multiple_of_jump = (k for k in range(start, end) if k % jump == 0) admissible_bkps = list() for bkp in multiple_of_jump: n_samples = bkp - start # first check if left subproblem is possible if sanity_check( n_samples=n_samples, n_bkps=n_bkps - 1, jump=jump, min_size=min_size, ): # second check if the right subproblem has enough points if end - bkp >= min_size: admissible_bkps.append(bkp) assert (len(admissible_bkps) > 0), "No admissible last breakpoints found.\ start, end: ({},{}), n_bkps: {}.".format(start, end, n_bkps) # Compute the subproblems sub_problems = list() for bkp in admissible_bkps: left_partition = self.seg(start, bkp, n_bkps - 1) right_partition = self.seg(bkp, end, 0) tmp_partition = dict(left_partition) tmp_partition[(bkp, end)] = right_partition[(bkp, end)] sub_problems.append(tmp_partition) # Find the optimal partition return min(sub_problems, key=lambda d: sum(d.values()))
def predict(self, n_bkps=None, pen=None): """Return the optimal breakpoints. Must be called after the fit method. The breakpoints are associated with the signal passed to [`fit()`][ruptures.detection.kernelcpd.KernelCPD.fit]. Args: n_bkps (int, optional): Number of change points. Defaults to None. pen (float, optional): penalty value (>0). Defaults to None. Not considered if n_bkps is not None. Raises: AssertionError: if `pen` or `n_bkps` is not strictly positive. BadSegmentationParameters: in case of impossible segmentation configuration Returns: list[int]: sorted list of breakpoints """ # raise an exception in case of impossible segmentation configuration if not sanity_check( n_samples=self.cost.signal.shape[0], n_bkps=1 if n_bkps is None else n_bkps, jump=self.jump, min_size=self.min_size, ): raise BadSegmentationParameters # dynamic programming if the user passed a number change points if n_bkps is not None: n_bkps = int(n_bkps) err_msg = "The number of changes must be positive: {}".format( n_bkps) assert n_bkps > 0, err_msg # if we have already computed it, return it without computations. if n_bkps in self.segmentations_dict: return self.segmentations_dict[n_bkps] # otherwise, call the C function if self.kernel_name == "linear": path_matrix_flat = ekcpd_L2(self.cost.signal, n_bkps, self.min_size) elif self.kernel_name == "rbf": path_matrix_flat = ekcpd_Gaussian(self.cost.signal, n_bkps, self.min_size, self.cost.gamma) elif self.kernel_name == "cosine": path_matrix_flat = ekcpd_cosine(self.cost.signal, n_bkps, self.min_size) # from the path matrix, get all segmentation for k=1,...,n_bkps changes for k in range(1, n_bkps + 1): self.segmentations_dict[k] = from_path_matrix_to_bkps_list( path_matrix_flat, k, self.n_samples, n_bkps, self.jump) return self.segmentations_dict[n_bkps] # Call pelt if the user passed a penalty if pen is not None: assert pen > 0, "The penalty must be positive: {}".format(pen) if self.kernel_name == "linear": path_matrix = ekcpd_pelt_L2(self.cost.signal, pen, self.min_size) elif self.kernel_name == "rbf": path_matrix = ekcpd_pelt_Gaussian(self.cost.signal, pen, self.min_size, self.cost.gamma) elif self.kernel_name == "cosine": path_matrix = ekcpd_pelt_cosine(self.cost.signal, pen, self.min_size) my_bkps = list() ind = self.n_samples while ind > 0: my_bkps.append(ind) ind = path_matrix[ind] return my_bkps[::-1]