FIX Apply dtype param in `check_array_api_compute_metric` unit test (#27940)
This commit is contained in:
parent
94b84718f9
commit
77aeb825b6
|
|
@ -817,9 +817,9 @@ def test_variance_correctness(copy):
|
|||
np.testing.assert_allclose(pca_var, true_var)
|
||||
|
||||
|
||||
def check_array_api_get_precision(name, estimator, array_namespace, device, dtype):
|
||||
def check_array_api_get_precision(name, estimator, array_namespace, device, dtype_name):
|
||||
xp = _array_api_for_tests(array_namespace, device)
|
||||
iris_np = iris.data.astype(dtype)
|
||||
iris_np = iris.data.astype(dtype_name)
|
||||
iris_xp = xp.asarray(iris_np, device=device)
|
||||
|
||||
estimator.fit(iris_np)
|
||||
|
|
@ -835,7 +835,7 @@ def check_array_api_get_precision(name, estimator, array_namespace, device, dtyp
|
|||
assert_allclose(
|
||||
_convert_to_numpy(precision_xp, xp=xp),
|
||||
precision_np,
|
||||
atol=_atol_for_type(dtype),
|
||||
atol=_atol_for_type(dtype_name),
|
||||
)
|
||||
covariance_xp = estimator_xp.get_covariance()
|
||||
assert covariance_xp.shape == (4, 4)
|
||||
|
|
@ -844,12 +844,12 @@ def check_array_api_get_precision(name, estimator, array_namespace, device, dtyp
|
|||
assert_allclose(
|
||||
_convert_to_numpy(covariance_xp, xp=xp),
|
||||
covariance_np,
|
||||
atol=_atol_for_type(dtype),
|
||||
atol=_atol_for_type(dtype_name),
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"array_namespace, device, dtype", yield_namespace_device_dtype_combinations()
|
||||
"array_namespace, device, dtype_name", yield_namespace_device_dtype_combinations()
|
||||
)
|
||||
@pytest.mark.parametrize(
|
||||
"check",
|
||||
|
|
@ -870,13 +870,15 @@ def check_array_api_get_precision(name, estimator, array_namespace, device, dtyp
|
|||
],
|
||||
ids=_get_check_estimator_ids,
|
||||
)
|
||||
def test_pca_array_api_compliance(estimator, check, array_namespace, device, dtype):
|
||||
def test_pca_array_api_compliance(
|
||||
estimator, check, array_namespace, device, dtype_name
|
||||
):
|
||||
name = estimator.__class__.__name__
|
||||
check(name, estimator, array_namespace, device=device, dtype=dtype)
|
||||
check(name, estimator, array_namespace, device=device, dtype_name=dtype_name)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"array_namespace, device, dtype", yield_namespace_device_dtype_combinations()
|
||||
"array_namespace, device, dtype_name", yield_namespace_device_dtype_combinations()
|
||||
)
|
||||
@pytest.mark.parametrize(
|
||||
"check",
|
||||
|
|
@ -892,9 +894,11 @@ def test_pca_array_api_compliance(estimator, check, array_namespace, device, dty
|
|||
],
|
||||
ids=_get_check_estimator_ids,
|
||||
)
|
||||
def test_pca_mle_array_api_compliance(estimator, check, array_namespace, device, dtype):
|
||||
def test_pca_mle_array_api_compliance(
|
||||
estimator, check, array_namespace, device, dtype_name
|
||||
):
|
||||
name = estimator.__class__.__name__
|
||||
check(name, estimator, array_namespace, device=device, dtype=dtype)
|
||||
check(name, estimator, array_namespace, device=device, dtype_name=dtype_name)
|
||||
|
||||
|
||||
def test_array_api_error_and_warnings_on_unsupported_params():
|
||||
|
|
|
|||
|
|
@ -1733,67 +1733,87 @@ def test_metrics_pos_label_error_str(metric, y_pred_threshold, dtype_y_str):
|
|||
|
||||
|
||||
def check_array_api_metric(
|
||||
metric, array_namespace, device, dtype, y_true_np, y_pred_np, sample_weight=None
|
||||
metric, array_namespace, device, dtype_name, y_true_np, y_pred_np, sample_weight
|
||||
):
|
||||
xp = _array_api_for_tests(array_namespace, device)
|
||||
|
||||
y_true_xp = xp.asarray(y_true_np, device=device)
|
||||
y_pred_xp = xp.asarray(y_pred_np, device=device)
|
||||
|
||||
metric_np = metric(y_true_np, y_pred_np, sample_weight=sample_weight)
|
||||
|
||||
if sample_weight is not None:
|
||||
sample_weight = xp.asarray(sample_weight, device=device)
|
||||
|
||||
with config_context(array_api_dispatch=True):
|
||||
if sample_weight is not None:
|
||||
sample_weight = xp.asarray(sample_weight, device=device)
|
||||
metric_xp = metric(y_true_xp, y_pred_xp, sample_weight=sample_weight)
|
||||
|
||||
assert_allclose(
|
||||
metric_xp,
|
||||
metric_np,
|
||||
atol=_atol_for_type(dtype),
|
||||
atol=_atol_for_type(dtype_name),
|
||||
)
|
||||
|
||||
|
||||
def check_array_api_binary_classification_metric(
|
||||
metric, array_namespace, device, dtype
|
||||
metric, array_namespace, device, dtype_name
|
||||
):
|
||||
y_true_np = np.array([0, 0, 1, 1])
|
||||
y_pred_np = np.array([0, 1, 0, 1])
|
||||
|
||||
check_array_api_metric(
|
||||
metric, array_namespace, device, dtype, y_true_np=y_true_np, y_pred_np=y_pred_np
|
||||
metric,
|
||||
array_namespace,
|
||||
device,
|
||||
dtype_name,
|
||||
y_true_np=y_true_np,
|
||||
y_pred_np=y_pred_np,
|
||||
sample_weight=None,
|
||||
)
|
||||
|
||||
sample_weight = np.array([0.0, 0.1, 2.0, 1.0], dtype=dtype_name)
|
||||
|
||||
check_array_api_metric(
|
||||
metric,
|
||||
array_namespace,
|
||||
device,
|
||||
dtype_name,
|
||||
y_true_np=y_true_np,
|
||||
y_pred_np=y_pred_np,
|
||||
sample_weight=sample_weight,
|
||||
)
|
||||
if "sample_weight" in signature(metric).parameters:
|
||||
check_array_api_metric(
|
||||
metric,
|
||||
array_namespace,
|
||||
device,
|
||||
dtype,
|
||||
y_true_np=y_true_np,
|
||||
y_pred_np=y_pred_np,
|
||||
sample_weight=np.array([0.0, 0.1, 2.0, 1.0]),
|
||||
)
|
||||
|
||||
|
||||
def check_array_api_multiclass_classification_metric(
|
||||
metric, array_namespace, device, dtype
|
||||
metric, array_namespace, device, dtype_name
|
||||
):
|
||||
y_true_np = np.array([0, 1, 2, 3])
|
||||
y_pred_np = np.array([0, 1, 0, 2])
|
||||
|
||||
check_array_api_metric(
|
||||
metric, array_namespace, device, dtype, y_true_np=y_true_np, y_pred_np=y_pred_np
|
||||
metric,
|
||||
array_namespace,
|
||||
device,
|
||||
dtype_name,
|
||||
y_true_np=y_true_np,
|
||||
y_pred_np=y_pred_np,
|
||||
sample_weight=None,
|
||||
)
|
||||
|
||||
sample_weight = np.array([0.0, 0.1, 2.0, 1.0], dtype=dtype_name)
|
||||
|
||||
check_array_api_metric(
|
||||
metric,
|
||||
array_namespace,
|
||||
device,
|
||||
dtype_name,
|
||||
y_true_np=y_true_np,
|
||||
y_pred_np=y_pred_np,
|
||||
sample_weight=sample_weight,
|
||||
)
|
||||
if "sample_weight" in signature(metric).parameters:
|
||||
check_array_api_metric(
|
||||
metric,
|
||||
array_namespace,
|
||||
device,
|
||||
dtype,
|
||||
y_true_np=y_true_np,
|
||||
y_pred_np=y_pred_np,
|
||||
sample_weight=np.array([0.0, 0.1, 2.0, 1.0]),
|
||||
)
|
||||
|
||||
|
||||
metric_checkers = {
|
||||
array_api_metric_checkers = {
|
||||
accuracy_score: [
|
||||
check_array_api_binary_classification_metric,
|
||||
check_array_api_multiclass_classification_metric,
|
||||
|
|
@ -1805,15 +1825,15 @@ metric_checkers = {
|
|||
}
|
||||
|
||||
|
||||
def yield_metric_checker_combinations(metric_checkers=metric_checkers):
|
||||
def yield_metric_checker_combinations(metric_checkers=array_api_metric_checkers):
|
||||
for metric, checkers in metric_checkers.items():
|
||||
for checker in checkers:
|
||||
yield metric, checker
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"array_namespace, device, dtype", yield_namespace_device_dtype_combinations()
|
||||
"array_namespace, device, dtype_name", yield_namespace_device_dtype_combinations()
|
||||
)
|
||||
@pytest.mark.parametrize("metric, check_func", yield_metric_checker_combinations())
|
||||
def test_array_api_compliance(metric, array_namespace, device, dtype, check_func):
|
||||
check_func(metric, array_namespace, device, dtype)
|
||||
def test_array_api_compliance(metric, array_namespace, device, dtype_name, check_func):
|
||||
check_func(metric, array_namespace, device, dtype_name)
|
||||
|
|
|
|||
|
|
@ -1267,7 +1267,7 @@ def test_train_test_split_default_test_size(train_size, exp_train, exp_test):
|
|||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"array_namespace, device, dtype", yield_namespace_device_dtype_combinations()
|
||||
"array_namespace, device, dtype_name", yield_namespace_device_dtype_combinations()
|
||||
)
|
||||
@pytest.mark.parametrize(
|
||||
"shuffle,stratify",
|
||||
|
|
@ -1278,16 +1278,18 @@ def test_train_test_split_default_test_size(train_size, exp_train, exp_test):
|
|||
(False, None),
|
||||
),
|
||||
)
|
||||
def test_array_api_train_test_split(shuffle, stratify, array_namespace, device, dtype):
|
||||
def test_array_api_train_test_split(
|
||||
shuffle, stratify, array_namespace, device, dtype_name
|
||||
):
|
||||
xp = _array_api_for_tests(array_namespace, device)
|
||||
|
||||
X = np.arange(100).reshape((10, 10))
|
||||
y = np.arange(10)
|
||||
|
||||
X_np = X.astype(dtype)
|
||||
X_np = X.astype(dtype_name)
|
||||
X_xp = xp.asarray(X_np, device=device)
|
||||
|
||||
y_np = y.astype(dtype)
|
||||
y_np = y.astype(dtype_name)
|
||||
y_xp = xp.asarray(y_np, device=device)
|
||||
|
||||
X_train_np, X_test_np, y_train_np, y_test_np = train_test_split(
|
||||
|
|
|
|||
|
|
@ -682,7 +682,7 @@ def test_standard_check_array_of_inverse_transform():
|
|||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"array_namespace, device, dtype", yield_namespace_device_dtype_combinations()
|
||||
"array_namespace, device, dtype_name", yield_namespace_device_dtype_combinations()
|
||||
)
|
||||
@pytest.mark.parametrize(
|
||||
"check",
|
||||
|
|
@ -701,9 +701,11 @@ def test_standard_check_array_of_inverse_transform():
|
|||
],
|
||||
ids=_get_check_estimator_ids,
|
||||
)
|
||||
def test_scaler_array_api_compliance(estimator, check, array_namespace, device, dtype):
|
||||
def test_scaler_array_api_compliance(
|
||||
estimator, check, array_namespace, device, dtype_name
|
||||
):
|
||||
name = estimator.__class__.__name__
|
||||
check(name, estimator, array_namespace, device=device, dtype=dtype)
|
||||
check(name, estimator, array_namespace, device=device, dtype_name=dtype_name)
|
||||
|
||||
|
||||
def test_min_max_scaler_iris():
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ def yield_namespace_device_dtype_combinations():
|
|||
The name of the device on which to allocate the arrays. Can be None to
|
||||
indicate that the default value should be used.
|
||||
|
||||
dtype : str
|
||||
dtype_name : str
|
||||
The name of the data type to use for arrays. Can be None to indicate
|
||||
that the default value should be used.
|
||||
"""
|
||||
|
|
@ -444,7 +444,9 @@ def _weighted_sum(sample_score, sample_weight, normalize=False, xp=None):
|
|||
sample_score = xp.astype(xp.asarray(sample_score, device="cpu"), xp.float64)
|
||||
|
||||
if sample_weight is not None:
|
||||
sample_weight = xp.asarray(sample_weight, dtype=sample_score.dtype)
|
||||
sample_weight = xp.asarray(
|
||||
sample_weight, dtype=sample_score.dtype, device=device(sample_score)
|
||||
)
|
||||
if not xp.isdtype(sample_weight.dtype, "real floating"):
|
||||
sample_weight = xp.astype(sample_weight, xp.float64)
|
||||
|
||||
|
|
|
|||
|
|
@ -311,11 +311,15 @@ def _yield_outliers_checks(estimator):
|
|||
|
||||
|
||||
def _yield_array_api_checks(estimator):
|
||||
for array_namespace, device, dtype in yield_namespace_device_dtype_combinations():
|
||||
for (
|
||||
array_namespace,
|
||||
device,
|
||||
dtype_name,
|
||||
) in yield_namespace_device_dtype_combinations():
|
||||
yield partial(
|
||||
check_array_api_input,
|
||||
array_namespace=array_namespace,
|
||||
dtype=dtype,
|
||||
dtype_name=dtype_name,
|
||||
device=device,
|
||||
)
|
||||
|
||||
|
|
@ -864,7 +868,7 @@ def check_array_api_input(
|
|||
estimator_orig,
|
||||
array_namespace,
|
||||
device=None,
|
||||
dtype="float64",
|
||||
dtype_name="float64",
|
||||
check_values=False,
|
||||
):
|
||||
"""Check that the estimator can work consistently with the Array API
|
||||
|
|
@ -878,7 +882,7 @@ def check_array_api_input(
|
|||
xp = _array_api_for_tests(array_namespace, device)
|
||||
|
||||
X, y = make_classification(random_state=42)
|
||||
X = X.astype(dtype, copy=False)
|
||||
X = X.astype(dtype_name, copy=False)
|
||||
|
||||
X = _enforce_estimator_tags_X(estimator_orig, X)
|
||||
y = _enforce_estimator_tags_y(estimator_orig, y)
|
||||
|
|
@ -1007,14 +1011,14 @@ def check_array_api_input_and_values(
|
|||
estimator_orig,
|
||||
array_namespace,
|
||||
device=None,
|
||||
dtype="float64",
|
||||
dtype_name="float64",
|
||||
):
|
||||
return check_array_api_input(
|
||||
name,
|
||||
estimator_orig,
|
||||
array_namespace=array_namespace,
|
||||
device=device,
|
||||
dtype=dtype,
|
||||
dtype_name=dtype_name,
|
||||
check_values=True,
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -129,7 +129,7 @@ def test_asarray_with_order_ignored():
|
|||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"array_namespace, device, dtype", yield_namespace_device_dtype_combinations()
|
||||
"array_namespace, device, dtype_name", yield_namespace_device_dtype_combinations()
|
||||
)
|
||||
@pytest.mark.parametrize(
|
||||
"sample_weight, normalize, expected",
|
||||
|
|
@ -143,20 +143,20 @@ def test_asarray_with_order_ignored():
|
|||
],
|
||||
)
|
||||
def test_weighted_sum(
|
||||
array_namespace, device, dtype, sample_weight, normalize, expected
|
||||
array_namespace, device, dtype_name, sample_weight, normalize, expected
|
||||
):
|
||||
xp = _array_api_for_tests(array_namespace, device)
|
||||
sample_score = numpy.asarray([1, 2, 3, 4], dtype=dtype)
|
||||
sample_score = numpy.asarray([1, 2, 3, 4], dtype=dtype_name)
|
||||
sample_score = xp.asarray(sample_score, device=device)
|
||||
if sample_weight is not None:
|
||||
sample_weight = numpy.asarray(sample_weight, dtype=dtype)
|
||||
sample_weight = numpy.asarray(sample_weight, dtype=dtype_name)
|
||||
sample_weight = xp.asarray(sample_weight, device=device)
|
||||
|
||||
with config_context(array_api_dispatch=True):
|
||||
result = _weighted_sum(sample_score, sample_weight, normalize)
|
||||
|
||||
assert isinstance(result, float)
|
||||
assert_allclose(result, expected, atol=_atol_for_type(dtype))
|
||||
assert_allclose(result, expected, atol=_atol_for_type(dtype_name))
|
||||
|
||||
|
||||
@skip_if_array_api_compat_not_configured
|
||||
|
|
|
|||
|
|
@ -379,17 +379,17 @@ def test_is_multilabel():
|
|||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"array_namespace, device, dtype",
|
||||
"array_namespace, device, dtype_name",
|
||||
yield_namespace_device_dtype_combinations(),
|
||||
)
|
||||
def test_is_multilabel_array_api_compliance(array_namespace, device, dtype):
|
||||
def test_is_multilabel_array_api_compliance(array_namespace, device, dtype_name):
|
||||
xp = _array_api_for_tests(array_namespace, device)
|
||||
|
||||
for group, group_examples in ARRAY_API_EXAMPLES.items():
|
||||
dense_exp = group == "multilabel-indicator"
|
||||
for example in group_examples:
|
||||
if np.asarray(example).dtype.kind == "f":
|
||||
example = np.asarray(example, dtype=dtype)
|
||||
example = np.asarray(example, dtype=dtype_name)
|
||||
else:
|
||||
example = np.asarray(example)
|
||||
example = xp.asarray(example, device=device)
|
||||
|
|
|
|||
Loading…
Reference in New Issue