Skip to content

Kernelized mean change (CostRbf)#

Bases: BaseCost

Kernel cost function (rbf kernel).

Source code in ruptures/costs/costrbf.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
69
70
71
72
73
74
75
76
77
78
79
80
81
class CostRbf(BaseCost):
    r"""Kernel cost function (rbf kernel)."""

    model = "rbf"

    def __init__(self, gamma=None):
        """Initialize the object."""
        self.min_size = 1
        self.gamma = gamma
        self._gram = None

    @property
    def gram(self):
        """Generate the gram matrix (lazy loading).

        Only access this function after a `.fit()` (otherwise
        `self.signal` is not defined).
        """
        if self._gram is None:
            K = pdist(self.signal, metric="sqeuclidean")
            if self.gamma is None:
                self.gamma = 1.0
                # median heuristics
                K_median = np.median(K)
                if K_median != 0:
                    # K /= K_median
                    self.gamma = 1 / K_median
            K *= self.gamma
            np.clip(K, 1e-2, 1e2, K)  # clipping to avoid exponential under/overflow
            self._gram = np.exp(squareform(-K))
        return self._gram

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

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

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

        # If gamma is none, set it using the median heuristic.
        # This heuristic involves computing the gram matrix which is lazy loaded
        # so we simply access the `.gram` property
        if self.gamma is None:
            self.gram

        return self

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

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

        Returns:
            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

gram property #

Generate the gram matrix (lazy loading).

Only access this function after a .fit() (otherwise self.signal is not defined).

__init__(gamma=None) #

Initialize the object.

Source code in ruptures/costs/costrbf.py
14
15
16
17
18
def __init__(self, gamma=None):
    """Initialize the object."""
    self.min_size = 1
    self.gamma = gamma
    self._gram = None

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:

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/costrbf.py
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
def error(self, start, end) -> float:
    """Return the approximation cost on the segment [start:end].

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

    Returns:
        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) #

Sets parameters of the instance.

Parameters:

Name Type Description Default
signal array

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

required

Returns:

Type Description
CostRbf

self

Source code in ruptures/costs/costrbf.py
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
def fit(self, signal) -> "CostRbf":
    """Sets parameters of the instance.

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

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

    # If gamma is none, set it using the median heuristic.
    # This heuristic involves computing the gram matrix which is lazy loaded
    # so we simply access the `.gram` property
    if self.gamma is None:
        self.gram

    return self