From a5f84603a0878ac803657e04e8ad819edeb757ca Mon Sep 17 00:00:00 2001 From: virchan Date: Mon, 21 Oct 2024 16:08:32 -0700 Subject: [PATCH 01/27] ENH Reduce redundancy in floating type checks for Array API support --- sklearn/metrics/_regression.py | 122 ++++++++++++++++++++++----------- 1 file changed, 82 insertions(+), 40 deletions(-) diff --git a/sklearn/metrics/_regression.py b/sklearn/metrics/_regression.py index 62251f9b96188..7d3e42f838fb4 100644 --- a/sklearn/metrics/_regression.py +++ b/sklearn/metrics/_regression.py @@ -71,11 +71,6 @@ def _check_reg_targets(y_true, y_pred, multioutput, dtype="numeric", xp=None): dtype : str or list, default="numeric" the dtype argument passed to check_array. - xp : module, default=None - Precomputed array namespace module. When passed, typically from a caller - that has already performed inspection of its own inputs, skips array - namespace inspection. - Returns ------- type_true : one of {'continuous', continuous-multioutput'} @@ -137,6 +132,63 @@ def _check_reg_targets(y_true, y_pred, multioutput, dtype="numeric", xp=None): return y_type, y_true, y_pred, multioutput +def _check_reg_targets_and_floating_dtype( + y_true, y_pred, sample_weight, multioutput, xp=None +): + """Ensure that y_true and y_pred correspond to the same regression task, + and select an appropriate floating-point data type when computing with arrays. + + Parameters + ---------- + y_true : array-like + + y_pred : array-like + + sample_weight : array-like of shape (n_samples,) + Sample weights. + + multioutput : array-like or string in ['raw_values', uniform_average', + 'variance_weighted'] or None + None is accepted due to backward compatibility of r2_score(). + + xp : module, default=None + Precomputed array namespace module. When passed, typically from a caller + that has already performed inspection of its own inputs, skips array + namespace inspection. + + Returns + ------- + type_true : one of {'continuous', continuous-multioutput'} + The type of the true target data, as output by + 'utils.multiclass.type_of_target'. + + y_true : array-like of shape (n_samples, n_outputs) + Ground truth (correct) target values. + + y_pred : array-like of shape (n_samples, n_outputs) + Estimated target values. + + sample_weight : array-like of shape (n_samples,), default=None + Sample weights. + + multioutput : array-like of shape (n_outputs) or string in ['raw_values', + uniform_average', 'variance_weighted'] or None + Custom output weights if ``multioutput`` is array-like or + just the corresponding argument if ``multioutput`` is a + correct keyword. + + dtype : str or list, default="numeric" + the dtype argument passed to check_array. + """ + dtype = _find_matching_floating_dtype(y_true, y_pred, sample_weight, xp=xp) + + y_type, y_true, y_pred, multioutput = _check_reg_targets( + y_true, y_pred, multioutput, dtype=dtype, xp=xp + ) + + return y_type, y_true, y_pred, sample_weight, multioutput, dtype + + @validate_params( { "y_true": ["array-like"], @@ -201,14 +253,14 @@ def mean_absolute_error( >>> mean_absolute_error(y_true, y_pred, multioutput=[0.3, 0.7]) 0.85... """ - input_arrays = [y_true, y_pred, sample_weight, multioutput] - xp, _ = get_namespace(*input_arrays) - - dtype = _find_matching_floating_dtype(y_true, y_pred, sample_weight, xp=xp) + xp, _ = get_namespace(y_true, y_pred, sample_weight, multioutput) - _, y_true, y_pred, multioutput = _check_reg_targets( - y_true, y_pred, multioutput, dtype=dtype, xp=xp + _, y_true, y_pred, sample_weight, multioutput, dtype = ( + _check_reg_targets_and_floating_dtype( + y_true, y_pred, sample_weight, multioutput, xp=xp + ) ) + check_consistent_length(y_true, y_pred, sample_weight) output_errors = _average( @@ -398,12 +450,11 @@ def mean_absolute_percentage_error( >>> mean_absolute_percentage_error(y_true, y_pred) 112589990684262.48 """ - input_arrays = [y_true, y_pred, sample_weight, multioutput] - xp, _ = get_namespace(*input_arrays) - dtype = _find_matching_floating_dtype(y_true, y_pred, sample_weight, xp=xp) - - y_type, y_true, y_pred, multioutput = _check_reg_targets( - y_true, y_pred, multioutput, dtype=dtype, xp=xp + xp, _ = get_namespace(y_true, y_pred, sample_weight, multioutput) + _, y_true, y_pred, sample_weight, multioutput, dtype = ( + _check_reg_targets_and_floating_dtype( + y_true, y_pred, sample_weight, multioutput, xp=xp + ) ) check_consistent_length(y_true, y_pred, sample_weight) epsilon = xp.asarray(xp.finfo(xp.float64).eps, dtype=dtype) @@ -494,10 +545,10 @@ def mean_squared_error( 0.825... """ xp, _ = get_namespace(y_true, y_pred, sample_weight, multioutput) - dtype = _find_matching_floating_dtype(y_true, y_pred, xp=xp) - - _, y_true, y_pred, multioutput = _check_reg_targets( - y_true, y_pred, multioutput, dtype=dtype, xp=xp + _, y_true, y_pred, sample_weight, multioutput, _ = ( + _check_reg_targets_and_floating_dtype( + y_true, y_pred, sample_weight, multioutput, xp=xp + ) ) check_consistent_length(y_true, y_pred, sample_weight) output_errors = _average((y_true - y_pred) ** 2, axis=0, weights=sample_weight) @@ -670,11 +721,6 @@ def mean_squared_log_error( 0.060... """ xp, _ = get_namespace(y_true, y_pred) - dtype = _find_matching_floating_dtype(y_true, y_pred, xp=xp) - - _, y_true, y_pred, _ = _check_reg_targets( - y_true, y_pred, multioutput, dtype=dtype, xp=xp - ) if xp.any(y_true <= -1) or xp.any(y_pred <= -1): raise ValueError( @@ -747,11 +793,6 @@ def root_mean_squared_log_error( 0.199... """ xp, _ = get_namespace(y_true, y_pred) - dtype = _find_matching_floating_dtype(y_true, y_pred, xp=xp) - - _, y_true, y_pred, multioutput = _check_reg_targets( - y_true, y_pred, multioutput, dtype=dtype, xp=xp - ) if xp.any(y_true <= -1) or xp.any(y_pred <= -1): raise ValueError( @@ -1188,11 +1229,12 @@ def r2_score( y_true, y_pred, sample_weight, multioutput ) - dtype = _find_matching_floating_dtype(y_true, y_pred, sample_weight, xp=xp) - - _, y_true, y_pred, multioutput = _check_reg_targets( - y_true, y_pred, multioutput, dtype=dtype, xp=xp + _, y_true, y_pred, sample_weight, multioutput, dtype = ( + _check_reg_targets_and_floating_dtype( + y_true, y_pred, sample_weight, multioutput, xp=xp + ) ) + check_consistent_length(y_true, y_pred, sample_weight) if _num_samples(y_pred) < 2: @@ -1258,7 +1300,7 @@ def max_error(y_true, y_pred): np.int64(1) """ xp, _ = get_namespace(y_true, y_pred) - y_type, y_true, y_pred, _ = _check_reg_targets(y_true, y_pred, None, xp=xp) + y_type, y_true, y_pred, _ = _check_reg_targets(y_true, y_pred, None) if y_type == "continuous-multioutput": raise ValueError("Multioutput not supported in max_error") return xp.max(xp.abs(y_true - y_pred)) @@ -1356,8 +1398,8 @@ def mean_tweedie_deviance(y_true, y_pred, *, sample_weight=None, power=0): 1.4260... """ xp, _ = get_namespace(y_true, y_pred) - y_type, y_true, y_pred, _ = _check_reg_targets( - y_true, y_pred, None, dtype=[xp.float64, xp.float32], xp=xp + y_type, y_true, y_pred, sample_weight, _, _ = _check_reg_targets_and_floating_dtype( + y_true, y_pred, sample_weight, multioutput=None, xp=xp ) if y_type == "continuous-multioutput": raise ValueError("Multioutput not supported in mean_tweedie_deviance") @@ -1570,8 +1612,8 @@ def d2_tweedie_score(y_true, y_pred, *, sample_weight=None, power=0): """ xp, _ = get_namespace(y_true, y_pred) - y_type, y_true, y_pred, _ = _check_reg_targets( - y_true, y_pred, None, dtype=[xp.float64, xp.float32], xp=xp + y_type, y_true, y_pred, sample_weight, _, _ = _check_reg_targets_and_floating_dtype( + y_true, y_pred, sample_weight, multioutput=None, xp=xp ) if y_type == "continuous-multioutput": raise ValueError("Multioutput not supported in d2_tweedie_score") From 92c048e28fd757ae5d872d4a36d22535723f9fa8 Mon Sep 17 00:00:00 2001 From: virchan Date: Mon, 21 Oct 2024 16:11:29 -0700 Subject: [PATCH 02/27] ENH Reduce redundancy in floating type checks for Array API support --- sklearn/metrics/_regression.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sklearn/metrics/_regression.py b/sklearn/metrics/_regression.py index 7d3e42f838fb4..1f54ea3a29194 100644 --- a/sklearn/metrics/_regression.py +++ b/sklearn/metrics/_regression.py @@ -71,6 +71,11 @@ def _check_reg_targets(y_true, y_pred, multioutput, dtype="numeric", xp=None): dtype : str or list, default="numeric" the dtype argument passed to check_array. + xp : module, default=None + Precomputed array namespace module. When passed, typically from a caller + that has already performed inspection of its own inputs, skips array + namespace inspection. + Returns ------- type_true : one of {'continuous', continuous-multioutput'} From 69e00ccf5964055759b97b99b11cbeb712ac729e Mon Sep 17 00:00:00 2001 From: virchan Date: Mon, 21 Oct 2024 17:34:47 -0700 Subject: [PATCH 03/27] Updating `_regression.py` and `test_common.py`. --- sklearn/metrics/_regression.py | 8 ++++++++ sklearn/metrics/tests/test_common.py | 4 ++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/sklearn/metrics/_regression.py b/sklearn/metrics/_regression.py index 1f54ea3a29194..2af9d5f6c8e96 100644 --- a/sklearn/metrics/_regression.py +++ b/sklearn/metrics/_regression.py @@ -727,6 +727,10 @@ def mean_squared_log_error( """ xp, _ = get_namespace(y_true, y_pred) + _, y_true, y_pred, _, _, _ = _check_reg_targets_and_floating_dtype( + y_true, y_pred, sample_weight, multioutput, xp=xp + ) + if xp.any(y_true <= -1) or xp.any(y_pred <= -1): raise ValueError( "Mean Squared Logarithmic Error cannot be used when " @@ -799,6 +803,10 @@ def root_mean_squared_log_error( """ xp, _ = get_namespace(y_true, y_pred) + _, y_true, y_pred, _, _, _ = _check_reg_targets_and_floating_dtype( + y_true, y_pred, sample_weight, multioutput, xp=xp + ) + if xp.any(y_true <= -1) or xp.any(y_pred <= -1): raise ValueError( "Root Mean Squared Logarithmic Error cannot be used when " diff --git a/sklearn/metrics/tests/test_common.py b/sklearn/metrics/tests/test_common.py index f70f0bfa50137..45abed3fa3790 100644 --- a/sklearn/metrics/tests/test_common.py +++ b/sklearn/metrics/tests/test_common.py @@ -582,8 +582,8 @@ def _require_positive_targets(y1, y2): def _require_log1p_targets(y1, y2): """Make targets strictly larger than -1""" offset = abs(min(y1.min(), y2.min())) - 0.99 - y1 = y1.astype(float) - y2 = y2.astype(float) + y1 = y1.astype((np.float64) + y2 = y2.astype((np.float64) y1 += offset y2 += offset return y1, y2 From 3a2ed0e6dcaaa4c112d407a4dcecb57e54da9f48 Mon Sep 17 00:00:00 2001 From: virchan Date: Mon, 21 Oct 2024 17:38:52 -0700 Subject: [PATCH 04/27] Updating `test_common.py`. --- sklearn/metrics/tests/test_common.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sklearn/metrics/tests/test_common.py b/sklearn/metrics/tests/test_common.py index 45abed3fa3790..a180683c50b2e 100644 --- a/sklearn/metrics/tests/test_common.py +++ b/sklearn/metrics/tests/test_common.py @@ -582,8 +582,8 @@ def _require_positive_targets(y1, y2): def _require_log1p_targets(y1, y2): """Make targets strictly larger than -1""" offset = abs(min(y1.min(), y2.min())) - 0.99 - y1 = y1.astype((np.float64) - y2 = y2.astype((np.float64) + y1 = y1.astype(np.float64) + y2 = y2.astype(np.float64) y1 += offset y2 += offset return y1, y2 From eec32bb3dcd61ebf7efd7ee03740de4717379eac Mon Sep 17 00:00:00 2001 From: virchan Date: Mon, 21 Oct 2024 17:55:23 -0700 Subject: [PATCH 05/27] Update changelog. --- doc/whats_new/upcoming_changes/array-api/30128.other.rst | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 doc/whats_new/upcoming_changes/array-api/30128.other.rst diff --git a/doc/whats_new/upcoming_changes/array-api/30128.other.rst b/doc/whats_new/upcoming_changes/array-api/30128.other.rst new file mode 100644 index 0000000000000..615fc6d7b5adc --- /dev/null +++ b/doc/whats_new/upcoming_changes/array-api/30128.other.rst @@ -0,0 +1,3 @@ +- Introduce a new function `_check_reg_targets_and_floating_dtype` to + streamline regression task and floating type checks for regression metrics. + By :user:`Virgil Chan ` \ No newline at end of file From e7a2602e7f4161f3d9a07e281fdbacafb2d7fa9f Mon Sep 17 00:00:00 2001 From: virchan Date: Mon, 21 Oct 2024 19:08:08 -0700 Subject: [PATCH 06/27] Update `_regression.py`. --- sklearn/metrics/_regression.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sklearn/metrics/_regression.py b/sklearn/metrics/_regression.py index 2af9d5f6c8e96..7bcbf755e5c0e 100644 --- a/sklearn/metrics/_regression.py +++ b/sklearn/metrics/_regression.py @@ -182,8 +182,9 @@ def _check_reg_targets_and_floating_dtype( just the corresponding argument if ``multioutput`` is a correct keyword. - dtype : str or list, default="numeric" - the dtype argument passed to check_array. + dtype : str + If there are no floating point input arrays (all integral inputs for + instance), return the default floating point dtype for the namespace. """ dtype = _find_matching_floating_dtype(y_true, y_pred, sample_weight, xp=xp) From ad5cdea00113a68fcb4b61a47abec26489c76187 Mon Sep 17 00:00:00 2001 From: virchan Date: Mon, 21 Oct 2024 19:12:22 -0700 Subject: [PATCH 07/27] Update `_regression.py`. --- sklearn/metrics/_regression.py | 1 - 1 file changed, 1 deletion(-) diff --git a/sklearn/metrics/_regression.py b/sklearn/metrics/_regression.py index 7bcbf755e5c0e..85fd9201c81f9 100644 --- a/sklearn/metrics/_regression.py +++ b/sklearn/metrics/_regression.py @@ -150,7 +150,6 @@ def _check_reg_targets_and_floating_dtype( y_pred : array-like sample_weight : array-like of shape (n_samples,) - Sample weights. multioutput : array-like or string in ['raw_values', uniform_average', 'variance_weighted'] or None From 8cc25838d7406b4d371c4bc3cbfd42a239e92dc4 Mon Sep 17 00:00:00 2001 From: Virgil Chan Date: Tue, 22 Oct 2024 00:19:44 -0700 Subject: [PATCH 08/27] Update sklearn/metrics/_regression.py Co-authored-by: Adrin Jalali --- sklearn/metrics/_regression.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sklearn/metrics/_regression.py b/sklearn/metrics/_regression.py index 85fd9201c81f9..9255861ec2fc0 100644 --- a/sklearn/metrics/_regression.py +++ b/sklearn/metrics/_regression.py @@ -151,7 +151,7 @@ def _check_reg_targets_and_floating_dtype( sample_weight : array-like of shape (n_samples,) - multioutput : array-like or string in ['raw_values', uniform_average', + multioutput : array-like or string in ['raw_values', 'uniform_average', \ 'variance_weighted'] or None None is accepted due to backward compatibility of r2_score(). From b94082759ff3a1d3f20ee4661f76024d9e45519c Mon Sep 17 00:00:00 2001 From: Virgil Chan Date: Tue, 22 Oct 2024 00:20:07 -0700 Subject: [PATCH 09/27] Update sklearn/metrics/_regression.py Co-authored-by: Adrin Jalali --- sklearn/metrics/_regression.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sklearn/metrics/_regression.py b/sklearn/metrics/_regression.py index 9255861ec2fc0..de6fe63527047 100644 --- a/sklearn/metrics/_regression.py +++ b/sklearn/metrics/_regression.py @@ -162,7 +162,7 @@ def _check_reg_targets_and_floating_dtype( Returns ------- - type_true : one of {'continuous', continuous-multioutput'} + type_true : one of {'continuous', 'continuous-multioutput'} The type of the true target data, as output by 'utils.multiclass.type_of_target'. From dafacafd6432dd9e158156ece6c4c5fa2c3d5d6c Mon Sep 17 00:00:00 2001 From: Virgil Chan Date: Tue, 22 Oct 2024 00:20:20 -0700 Subject: [PATCH 10/27] Update sklearn/metrics/_regression.py Co-authored-by: Adrin Jalali --- sklearn/metrics/_regression.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sklearn/metrics/_regression.py b/sklearn/metrics/_regression.py index de6fe63527047..667264454311a 100644 --- a/sklearn/metrics/_regression.py +++ b/sklearn/metrics/_regression.py @@ -175,8 +175,8 @@ def _check_reg_targets_and_floating_dtype( sample_weight : array-like of shape (n_samples,), default=None Sample weights. - multioutput : array-like of shape (n_outputs) or string in ['raw_values', - uniform_average', 'variance_weighted'] or None + multioutput : array-like of shape (n_outputs) or string in ['raw_values', \ + 'uniform_average', 'variance_weighted'] or None Custom output weights if ``multioutput`` is array-like or just the corresponding argument if ``multioutput`` is a correct keyword. From 1ba7c37e3a359832399eaf3a216f6fe507cc4b2f Mon Sep 17 00:00:00 2001 From: virchan Date: Tue, 22 Oct 2024 00:24:53 -0700 Subject: [PATCH 11/27] Remove changelog and add `xp` back to `max_error`. --- doc/whats_new/upcoming_changes/array-api/30128.other.rst | 3 --- sklearn/metrics/_regression.py | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) delete mode 100644 doc/whats_new/upcoming_changes/array-api/30128.other.rst diff --git a/doc/whats_new/upcoming_changes/array-api/30128.other.rst b/doc/whats_new/upcoming_changes/array-api/30128.other.rst deleted file mode 100644 index 615fc6d7b5adc..0000000000000 --- a/doc/whats_new/upcoming_changes/array-api/30128.other.rst +++ /dev/null @@ -1,3 +0,0 @@ -- Introduce a new function `_check_reg_targets_and_floating_dtype` to - streamline regression task and floating type checks for regression metrics. - By :user:`Virgil Chan ` \ No newline at end of file diff --git a/sklearn/metrics/_regression.py b/sklearn/metrics/_regression.py index 667264454311a..bff9fa5e5f88c 100644 --- a/sklearn/metrics/_regression.py +++ b/sklearn/metrics/_regression.py @@ -1313,7 +1313,7 @@ def max_error(y_true, y_pred): np.int64(1) """ xp, _ = get_namespace(y_true, y_pred) - y_type, y_true, y_pred, _ = _check_reg_targets(y_true, y_pred, None) + y_type, y_true, y_pred, _ = _check_reg_targets(y_true, y_pred, None, xp=xp) if y_type == "continuous-multioutput": raise ValueError("Multioutput not supported in max_error") return xp.max(xp.abs(y_true - y_pred)) From f53172e38ca7443e3b594dd9b4315e2d59bc3702 Mon Sep 17 00:00:00 2001 From: virchan Date: Tue, 22 Oct 2024 01:01:24 -0700 Subject: [PATCH 12/27] Update `_check_reg_targets` doc-string. --- sklearn/metrics/_regression.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sklearn/metrics/_regression.py b/sklearn/metrics/_regression.py index bff9fa5e5f88c..d00ac60a40a2f 100644 --- a/sklearn/metrics/_regression.py +++ b/sklearn/metrics/_regression.py @@ -58,6 +58,10 @@ def _check_reg_targets(y_true, y_pred, multioutput, dtype="numeric", xp=None): """Check that y_true and y_pred belong to the same regression task. + To reduce redundancy when calling `_find_matching_floating_dtype`, + please use `_check_reg_targets_and_floating_dtype` instead. + + Parameters ---------- y_true : array-like From 0e3cfae65533db176ceb3188b095afc236bb08ed Mon Sep 17 00:00:00 2001 From: virchan Date: Wed, 23 Oct 2024 14:28:31 -0700 Subject: [PATCH 13/27] Update variable name to `dtype_name`. --- sklearn/metrics/_regression.py | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/sklearn/metrics/_regression.py b/sklearn/metrics/_regression.py index d00ac60a40a2f..69cbdaf9d1461 100644 --- a/sklearn/metrics/_regression.py +++ b/sklearn/metrics/_regression.py @@ -61,7 +61,6 @@ def _check_reg_targets(y_true, y_pred, multioutput, dtype="numeric", xp=None): To reduce redundancy when calling `_find_matching_floating_dtype`, please use `_check_reg_targets_and_floating_dtype` instead. - Parameters ---------- y_true : array-like @@ -144,8 +143,10 @@ def _check_reg_targets(y_true, y_pred, multioutput, dtype="numeric", xp=None): def _check_reg_targets_and_floating_dtype( y_true, y_pred, sample_weight, multioutput, xp=None ): - """Ensure that y_true and y_pred correspond to the same regression task, - and select an appropriate floating-point data type when computing with arrays. + """Ensure that y_true and y_pred correspond to the same regression task. + + This helper automatically selects an appropriate floating-point data type when + computing with inputs that follow the array API specification. Parameters ---------- @@ -185,17 +186,17 @@ def _check_reg_targets_and_floating_dtype( just the corresponding argument if ``multioutput`` is a correct keyword. - dtype : str + dtype_name : str If there are no floating point input arrays (all integral inputs for instance), return the default floating point dtype for the namespace. """ - dtype = _find_matching_floating_dtype(y_true, y_pred, sample_weight, xp=xp) + dtype_name = _find_matching_floating_dtype(y_true, y_pred, sample_weight, xp=xp) y_type, y_true, y_pred, multioutput = _check_reg_targets( - y_true, y_pred, multioutput, dtype=dtype, xp=xp + y_true, y_pred, multioutput, dtype=dtype_name, xp=xp ) - return y_type, y_true, y_pred, sample_weight, multioutput, dtype + return y_type, y_true, y_pred, sample_weight, multioutput, dtype_name @validate_params( @@ -264,7 +265,7 @@ def mean_absolute_error( """ xp, _ = get_namespace(y_true, y_pred, sample_weight, multioutput) - _, y_true, y_pred, sample_weight, multioutput, dtype = ( + _, y_true, y_pred, sample_weight, multioutput, _ = ( _check_reg_targets_and_floating_dtype( y_true, y_pred, sample_weight, multioutput, xp=xp ) @@ -460,15 +461,15 @@ def mean_absolute_percentage_error( 112589990684262.48 """ xp, _ = get_namespace(y_true, y_pred, sample_weight, multioutput) - _, y_true, y_pred, sample_weight, multioutput, dtype = ( + _, y_true, y_pred, sample_weight, multioutput, dtype_name = ( _check_reg_targets_and_floating_dtype( y_true, y_pred, sample_weight, multioutput, xp=xp ) ) check_consistent_length(y_true, y_pred, sample_weight) - epsilon = xp.asarray(xp.finfo(xp.float64).eps, dtype=dtype) - y_true_abs = xp.asarray(xp.abs(y_true), dtype=dtype) - mape = xp.asarray(xp.abs(y_pred - y_true), dtype=dtype) / xp.maximum( + epsilon = xp.asarray(xp.finfo(xp.float64).eps, dtype=dtype_name) + y_true_abs = xp.asarray(xp.abs(y_true), dtype=dtype_name) + mape = xp.asarray(xp.abs(y_pred - y_true), dtype=dtype_name) / xp.maximum( y_true_abs, epsilon ) output_errors = _average(mape, weights=sample_weight, axis=0) @@ -1246,7 +1247,7 @@ def r2_score( y_true, y_pred, sample_weight, multioutput ) - _, y_true, y_pred, sample_weight, multioutput, dtype = ( + _, y_true, y_pred, sample_weight, multioutput, _ = ( _check_reg_targets_and_floating_dtype( y_true, y_pred, sample_weight, multioutput, xp=xp ) @@ -1260,7 +1261,7 @@ def r2_score( return float("nan") if sample_weight is not None: - sample_weight = column_or_1d(sample_weight, dtype=dtype) + sample_weight = column_or_1d(sample_weight, dtype=dtype_name) weight = sample_weight[:, None] else: weight = 1.0 From 4b844a0ce8e4519033f2b4687c2f850b7eea0600 Mon Sep 17 00:00:00 2001 From: virchan Date: Wed, 23 Oct 2024 17:05:21 -0700 Subject: [PATCH 14/27] Update `r2_score`. --- sklearn/metrics/_regression.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sklearn/metrics/_regression.py b/sklearn/metrics/_regression.py index 69cbdaf9d1461..a7623cca6e759 100644 --- a/sklearn/metrics/_regression.py +++ b/sklearn/metrics/_regression.py @@ -1261,7 +1261,7 @@ def r2_score( return float("nan") if sample_weight is not None: - sample_weight = column_or_1d(sample_weight, dtype=dtype_name) + sample_weight = column_or_1d(sample_weight) weight = sample_weight[:, None] else: weight = 1.0 From 08ee432e29334368c590b807ed2cabd438d95b97 Mon Sep 17 00:00:00 2001 From: virchan Date: Wed, 23 Oct 2024 17:32:16 -0700 Subject: [PATCH 15/27] Fix linting. --- sklearn/metrics/_regression.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/sklearn/metrics/_regression.py b/sklearn/metrics/_regression.py index a7623cca6e759..714c49ab29bdf 100644 --- a/sklearn/metrics/_regression.py +++ b/sklearn/metrics/_regression.py @@ -144,9 +144,10 @@ def _check_reg_targets_and_floating_dtype( y_true, y_pred, sample_weight, multioutput, xp=None ): """Ensure that y_true and y_pred correspond to the same regression task. - - This helper automatically selects an appropriate floating-point data type when - computing with inputs that follow the array API specification. + + This helper automatically selects a floating-point data type with + `_find_matching_floating_dtype` when computing with inputs that + follow the array API specification. Parameters ---------- From f9ee0f7f3aaf1203a4b4e3fa907610ad88265c77 Mon Sep 17 00:00:00 2001 From: virchan Date: Thu, 24 Oct 2024 18:07:31 -0700 Subject: [PATCH 16/27] Update `_check_reg_targets_and_floating_dtype`. --- sklearn/metrics/_regression.py | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/sklearn/metrics/_regression.py b/sklearn/metrics/_regression.py index 714c49ab29bdf..cac4e51a2ad6a 100644 --- a/sklearn/metrics/_regression.py +++ b/sklearn/metrics/_regression.py @@ -149,6 +149,10 @@ def _check_reg_targets_and_floating_dtype( `_find_matching_floating_dtype` when computing with inputs that follow the array API specification. + To inspect the resulting floating-point data type, users can access the + `.dtype` attribute of the returned arrays, e.g., `y_true.dtype` or + `y_pred.dtype`. + Parameters ---------- y_true : array-like @@ -187,9 +191,6 @@ def _check_reg_targets_and_floating_dtype( just the corresponding argument if ``multioutput`` is a correct keyword. - dtype_name : str - If there are no floating point input arrays (all integral inputs for - instance), return the default floating point dtype for the namespace. """ dtype_name = _find_matching_floating_dtype(y_true, y_pred, sample_weight, xp=xp) @@ -197,7 +198,7 @@ def _check_reg_targets_and_floating_dtype( y_true, y_pred, multioutput, dtype=dtype_name, xp=xp ) - return y_type, y_true, y_pred, sample_weight, multioutput, dtype_name + return y_type, y_true, y_pred, sample_weight, multioutput @validate_params( @@ -266,7 +267,7 @@ def mean_absolute_error( """ xp, _ = get_namespace(y_true, y_pred, sample_weight, multioutput) - _, y_true, y_pred, sample_weight, multioutput, _ = ( + _, y_true, y_pred, sample_weight, multioutput = ( _check_reg_targets_and_floating_dtype( y_true, y_pred, sample_weight, multioutput, xp=xp ) @@ -462,17 +463,15 @@ def mean_absolute_percentage_error( 112589990684262.48 """ xp, _ = get_namespace(y_true, y_pred, sample_weight, multioutput) - _, y_true, y_pred, sample_weight, multioutput, dtype_name = ( + _, y_true, y_pred, sample_weight, multioutput = ( _check_reg_targets_and_floating_dtype( y_true, y_pred, sample_weight, multioutput, xp=xp ) ) check_consistent_length(y_true, y_pred, sample_weight) - epsilon = xp.asarray(xp.finfo(xp.float64).eps, dtype=dtype_name) - y_true_abs = xp.asarray(xp.abs(y_true), dtype=dtype_name) - mape = xp.asarray(xp.abs(y_pred - y_true), dtype=dtype_name) / xp.maximum( - y_true_abs, epsilon - ) + epsilon = xp.asarray(xp.finfo(xp.float64).eps, dtype=y_true.dtype) + y_true_abs = xp.abs(y_true) + mape = xp.abs(y_pred - y_true) / xp.maximum(y_true_abs, epsilon) output_errors = _average(mape, weights=sample_weight, axis=0) if isinstance(multioutput, str): if multioutput == "raw_values": @@ -556,7 +555,7 @@ def mean_squared_error( 0.825... """ xp, _ = get_namespace(y_true, y_pred, sample_weight, multioutput) - _, y_true, y_pred, sample_weight, multioutput, _ = ( + _, y_true, y_pred, sample_weight, multioutput = ( _check_reg_targets_and_floating_dtype( y_true, y_pred, sample_weight, multioutput, xp=xp ) @@ -733,7 +732,7 @@ def mean_squared_log_error( """ xp, _ = get_namespace(y_true, y_pred) - _, y_true, y_pred, _, _, _ = _check_reg_targets_and_floating_dtype( + _, y_true, y_pred, _, _ = _check_reg_targets_and_floating_dtype( y_true, y_pred, sample_weight, multioutput, xp=xp ) @@ -809,7 +808,7 @@ def root_mean_squared_log_error( """ xp, _ = get_namespace(y_true, y_pred) - _, y_true, y_pred, _, _, _ = _check_reg_targets_and_floating_dtype( + _, y_true, y_pred, _, _ = _check_reg_targets_and_floating_dtype( y_true, y_pred, sample_weight, multioutput, xp=xp ) @@ -1248,7 +1247,7 @@ def r2_score( y_true, y_pred, sample_weight, multioutput ) - _, y_true, y_pred, sample_weight, multioutput, _ = ( + _, y_true, y_pred, sample_weight, multioutput = ( _check_reg_targets_and_floating_dtype( y_true, y_pred, sample_weight, multioutput, xp=xp ) @@ -1417,7 +1416,7 @@ def mean_tweedie_deviance(y_true, y_pred, *, sample_weight=None, power=0): 1.4260... """ xp, _ = get_namespace(y_true, y_pred) - y_type, y_true, y_pred, sample_weight, _, _ = _check_reg_targets_and_floating_dtype( + y_type, y_true, y_pred, sample_weight, _ = _check_reg_targets_and_floating_dtype( y_true, y_pred, sample_weight, multioutput=None, xp=xp ) if y_type == "continuous-multioutput": @@ -1631,7 +1630,7 @@ def d2_tweedie_score(y_true, y_pred, *, sample_weight=None, power=0): """ xp, _ = get_namespace(y_true, y_pred) - y_type, y_true, y_pred, sample_weight, _, _ = _check_reg_targets_and_floating_dtype( + y_type, y_true, y_pred, sample_weight, _ = _check_reg_targets_and_floating_dtype( y_true, y_pred, sample_weight, multioutput=None, xp=xp ) if y_type == "continuous-multioutput": From fc0f593ebd0f62d86fabd2e1499b10ceb839c347 Mon Sep 17 00:00:00 2001 From: Virgil Chan Date: Fri, 25 Oct 2024 09:24:23 -0700 Subject: [PATCH 17/27] Update sklearn/metrics/_regression.py Co-authored-by: Olivier Grisel --- sklearn/metrics/_regression.py | 1 - 1 file changed, 1 deletion(-) diff --git a/sklearn/metrics/_regression.py b/sklearn/metrics/_regression.py index cac4e51a2ad6a..22d93b0d35588 100644 --- a/sklearn/metrics/_regression.py +++ b/sklearn/metrics/_regression.py @@ -190,7 +190,6 @@ def _check_reg_targets_and_floating_dtype( Custom output weights if ``multioutput`` is array-like or just the corresponding argument if ``multioutput`` is a correct keyword. - """ dtype_name = _find_matching_floating_dtype(y_true, y_pred, sample_weight, xp=xp) From 635c8836af9dc4e95ec22098a288df7c3aedbd5b Mon Sep 17 00:00:00 2001 From: Virgil Chan Date: Fri, 25 Oct 2024 09:25:29 -0700 Subject: [PATCH 18/27] Update sklearn/metrics/_regression.py Co-authored-by: Olivier Grisel --- sklearn/metrics/_regression.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/sklearn/metrics/_regression.py b/sklearn/metrics/_regression.py index 22d93b0d35588..8979d19b94218 100644 --- a/sklearn/metrics/_regression.py +++ b/sklearn/metrics/_regression.py @@ -147,11 +147,8 @@ def _check_reg_targets_and_floating_dtype( This helper automatically selects a floating-point data type with `_find_matching_floating_dtype` when computing with inputs that - follow the array API specification. - - To inspect the resulting floating-point data type, users can access the - `.dtype` attribute of the returned arrays, e.g., `y_true.dtype` or - `y_pred.dtype`. + follow the array API specification and ensure that all non-None inputs + are converted to that common dtype if needed before returning them. Parameters ---------- From eccc7f1ba8ef8aab13b57c7312c9e53a705b7402 Mon Sep 17 00:00:00 2001 From: virchan Date: Fri, 25 Oct 2024 09:33:24 -0700 Subject: [PATCH 19/27] Rename `_check_reg_targets_and_floating_dtype` to `_check_reg_targets_with_floating_dtype`. --- sklearn/metrics/_regression.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/sklearn/metrics/_regression.py b/sklearn/metrics/_regression.py index 8979d19b94218..720497147190d 100644 --- a/sklearn/metrics/_regression.py +++ b/sklearn/metrics/_regression.py @@ -59,7 +59,7 @@ def _check_reg_targets(y_true, y_pred, multioutput, dtype="numeric", xp=None): """Check that y_true and y_pred belong to the same regression task. To reduce redundancy when calling `_find_matching_floating_dtype`, - please use `_check_reg_targets_and_floating_dtype` instead. + please use `_check_reg_targets_with_floating_dtype` instead. Parameters ---------- @@ -140,7 +140,7 @@ def _check_reg_targets(y_true, y_pred, multioutput, dtype="numeric", xp=None): return y_type, y_true, y_pred, multioutput -def _check_reg_targets_and_floating_dtype( +def _check_reg_targets_with_floating_dtype( y_true, y_pred, sample_weight, multioutput, xp=None ): """Ensure that y_true and y_pred correspond to the same regression task. @@ -264,7 +264,7 @@ def mean_absolute_error( xp, _ = get_namespace(y_true, y_pred, sample_weight, multioutput) _, y_true, y_pred, sample_weight, multioutput = ( - _check_reg_targets_and_floating_dtype( + _check_reg_targets_with_floating_dtype( y_true, y_pred, sample_weight, multioutput, xp=xp ) ) @@ -460,7 +460,7 @@ def mean_absolute_percentage_error( """ xp, _ = get_namespace(y_true, y_pred, sample_weight, multioutput) _, y_true, y_pred, sample_weight, multioutput = ( - _check_reg_targets_and_floating_dtype( + _check_reg_targets_with_floating_dtype( y_true, y_pred, sample_weight, multioutput, xp=xp ) ) @@ -552,7 +552,7 @@ def mean_squared_error( """ xp, _ = get_namespace(y_true, y_pred, sample_weight, multioutput) _, y_true, y_pred, sample_weight, multioutput = ( - _check_reg_targets_and_floating_dtype( + _check_reg_targets_with_floating_dtype( y_true, y_pred, sample_weight, multioutput, xp=xp ) ) @@ -728,7 +728,7 @@ def mean_squared_log_error( """ xp, _ = get_namespace(y_true, y_pred) - _, y_true, y_pred, _, _ = _check_reg_targets_and_floating_dtype( + _, y_true, y_pred, _, _ = _check_reg_targets_with_floating_dtype( y_true, y_pred, sample_weight, multioutput, xp=xp ) @@ -804,7 +804,7 @@ def root_mean_squared_log_error( """ xp, _ = get_namespace(y_true, y_pred) - _, y_true, y_pred, _, _ = _check_reg_targets_and_floating_dtype( + _, y_true, y_pred, _, _ = _check_reg_targets_with_floating_dtype( y_true, y_pred, sample_weight, multioutput, xp=xp ) @@ -1244,7 +1244,7 @@ def r2_score( ) _, y_true, y_pred, sample_weight, multioutput = ( - _check_reg_targets_and_floating_dtype( + _check_reg_targets_with_floating_dtype( y_true, y_pred, sample_weight, multioutput, xp=xp ) ) @@ -1412,7 +1412,7 @@ def mean_tweedie_deviance(y_true, y_pred, *, sample_weight=None, power=0): 1.4260... """ xp, _ = get_namespace(y_true, y_pred) - y_type, y_true, y_pred, sample_weight, _ = _check_reg_targets_and_floating_dtype( + y_type, y_true, y_pred, sample_weight, _ = _check_reg_targets_with_floating_dtype( y_true, y_pred, sample_weight, multioutput=None, xp=xp ) if y_type == "continuous-multioutput": @@ -1626,7 +1626,7 @@ def d2_tweedie_score(y_true, y_pred, *, sample_weight=None, power=0): """ xp, _ = get_namespace(y_true, y_pred) - y_type, y_true, y_pred, sample_weight, _ = _check_reg_targets_and_floating_dtype( + y_type, y_true, y_pred, sample_weight, _ = _check_reg_targets_with_floating_dtype( y_true, y_pred, sample_weight, multioutput=None, xp=xp ) if y_type == "continuous-multioutput": From 64d5e9503cecc371e55a73fcf0b547ad84998c25 Mon Sep 17 00:00:00 2001 From: virchan Date: Sat, 2 Nov 2024 09:59:18 +0900 Subject: [PATCH 20/27] Updating `_check_reg_targets` and _check_reg_targets_with_floating_dtype` doc-strings. --- sklearn/metrics/_regression.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/sklearn/metrics/_regression.py b/sklearn/metrics/_regression.py index 720497147190d..446785dfab29e 100644 --- a/sklearn/metrics/_regression.py +++ b/sklearn/metrics/_regression.py @@ -63,9 +63,11 @@ def _check_reg_targets(y_true, y_pred, multioutput, dtype="numeric", xp=None): Parameters ---------- - y_true : array-like + y_true : array-like of shape (n_samples,) or (n_samples, n_outputs) + Ground truth (correct) target values. - y_pred : array-like + y_pred : array-like of shape (n_samples,) or (n_samples, n_outputs) + Estimated target values. multioutput : array-like or string in ['raw_values', uniform_average', 'variance_weighted'] or None @@ -152,9 +154,11 @@ def _check_reg_targets_with_floating_dtype( Parameters ---------- - y_true : array-like + y_true : array-like of shape (n_samples,) or (n_samples, n_outputs) + Ground truth (correct) target values. - y_pred : array-like + y_pred : array-like of shape (n_samples,) or (n_samples, n_outputs) + Estimated target values. sample_weight : array-like of shape (n_samples,) From e772fe258855326c932a8745f541f156b297213e Mon Sep 17 00:00:00 2001 From: virchan Date: Sat, 2 Nov 2024 10:15:09 +0900 Subject: [PATCH 21/27] Updating `_check_reg_targets_with_floating_dtype` to convert `sample_weight`'s data-type. --- sklearn/metrics/_regression.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sklearn/metrics/_regression.py b/sklearn/metrics/_regression.py index 446785dfab29e..5e3a4269ab4de 100644 --- a/sklearn/metrics/_regression.py +++ b/sklearn/metrics/_regression.py @@ -194,8 +194,8 @@ def _check_reg_targets_with_floating_dtype( """ dtype_name = _find_matching_floating_dtype(y_true, y_pred, sample_weight, xp=xp) - y_type, y_true, y_pred, multioutput = _check_reg_targets( - y_true, y_pred, multioutput, dtype=dtype_name, xp=xp + y_type, y_true, y_pred, sample_weight, multioutput = _check_reg_targets( + y_true, y_pred, sample_weight, multioutput, dtype=dtype_name, xp=xp ) return y_type, y_true, y_pred, sample_weight, multioutput From ed6224ca073e43b8ee8127b40a7de99f196a1441 Mon Sep 17 00:00:00 2001 From: virchan Date: Sat, 2 Nov 2024 11:01:17 +0900 Subject: [PATCH 22/27] Updating `_check_reg_targets_with_floating_dtype` --- sklearn/metrics/_regression.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sklearn/metrics/_regression.py b/sklearn/metrics/_regression.py index 5e3a4269ab4de..446785dfab29e 100644 --- a/sklearn/metrics/_regression.py +++ b/sklearn/metrics/_regression.py @@ -194,8 +194,8 @@ def _check_reg_targets_with_floating_dtype( """ dtype_name = _find_matching_floating_dtype(y_true, y_pred, sample_weight, xp=xp) - y_type, y_true, y_pred, sample_weight, multioutput = _check_reg_targets( - y_true, y_pred, sample_weight, multioutput, dtype=dtype_name, xp=xp + y_type, y_true, y_pred, multioutput = _check_reg_targets( + y_true, y_pred, multioutput, dtype=dtype_name, xp=xp ) return y_type, y_true, y_pred, sample_weight, multioutput From c5075137a5f41d9a18a09a18cc1e16728c31902f Mon Sep 17 00:00:00 2001 From: virchan Date: Sun, 3 Nov 2024 01:09:20 +0900 Subject: [PATCH 23/27] Updating `_check_reg_targets_with_floating_dtype`. --- sklearn/metrics/_regression.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sklearn/metrics/_regression.py b/sklearn/metrics/_regression.py index 446785dfab29e..b90276defcfc1 100644 --- a/sklearn/metrics/_regression.py +++ b/sklearn/metrics/_regression.py @@ -198,6 +198,10 @@ def _check_reg_targets_with_floating_dtype( y_true, y_pred, multioutput, dtype=dtype_name, xp=xp ) + # _check_reg_targets does not accept sample_weight as input. + # Convert sample_weight's data type separately to match dtype_name. + sample_weight = sample_weight.astype(dtype_name) + return y_type, y_true, y_pred, sample_weight, multioutput From 8d7507d1895adaca046e81b53d6a750e2bf07b03 Mon Sep 17 00:00:00 2001 From: virchan Date: Sun, 3 Nov 2024 01:46:32 +0900 Subject: [PATCH 24/27] Updating `_check_reg_targets_with_floating_dtype`. --- sklearn/metrics/_regression.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sklearn/metrics/_regression.py b/sklearn/metrics/_regression.py index b90276defcfc1..5976cb810dce8 100644 --- a/sklearn/metrics/_regression.py +++ b/sklearn/metrics/_regression.py @@ -200,7 +200,8 @@ def _check_reg_targets_with_floating_dtype( # _check_reg_targets does not accept sample_weight as input. # Convert sample_weight's data type separately to match dtype_name. - sample_weight = sample_weight.astype(dtype_name) + if sample_weight is not None: + sample_weight = _check_sample_weight(sample_weight, y_pred, dtype=dtype_name) return y_type, y_true, y_pred, sample_weight, multioutput From 63c34f516a6b20cc2940dc11aff7ac83acdcba8c Mon Sep 17 00:00:00 2001 From: virchan Date: Sun, 3 Nov 2024 08:33:27 +0900 Subject: [PATCH 25/27] Updating `_check_reg_targets_with_floating_dtype`. --- sklearn/metrics/_regression.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sklearn/metrics/_regression.py b/sklearn/metrics/_regression.py index 5976cb810dce8..bcb8697060720 100644 --- a/sklearn/metrics/_regression.py +++ b/sklearn/metrics/_regression.py @@ -201,7 +201,7 @@ def _check_reg_targets_with_floating_dtype( # _check_reg_targets does not accept sample_weight as input. # Convert sample_weight's data type separately to match dtype_name. if sample_weight is not None: - sample_weight = _check_sample_weight(sample_weight, y_pred, dtype=dtype_name) + sample_weight = sample_weight.astype(dtype_name) return y_type, y_true, y_pred, sample_weight, multioutput From ee66bd2dfd5944e22db347e6465f3ca71ab8d686 Mon Sep 17 00:00:00 2001 From: virchan Date: Sun, 3 Nov 2024 10:05:57 +0900 Subject: [PATCH 26/27] Updating `_check_reg_targets_with_floating_dtype`. --- sklearn/metrics/_regression.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sklearn/metrics/_regression.py b/sklearn/metrics/_regression.py index bcb8697060720..007e61f928b58 100644 --- a/sklearn/metrics/_regression.py +++ b/sklearn/metrics/_regression.py @@ -201,7 +201,7 @@ def _check_reg_targets_with_floating_dtype( # _check_reg_targets does not accept sample_weight as input. # Convert sample_weight's data type separately to match dtype_name. if sample_weight is not None: - sample_weight = sample_weight.astype(dtype_name) + sample_weight = xp.asarray(sample_weight, dtype=dtype_name) return y_type, y_true, y_pred, sample_weight, multioutput From e868d9d71f7c2129d3323acdf5eaeb545619b9a5 Mon Sep 17 00:00:00 2001 From: virchan Date: Mon, 18 Nov 2024 23:53:50 +0800 Subject: [PATCH 27/27] Update `_check_reg_targets_with_floating_dtype` doc-string. --- sklearn/metrics/_regression.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/sklearn/metrics/_regression.py b/sklearn/metrics/_regression.py index 007e61f928b58..c5ebe67e34a2e 100644 --- a/sklearn/metrics/_regression.py +++ b/sklearn/metrics/_regression.py @@ -145,12 +145,13 @@ def _check_reg_targets(y_true, y_pred, multioutput, dtype="numeric", xp=None): def _check_reg_targets_with_floating_dtype( y_true, y_pred, sample_weight, multioutput, xp=None ): - """Ensure that y_true and y_pred correspond to the same regression task. + """Ensures that y_true, y_pred, and sample_weight correspond to the same + regression task. - This helper automatically selects a floating-point data type with - `_find_matching_floating_dtype` when computing with inputs that - follow the array API specification and ensure that all non-None inputs - are converted to that common dtype if needed before returning them. + Extends `_check_reg_targets` by automatically selecting a suitable floating-point + data type for inputs using `_find_matching_floating_dtype`. + + Use this private method only when converting inputs to array API-compatibles. Parameters ----------