Ejemplo n.º 1
0
def test_lower_bounding() -> None:
    """Test for various lower bounding methods."""
    no_bounding = LowerBounding.NO_BOUNDING
    no_bounding_int = LowerBounding(1)
    assert (
        no_bounding_int is no_bounding
    ), "No bounding must be able to be constructed using the enum and a int value."

    sakoe_chiba = LowerBounding.SAKOE_CHIBA
    sakoe_chiba_int = LowerBounding(2)
    assert (
        sakoe_chiba_int is sakoe_chiba
    ), "Sakoe chiba must be able to be constructed using the enum and a int value."

    itakura_parallelogram = LowerBounding.ITAKURA_PARALLELOGRAM
    itakura_parallelogram_int = LowerBounding(3)
    assert itakura_parallelogram_int is itakura_parallelogram, (
        "Itakura parallelogram must be able to be constructed using the enum and a int "
        "value"
    )

    _validate_bounding(
        x=create_test_distance_numpy(10, 10),
        y=create_test_distance_numpy(10, 10, random_state=2),
    )
Ejemplo n.º 2
0
def _test_incorrect_parameters(distance_func: Callable):
    """Test to ensure correct errors thrown."""
    numpy_x = create_test_distance_numpy(10, 10)
    numpy_y = create_test_distance_numpy(10, 10, random_state=2)

    numpy_4d = np.array([[[[1, 2, 3]]]])

    class _InvalidTestClass:
        @staticmethod
        @njit()
        def _numba_distance(x, y, **kwargs) -> float:
            return 5.0

        def _distance_factory(
            self, x: np.ndarray, y: np.ndarray, **kwargs: dict
        ) -> DistanceCallable:
            return self._numba_distance

    with pytest.raises(ValueError):  # Invalid metric string
        distance_func(numpy_x, numpy_y, metric="fake")

    with pytest.raises(ValueError):  # Invalid dimensions x
        distance_func(numpy_4d, numpy_y, metric="euclidean")

    with pytest.raises(ValueError):  # Invalid dimensions y
        distance_func(numpy_x, numpy_4d, metric="euclidean")

    with pytest.raises(ValueError):  # Object that doesn't inherit NumbaDistance
        distance_func(numpy_x, numpy_y, metric=_InvalidTestClass())
Ejemplo n.º 3
0
def test_numba_lower_bounding() -> None:
    """Test numba implementation of bounding."""
    _validate_bounding(
        x=np.array([10.0]),
        y=np.array([15.0]),
    )

    _validate_bounding(
        x=create_test_distance_numpy(10),
        y=create_test_distance_numpy(10, random_state=2),
    )

    _validate_bounding(
        x=create_test_distance_numpy(10, 1),
        y=create_test_distance_numpy(10, 1, random_state=2),
    )

    _validate_bounding(
        x=create_test_distance_numpy(10, 10),
        y=create_test_distance_numpy(10, 10, random_state=2),
    )

    _validate_bounding(
        x=create_test_distance_numpy(10, 10, 1),
        y=create_test_distance_numpy(10, 10, 1, random_state=2),
    )

    _validate_bounding(
        x=create_test_distance_numpy(10, 10, 10),
        y=create_test_distance_numpy(10, 10, 10, random_state=2),
    )
Ejemplo n.º 4
0
def test_distance_alignment_path(dist):
    """Test the distance paths."""
    if dist.dist_alignment_path_func is not None:

        x = create_test_distance_numpy(10, 1)
        y = create_test_distance_numpy(10, 1, random_state=2)
        _validate_distance_alignment_path_result(
            x=x,
            y=y,
            metric_str=dist.canonical_name,
            distance_path_callable=dist.dist_alignment_path_func,
        )
Ejemplo n.º 5
0
def _test_metric_parameters(distance_func: Callable):
    """Test to ensure custom distances can be used."""

    @njit()
    def _standalone_numba_distance(x, y) -> float:
        return 5.0

    class _ValidTestClass(NumbaDistance):
        @staticmethod
        @njit()
        def _numba_distance(x, y) -> float:
            return _standalone_numba_distance(x, y)

        def _distance_factory(
            self, x: np.ndarray, y: np.ndarray, **kwargs: dict
        ) -> DistanceCallable:
            return _ValidTestClass._numba_distance

    x_numpy = create_test_distance_numpy(10, 10)
    y_numpy = create_test_distance_numpy(10, 10, random_state=2)

    class_result = distance_func(x_numpy, y_numpy, metric=_ValidTestClass())
    standalone_dist_result = distance_func(
        x_numpy, y_numpy, metric=_standalone_numba_distance
    )

    if isinstance(class_result, float) or class_result.shape == (1, 1):
        expected = 5.0
        assert class_result == expected, (
            f"Using a custom NumbaDistance did not produce the expected result. Ensure"
            f"custom NumbaDistances can be passed. Expected result {expected}, got "
            f"{class_result}"
        )

        assert standalone_dist_result == expected, (
            f"Using a custom no_python compiled distance function did not produce the"
            f"expected result. Ensure no_python compiled functions can be passed. "
            f"Expected result {expected}, got {class_result}"
        )
    else:
        expected = 50.0
        assert class_result.trace() == expected, (
            f"Using a custom NumbaDistance did not produce the expected result. Ensure"
            f"custom NumbaDistances can be passed. Expected result {expected}, got "
            f"{class_result.trace()}"
        )

        assert standalone_dist_result.trace() == expected, (
            f"Using a custom no_python compiled distance function did not produce the"
            f"expected result. Ensure no_python compiled functions can be passed."
            f"Expected result {expected}, got {class_result.trace()}"
        )
Ejemplo n.º 6
0
def test_pairwise_distance(dist: MetricInfo) -> None:
    """Test pairwise distance.

    Parameters
    ----------
    dist: MetricInfo
        MetricInfo NamedTuple containing data for distance metric.
    """
    name = dist.canonical_name
    distance_numba_class = dist.dist_instance
    distance_function = dist.dist_func

    distance_factory = distance_numba_class.distance_factory

    _validate_pairwise_result(
        x=np.array([10.0]),
        y=np.array([15.0]),
        metric_str=name,
        distance_factory=distance_factory,
        distance_function=distance_function,
        distance_numba_class=distance_numba_class,
    )

    _validate_pairwise_result(
        x=create_test_distance_numpy(5),
        y=create_test_distance_numpy(5, random_state=2),
        metric_str=name,
        distance_factory=distance_factory,
        distance_function=distance_function,
        distance_numba_class=distance_numba_class,
    )

    _validate_pairwise_result(
        x=create_test_distance_numpy(5, 5),
        y=create_test_distance_numpy(5, 5, random_state=2),
        metric_str=name,
        distance_factory=distance_factory,
        distance_function=distance_function,
        distance_numba_class=distance_numba_class,
    )

    _validate_pairwise_result(
        x=create_test_distance_numpy(5, 1, 5),
        y=create_test_distance_numpy(5, 1, 5, random_state=2),
        metric_str=name,
        distance_factory=distance_factory,
        distance_function=distance_function,
        distance_numba_class=distance_numba_class,
    )

    _validate_pairwise_result(
        x=create_test_distance_numpy(5, 5, 5),
        y=create_test_distance_numpy(5, 5, 5, random_state=2),
        metric_str=name,
        distance_factory=distance_factory,
        distance_function=distance_function,
        distance_numba_class=distance_numba_class,
    )
Ejemplo n.º 7
0
def test_lloyds():
    """Test implementation of Lloyds."""
    X_train = create_test_distance_numpy(20, 10, 10)
    X_test = create_test_distance_numpy(20, 10, 10, random_state=2)

    lloyd = _test_class()
    lloyd.fit(X_train)
    test_result = lloyd.predict(X_test)

    assert test_result.dtype is np.dtype("int64")

    assert np.array_equal(
        test_result,
        np.array([
            0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
            19
        ]),
    )
Ejemplo n.º 8
0
def test_dba():
    """Test dba functionality."""
    X_train = create_test_distance_numpy(10, 10, 10)

    average_ts = dba(X_train)

    assert isinstance(average_ts, np.ndarray)
    assert average_ts.shape == X_train[0].shape
    assert np.allclose(average_ts, expected_dba)
Ejemplo n.º 9
0
def test_distance(dist: MetricInfo) -> None:
    """Test distance.

    Parameters
    ----------
    dist: MetricInfo
        MetricInfo NamedTuple containing data for distance metric.
    """
    name = dist.canonical_name
    distance_numba_class = dist.dist_instance
    distance_function = dist.dist_func
    distance_factory = distance_numba_class.distance_factory

    _validate_distance_result(
        x=np.array([10.0]),
        y=np.array([15.0]),
        metric_str=name,
        distance_factory=distance_factory,
        distance_function=distance_function,
        distance_numba_class=distance_numba_class,
        expected_result=_expected_distance_results[name][0],
    )

    _validate_distance_result(
        x=create_test_distance_numpy(10),
        y=create_test_distance_numpy(10, random_state=2),
        metric_str=name,
        distance_factory=distance_factory,
        distance_function=distance_function,
        distance_numba_class=distance_numba_class,
        expected_result=_expected_distance_results[name][1],
    )

    _validate_distance_result(
        x=create_test_distance_numpy(10, 10),
        y=create_test_distance_numpy(10, 10, random_state=2),
        metric_str=name,
        distance_factory=distance_factory,
        distance_function=distance_function,
        distance_numba_class=distance_numba_class,
        expected_result=_expected_distance_results[name][2],
    )
Ejemplo n.º 10
0
def test_incorrect_parameters() -> None:
    """Test to check correct errors raised."""
    numpy_x = create_test_distance_numpy(10, 10)
    numpy_y = create_test_distance_numpy(10, 10, random_state=2)

    df_x = pd.DataFrame(numpy_x)

    series_x = df_x.iloc[0]

    numpy_4d = np.array([[[[1, 2, 3]]]])

    no_bounding = LowerBounding.NO_BOUNDING
    sakoe_chiba = LowerBounding.SAKOE_CHIBA

    with pytest.raises(ValueError):  # Try pass data frame in y
        no_bounding.create_bounding_matrix(numpy_x, df_x)

    with pytest.raises(ValueError):  # Try pass data frame in x
        no_bounding.create_bounding_matrix(df_x, numpy_y)

    with pytest.raises(ValueError):  # Try pass series in y
        no_bounding.create_bounding_matrix(numpy_x, series_x)

    with pytest.raises(ValueError):  # Try pass series in x
        no_bounding.create_bounding_matrix(series_x, numpy_y)

    with pytest.raises(ValueError):  # Try pass 4d numpy in y
        no_bounding.create_bounding_matrix(numpy_x, numpy_4d)

    with pytest.raises(ValueError):  # Try pass 4d numpy in x
        no_bounding.create_bounding_matrix(numpy_4d, numpy_y)

    with pytest.raises(ValueError):  # Try pass float to sakoe
        sakoe_chiba.create_bounding_matrix(numpy_x,
                                           numpy_y,
                                           sakoe_chiba_window_radius=1.2)

    with pytest.raises(ValueError):  # Try pass both window and gradient
        sakoe_chiba.create_bounding_matrix(numpy_x,
                                           numpy_y,
                                           sakoe_chiba_window_radius=1.2,
                                           itakura_max_slope=10.0)
Ejemplo n.º 11
0
def test_medoids():
    """Test medoids."""
    X = create_test_distance_numpy(10, 3, 3, random_state=2)
    test_medoids = medoids(X).tolist()
    assert np.array_equal(
        test_medoids,
        [
            [-0.16783866926192373, 0.3056703897868587, 0.023985295934094188],
            [-0.41456764450738937, 0.04385510920416571, 0.5001829432753475],
            [-0.19054625875767497, -0.18783471153949682, -0.03723538144699049],
        ],
    )
Ejemplo n.º 12
0
def test_medoids():
    """Test medoids."""
    X = create_test_distance_numpy(10, 3, 3, random_state=2)
    test_medoids = medoids(X)
    assert np.array_equal(
        test_medoids,
        [
            [-0.3739354746469312, 0.004512625486662562, -0.439053946620171],
            [-0.07821708519231182, 0.12828522600064782, -0.4943895243848109],
            [-0.16941098301459817, -0.11809201542630064, -0.3188275062421506],
        ],
    )
def _test_distance_params(param_list: List[Dict], distance_func: Callable,
                          distance_str: str):
    x_univ = to_numba_timeseries(create_test_distance_numpy(10, 1))
    y_univ = to_numba_timeseries(
        create_test_distance_numpy(10, 1, random_state=2))

    x_multi = create_test_distance_numpy(10, 10)
    y_multi = create_test_distance_numpy(10, 10, random_state=2)

    test_ts = [[x_univ, y_univ], [x_multi, y_multi]]
    results_to_fill = []

    i = 0
    for param_dict in param_list:
        j = 0
        curr_results = []
        for x, y in test_ts:
            results = []
            curr_dist_fact = distance_factory(x,
                                              y,
                                              metric=distance_str,
                                              **param_dict)
            results.append(distance_func(x, y, **param_dict))
            results.append(distance(x, y, metric=distance_str, **param_dict))
            results.append(curr_dist_fact(x, y))

            if distance_str in _expected_distance_results_params:

                if _expected_distance_results_params[distance_str][i][
                        j] is not None:
                    for result in results:
                        assert result == pytest.approx(
                            _expected_distance_results_params[distance_str][i]
                            [j])
            curr_results.append(results[0])
            j += 1
        i += 1
        results_to_fill.append(curr_results)
Ejemplo n.º 14
0
def generate_test_results_clusterers():
    """Generate test results."""
    X_train, y_train = load_unit_test(split="train", return_type="numpy2d")
    print(" Shape = ", X_train[0].shape)
    s = StandardScaler()
    X_train = s.fit_transform(X_train.T)
    X_train = X_train.T
    d1 = X_train[0]
    d2 = X_train[1]
    print(" Shape = ", d1.shape)
    d3 = np.zeros(d1.shape)
    print(d1)
    print(d2)
    print(d3)
    # d1, c1 and c2= distance =  0.9166666666666666

    c1 = np.array([
        -0.70310574,
        -0.87214184,
        -1.00698691,
        -1.06674154,
        -1.12436733,
        -1.15538656,
        -1.15125921,
        -1.03439438,
        -0.85569435,
        -0.76934041,
        -0.47880807,
        0.13013539,
        1.24150173,
        1.47580796,
        1.21524191,
        1.03776906,
        0.9338891,
        1.11147877,
        1.35705589,
        1.29823615,
        0.81583304,
        0.30507612,
        -0.14019819,
        -0.5636006,
    ])
    c2 = np.array([
        -0.56887401,
        -0.78355128,
        -0.97270354,
        -1.05610923,
        -1.16663863,
        -1.21763814,
        -1.21428503,
        -1.14248176,
        -0.9842895,
        -0.91458795,
        -0.55085488,
        0.03584731,
        1.08807594,
        1.32503268,
        1.08481383,
        0.90703813,
        0.87781706,
        1.03376858,
        1.33278512,
        1.38938799,
        0.99061415,
        0.59018919,
        0.1635356,
        -0.24689165,
    ])
    x = create_test_distance_numpy(10)
    y = create_test_distance_numpy(10, random_state=2)
    curr_X = X_train[19]

    curr_X = curr_X.reshape((1, c1.shape[0]))

    c1 = c1.reshape((1, c1.shape[0]))
    print(f"instance 19  = {curr_X} shape X = {curr_X.shape}")
    print("Centroid 0 =", c1)
    d = lcss_distance(curr_X, c1, epsilon=0.01)
    print(" DISTANCE = ", d)
    print("Shape centroid = ", c1.shape)
    d = lcss_distance(curr_X, c2, epsilon=0.01)
    print(" DISTANCE = ", d)
    print("Shape centroid = ", c2.shape)

    italy1 = np.array([
        -0.71051757,
        -1.1833204,
        -1.3724416,
        -1.5930829,
        -1.4670021,
        -1.3724416,
        -1.0887599,
        0.045966947,
        0.92853223,
        1.0861332,
        1.2752543,
        0.96005242,
        0.61333034,
        0.014446758,
        -0.6474772,
        -0.26923494,
        -0.20619456,
        0.61333034,
        1.3698149,
        1.4643754,
        1.054613,
        0.58181015,
        0.1720477,
        -0.26923494,
    ])
    italy2 = np.array([
        -0.41137184,
        -0.67348487,
        -1.1103399,
        -1.2413964,
        -1.4161385,
        -1.3287674,
        -0.84822689,
        -0.58611386,
        -0.80454138,
        0.069168714,
        0.68076578,
        0.76813679,
        0.63708028,
        0.069168714,
        -0.36768633,
        -0.49874285,
        -0.36768633,
        -0.018202296,
        1.7729034,
        2.0350164,
        1.5544759,
        1.4234194,
        0.63708028,
        0.025483209,
    ])
    d = dtw_distance(italy1, italy2)
    print(" Italy DTW DISTANCE = ", d)