Skip to content

Mahalanobis-type change (CostMl)#

Bases: BaseCost

Mahalanobis-type cost function.

Source code in ruptures/costs/costml.py
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
class CostMl(BaseCost):
    r"""Mahalanobis-type cost function."""

    model = "mahalanobis"

    def __init__(self, metric=None):
        """Create a new instance.

        Args:
            metric (ndarray, optional): PSD matrix that defines a
                Mahalanobis-type pseudo distance. If None, defaults to the
                Mahalanobis matrix. Shape (n_features, n_features).
        """
        self.metric = metric  # metric matrix
        self.has_custom_metric = False if self.metric is None else True
        self.gram = None
        self.min_size = 2

    def fit(self, signal) -> "CostMl":
        """Set parameters of the instance.

        Args:
            signal (array): signal. Shape (n_samples,) or
                (n_samples, n_features)

        Returns:
            self
        """
        s_ = signal.reshape(-1, 1) if signal.ndim == 1 else signal

        # fit a Mahalanobis metric if self.has_custom_metric is False
        if self.has_custom_metric is False:
            covar = np.cov(s_.T)
            self.metric = inv(covar.reshape(1, 1) if covar.size == 1 else covar)

        self.gram = s_.dot(self.metric).dot(s_.T)
        self.signal = s_

        return self

    def error(self, start, end):
        """Return the approximation cost on the segment [start:end].

        Args:
            start (int): start of the segment
            end (int): end of the segment

        Returns:
            float: segment cost

        Raises:
            NotEnoughPoints: when the segment is too short (less than
                ``'min_size'`` samples).
        """
        if end - start < self.min_size:
            raise NotEnoughPoints
        sub_gram = self.gram[start:end, start:end]
        val = np.diagonal(sub_gram).sum()
        val -= sub_gram.sum() / (end - start)
        return val

__init__(metric=None) #

Create a new instance.

Parameters:

Name Type Description Default
metric ndarray

PSD matrix that defines a Mahalanobis-type pseudo distance. If None, defaults to the Mahalanobis matrix. Shape (n_features, n_features).

None
Source code in ruptures/costs/costml.py
14
15
16
17
18
19
20
21
22
23
24
25
def __init__(self, metric=None):
    """Create a new instance.

    Args:
        metric (ndarray, optional): PSD matrix that defines a
            Mahalanobis-type pseudo distance. If None, defaults to the
            Mahalanobis matrix. Shape (n_features, n_features).
    """
    self.metric = metric  # metric matrix
    self.has_custom_metric = False if self.metric is None else True
    self.gram = None
    self.min_size = 2

error(start, end) #

Return the approximation cost on the segment [start:end].

Parameters:

Name Type Description Default
start int

start of the segment

required
end int

end of the segment

required

Returns:

Name Type Description
float

segment cost

Raises:

Type Description
NotEnoughPoints

when the segment is too short (less than 'min_size' samples).

Source code in ruptures/costs/costml.py
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
def error(self, start, end):
    """Return the approximation cost on the segment [start:end].

    Args:
        start (int): start of the segment
        end (int): end of the segment

    Returns:
        float: segment cost

    Raises:
        NotEnoughPoints: when the segment is too short (less than
            ``'min_size'`` samples).
    """
    if end - start < self.min_size:
        raise NotEnoughPoints
    sub_gram = self.gram[start:end, start:end]
    val = np.diagonal(sub_gram).sum()
    val -= sub_gram.sum() / (end - start)
    return val

fit(signal) #

Set parameters of the instance.

Parameters:

Name Type Description Default
signal array

signal. Shape (n_samples,) or (n_samples, n_features)

required

Returns:

Type Description
CostMl

self

Source code in ruptures/costs/costml.py
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
def fit(self, signal) -> "CostMl":
    """Set parameters of the instance.

    Args:
        signal (array): signal. Shape (n_samples,) or
            (n_samples, n_features)

    Returns:
        self
    """
    s_ = signal.reshape(-1, 1) if signal.ndim == 1 else signal

    # fit a Mahalanobis metric if self.has_custom_metric is False
    if self.has_custom_metric is False:
        covar = np.cov(s_.T)
        self.metric = inv(covar.reshape(1, 1) if covar.size == 1 else covar)

    self.gram = s_.dot(self.metric).dot(s_.T)
    self.signal = s_

    return self