Thanks to visit codestin.com
Credit goes to github.com

Skip to content

FIX Support F-contiguous arrays for PairwiseDistancesReductions-backed estimators #23990

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 14 commits into from
Aug 1, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions doc/whats_new/v1.1.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ Changelog
- |Fix| A default HTML representation is shown for meta-estimators with invalid
parameters. :pr:`24015` by `Thomas Fan`_.

- |Fix| Add support for F-contiguous arrays for estimators and functions whose back-end
have been changed in 1.1.
:pr:`23990` by :user:`Julien Jerphanion <jjerphan>`.

:mod:`sklearn.base`
......................

Expand Down
7 changes: 7 additions & 0 deletions sklearn/metrics/_pairwise_distances_reduction/_dispatcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,11 +80,18 @@ def is_usable_for(cls, X, Y, metric) -> bool:
True if the PairwiseDistancesReduction can be used, else False.
"""
dtypes_validity = X.dtype == Y.dtype == np.float64
c_contiguity = (
hasattr(X, "flags")
and X.flags.c_contiguous
and hasattr(Y, "flags")
and Y.flags.c_contiguous
)
return (
get_config().get("enable_cython_pairwise_dist", True)
and not issparse(X)
and not issparse(Y)
and dtypes_validity
and c_contiguity
and metric in cls.valid_metrics()
)

Expand Down
8 changes: 8 additions & 0 deletions sklearn/metrics/tests/test_pairwise.py
Original file line number Diff line number Diff line change
Expand Up @@ -534,6 +534,14 @@ def test_pairwise_distances_argmin_min(dtype):

assert_array_equal(argmin_0, argmin_1)

# F-contiguous arrays must be supported and must return identical results.
argmin_C_contiguous = pairwise_distances_argmin(X, Y)
argmin_F_contiguous = pairwise_distances_argmin(
np.asfortranarray(X), np.asfortranarray(Y)
)

assert_array_equal(argmin_C_contiguous, argmin_F_contiguous)


def _reduce_func(dist, start):
return dist[:, :100]
Expand Down
3 changes: 3 additions & 0 deletions sklearn/metrics/tests/test_pairwise_distances_reduction.py
Original file line number Diff line number Diff line change
Expand Up @@ -527,6 +527,9 @@ def test_pairwise_distances_reduction_is_usable_for():
assert not PairwiseDistancesReduction.is_usable_for(csr_matrix(X), Y, metric)
assert not PairwiseDistancesReduction.is_usable_for(X, csr_matrix(Y), metric)

# F-ordered arrays are not supported
assert not PairwiseDistancesReduction.is_usable_for(np.asfortranarray(X), Y, metric)


def test_argkmin_factory_method_wrong_usages():
rng = np.random.RandomState(1)
Expand Down
59 changes: 59 additions & 0 deletions sklearn/tests/test_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,24 @@
import pytest
import numpy as np

from sklearn.cluster import (
AffinityPropagation,
Birch,
MeanShift,
OPTICS,
SpectralClustering,
)
from sklearn.datasets import make_blobs
from sklearn.manifold import Isomap, TSNE, LocallyLinearEmbedding
from sklearn.neighbors import (
LocalOutlierFactor,
KNeighborsClassifier,
KNeighborsRegressor,
RadiusNeighborsClassifier,
RadiusNeighborsRegressor,
)
from sklearn.semi_supervised import LabelPropagation, LabelSpreading

from sklearn.utils import all_estimators
from sklearn.utils._testing import ignore_warnings
from sklearn.exceptions import ConvergenceWarning
Expand Down Expand Up @@ -518,3 +536,44 @@ def test_check_param_validation(estimator):
)
_set_checking_parameters(estimator)
check_param_validation(name, estimator)


# TODO: remove this filter in 1.2
@pytest.mark.filterwarnings("ignore::FutureWarning:sklearn")
@pytest.mark.parametrize(
"Estimator",
[
AffinityPropagation,
Birch,
MeanShift,
KNeighborsClassifier,
KNeighborsRegressor,
RadiusNeighborsClassifier,
RadiusNeighborsRegressor,
LabelPropagation,
LabelSpreading,
OPTICS,
SpectralClustering,
LocalOutlierFactor,
LocallyLinearEmbedding,
Isomap,
TSNE,
],
)
def test_f_contiguous_array_estimator(Estimator):
# Non-regression test for:
# https://github.com/scikit-learn/scikit-learn/issues/23988
# https://github.com/scikit-learn/scikit-learn/issues/24013

X, _ = make_blobs(n_samples=80, n_features=4, random_state=0)
X = np.asfortranarray(X)
y = np.round(X[:, 0])

est = Estimator()
est.fit(X, y)

if hasattr(est, "transform"):
est.transform(X)

if hasattr(est, "predict"):
est.predict(X)