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), )
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())
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), )
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, )
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()}" )
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, )
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 ]), )
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)
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], )
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)
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], ], )
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)
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)