Exemple #1
0
    def test_multi_grid(self):
        size = 2**5 - 1  # test odd size
        freq = 1 / size
        input1 = np.cos(np.arange(size) * 2 * np.pi * freq)
        input2 = np.sin(np.arange(size) * 2 * np.pi *
                        freq) + 0.1 * np.random.random(size=size)

        series1 = _series_from_values(input1)
        series2 = _series_from_values(input2)

        exact_distance = dtw.dtw(series1, series2,
                                 multi_grid_radius=-1).distance()
        approx_distance = dtw.dtw(series1, series2,
                                  multi_grid_radius=1).distance()

        self.assertAlmostEqual(exact_distance, approx_distance, 3)
Exemple #2
0
    def test_sakoe_chiba_window(self):
        window = 2
        alignment = dtw.dtw(self.series1,
                            self.series2,
                            window=dtw.SakoeChiba(window_size=2))
        path = alignment.path()

        for i, j in path:
            self.assertGreaterEqual(window, abs(i - j))
Exemple #3
0
    def test_multivariate(self):
        n = 2

        values1 = np.repeat(self.series1.univariate_values(), n)
        values2 = np.repeat(self.series2.univariate_values(), n)

        values1 = values1.reshape((-1, n))
        values2 = values2.reshape((-1, n))

        multi_series1 = TimeSeries.from_values(values1)
        multi_series2 = TimeSeries.from_values(values2)

        radius = 2

        alignment_uni = dtw.dtw(self.series1,
                                self.series2,
                                multi_grid_radius=radius)
        alignment_multi = dtw.dtw(multi_series1,
                                  multi_series2,
                                  multi_grid_radius=radius)

        self.assertTrue(np.all(alignment_uni.path() == alignment_multi.path()))
Exemple #4
0
    def test_itakura_window(self):
        n = 6
        m = 5
        slope = 1.5

        window = dtw.Itakura(max_slope=slope)
        window.init_size(n, m)

        cells = list(window)
        self.assertEqual(
            cells,
            [
                (1, 1),
                (1, 2),
                (2, 1),
                (2, 2),
                (2, 3),
                (3, 1),
                (3, 2),
                (3, 3),
                (3, 4),
                (4, 2),
                (4, 3),
                (4, 4),
                (5, 2),
                (5, 3),
                (5, 4),
                (5, 5),
                (6, 4),
                (6, 5),
            ],
        )

        sizes = [(10, 43), (543, 45), (34, 11)]

        for n, m in sizes:
            slope = m / n + 1

            series1 = tg.sine_timeseries(length=n,
                                         value_frequency=1 / n,
                                         value_phase=0)
            series2 = tg.sine_timeseries(length=m,
                                         value_frequency=1 / m,
                                         value_phase=np.pi / 4)

            dist = dtw.dtw(series1, series2,
                           window=dtw.Itakura(slope)).mean_distance()
            self.assertGreater(1, dist)
Exemple #5
0
    def test_shift(self):
        input1 = [
            1,
            1,
            1,
            1,
            1.2,
            1.4,
            1.2,
            1,
            1,
            1,
            1,
            1,
            1,
            1.2,
            1.4,
            1.6,
            1.8,
            1.6,
            1.4,
            1.2,
            1,
            1,
        ]
        input2 = [1] + input1[:-1]

        expected_path = ([(0, 0)] + list(
            (i - 1, i) for i in range(1, len(input1))) +
                         [(len(input1) - 1, len(input2) - 1)])

        series1 = _series_from_values(input1)
        series2 = _series_from_values(input2)

        exact_alignment = dtw.dtw(series1, series2, multi_grid_radius=-1)

        self.assertEqual(
            exact_alignment.distance(),
            0,
            "Minimum cost between two shifted series should be 0",
        )
        self.assertTrue(np.array_equal(exact_alignment.path(), expected_path),
                        "Incorrect path")
Exemple #6
0
    def test_warp(self):
        # Support different time dimension names
        xa1 = self.series1.data_array().rename({"time": "time1"})
        xa2 = self.series2.data_array().rename({"time": "time2"})

        static_covs = pd.DataFrame([[0.0, 1.0]], columns=["st1", "st2"])
        series1 = TimeSeries.from_xarray(xa1).with_static_covariates(
            static_covs)
        series2 = TimeSeries.from_xarray(xa2).with_static_covariates(
            static_covs)

        alignment = dtw.dtw(series1, series2)

        warped1, warped2 = alignment.warped()
        self.assertAlmostEqual(alignment.mean_distance(),
                               mae(warped1, warped2))
        assert warped1.static_covariates.equals(series1.static_covariates)
        assert warped2.static_covariates.equals(series2.static_covariates)
        """
Exemple #7
0
def _dtw_multigrid():
    dtw.dtw(series1, series2, multi_grid_radius=1).distance()
Exemple #8
0
def _dtw_exact():
    dtw.dtw(series1, series2, multi_grid_radius=-1).distance()
Exemple #9
0
 def test_plot(self):
     align = dtw.dtw(self.series2, self.series1)
     align.plot()
     align.plot_alignment()
Exemple #10
0
    def test_nans(self):
        with self.assertRaises(ValueError):
            series1 = _series_from_values([np.nan, 0, 1, 2, 3])
            series2 = _series_from_values([0, 1, 2, 3, 4])

            dtw.dtw(series1, series2)
Exemple #11
0
def dtw_metric(
    actual_series: Union[TimeSeries, Sequence[TimeSeries]],
    pred_series: Union[TimeSeries, Sequence[TimeSeries]],
    metric: Callable[
        [
            Union[TimeSeries, Sequence[TimeSeries]],
            Union[TimeSeries, Sequence[TimeSeries]],
        ],
        Union[float, np.ndarray],
    ] = mae,
    *,
    reduction: Callable[[np.ndarray], float] = np.mean,
    inter_reduction: Callable[[np.ndarray], Union[float, np.ndarray]] = lambda x: x,
    n_jobs: int = 1,
    verbose: bool = False,
    **kwargs
) -> float:
    """
    Applies Dynamic Time Warping to actual_series and pred_series before passing it into the metric.
    Enables comparison between series of different lengths, phases and time indices.

    Defaults to using mae as a metric.

    See darts.dataprocessing.dtw.dtw for more supported parameters.

    Parameters
    ----------
    actual_series
        The (sequence of) actual series.
    pred_series
        The (sequence of) predicted series.
    metric
        The selected metric with signature '[[TimeSeries, TimeSeries], float]' to use. Default: `mae`.
    reduction
        Function taking as input a ``np.ndarray`` and returning a scalar value. This function is used to aggregate
        the metrics of different components in case of multivariate ``TimeSeries`` instances.
    inter_reduction
        Function taking as input a ``np.ndarray`` and returning either a scalar value or a ``np.ndarray``.
        This function can be used to aggregate the metrics of different series in case the metric is evaluated on a
        ``Sequence[TimeSeries]``. Defaults to the identity function, which returns the pairwise metrics for each pair
        of ``TimeSeries`` received in input. Example: ``inter_reduction=np.mean``, will return the average of the
        pairwise metrics.
    n_jobs
        The number of jobs to run in parallel. Parallel jobs are created only when a ``Sequence[TimeSeries]`` is
        passed as input, parallelising operations regarding different ``TimeSeries``. Defaults to `1`
        (sequential). Setting the parameter to `-1` means using all the available processors.
    verbose
        Optionally, whether to print operations progress

    Returns
    -------
    float
        Result of calling metric(warped_series1, warped_series2)
    """

    alignment = dtw.dtw(actual_series, pred_series, **kwargs)
    if metric == mae and "distance" not in kwargs:
        return alignment.mean_distance()

    warped_actual_series, warped_pred_series = alignment.warped()

    return metric(warped_actual_series, warped_pred_series)