8000 ENH Adds get_feature_names to manifold module (#22254) · scikit-learn/scikit-learn@3fd84f7 · GitHub
[go: up one dir, main page]

Skip to content

Commit 3fd84f7

Browse files
authored
ENH Adds get_feature_names to manifold module (#22254)
1 parent 64782c0 commit 3fd84f7

File tree

6 files changed

+55
-7
lines changed

6 files changed

+55
-7
lines changed

doc/whats_new/v1.1.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -417,6 +417,9 @@ Changelog
417417
preserve this dtype.
418418
:pr:`21534` by :user:`Andrew Knyazev <lobpcg>`.
419419

420+
- |Enhancement| Adds `get_feature_names_out` to :class:`manifold.Isomap`
421+
and :class:`manifold.LocallyLinearEmbedding`. :pr:`22254` by `Thomas Fan`_.
422+
420423
- |Fix| :func:`manifold.spectral_embedding` now uses Gaussian instead of
421424
the previous uniform on [0, 1] random initial approximations to eigenvectors
422425
in eigen_solvers `lobpcg` and `amg` to improve their numerical stability.

sklearn/manifold/_isomap.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
from scipy.sparse.csgraph import shortest_path
1111
from scipy.sparse.csgraph import connected_components
1212

13-
from ..base import BaseEstimator, TransformerMixin
13+
from ..base import BaseEstimator, TransformerMixin, _ClassNamePrefixFeaturesOutMixin
1414
from ..neighbors import NearestNeighbors, kneighbors_graph
1515
from ..utils.validation import check_is_fitted
1616
from ..decomposition import KernelPCA
@@ -19,7 +19,7 @@
1919
from ..externals._packaging.version import parse as parse_version
2020

2121

22-
class Isomap(TransformerMixin, BaseEstimator):
22+
class Isomap(_ClassNamePrefixFeaturesOutMixin, TransformerMixin, BaseEstimator):
2323
"""Isomap Embedding.
2424
2525
Non-linear dimensionality reduction through Isometric Mapping
@@ -257,6 +257,7 @@ def _fit_transform(self, X):
257257
G *= -0.5
258258

259259
self.embedding_ = self.kernel_pca_.fit_transform(G)
260+
self._n_features_out = self.embedding_.shape[1]
260261

261262
def reconstruction_error(self):
262263
"""Compute the reconstruction error for the embedding.

sklearn/manifold/_locally_linear.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,12 @@
99
from scipy.sparse import eye, csr_matrix
1010
from scipy.sparse.linalg import eigsh
1111

12-
from ..base import BaseEstimator, TransformerMixin, _UnstableArchMixin
12+
from ..base import (
13+
BaseEstimator,
14+
TransformerMixin,
15+
_UnstableArchMixin,
16+
_ClassNamePrefixFeaturesOutMixin,
17+
)
1318
from ..utils import check_random_state, check_array
1419
from ..utils._arpack import _init_arpack_v0
1520
from ..utils.extmath import stable_cumsum
@@ -542,7 +547,12 @@ def locally_linear_embedding(
542547
)
543548

544549

545-
class LocallyLinearEmbedding(TransformerMixin, _UnstableArchMixin, BaseEstimator):
550+
class LocallyLinearEmbedding(
551+
_ClassNamePrefixFeaturesOutMixin,
552+
TransformerMixin,
553+
_UnstableArchMixin,
554+
BaseEstimator,
555+
):
546556
"""Locally Linear Embedding.
547557
548558
Read more in the :ref:`User Guide <locally_linear_embedding>`.
@@ -728,6 +738,7 @@ def _fit_transform(self, X):
728738
reg=self.reg,
729739
n_jobs=self.n_jobs,
730740
)
741+
self._n_features_out = self.embedding_.shape[1]
731742

732743
def fit(self, X, y=None):
733744
"""Compute the embedding vectors for data X.

sklearn/manifold/tests/test_isomap.py

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,18 @@
11
from itertools import product
22
import numpy as np
3-
from numpy.testing import assert_almost_equal, assert_array_almost_equal
3+
from numpy.testing import (
4+
assert_almost_equal,
5+
assert_array_almost_equal,
6+
assert_array_equal,
7+
)
48
import pytest
59

610
from sklearn import datasets
711
from sklearn import manifold
812
from sklearn import neighbors
913
from sklearn import pipeline
1014
from sklearn import preprocessing
15+
from sklearn.datasets import make_blobs
1116
from sklearn.metrics.pairwise import pairwise_distances
1217

1318
from scipy.sparse import rand as sparse_rand
@@ -220,3 +225,14 @@ def test_multiple_connected_components_metric_precomputed():
220225
X_graph = neighbors.kneighbors_graph(X, n_neighbors=2, mode="distance")
221226
with pytest.raises(RuntimeError, match="number of connected components"):
222227
manifold.Isomap(n_neighbors=1, metric="precomputed").fit(X_graph)
228+
229+
230+
def test_get_feature_names_out():
231+
"""Check get_feature_names_out for Isomap."""
232+
X, y = make_blobs(random_state=0, n_features=4)
233+
n_components = 2
234+
235+
iso = manifold.Isomap(n_components=n_components)
236+
iso.fit_transform(X)
237+
names = iso.get_feature_names_out()
238+
assert_array_equal([f"isomap{i}" for i in range(n_components)], names)

sklearn/manifold/tests/test_locally_linear.py

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
11
from itertools import product
22

33
import numpy as np
4-
from numpy.testing import assert_almost_equal, assert_array_almost_equal
4+
from numpy.testing import (
5+
assert_almost_equal,
6+
assert_array_almost_equal,
7+
assert_array_equal,
8+
)
59
from scipy import linalg
610
import pytest
711

812
from sklearn import neighbors, manifold
13+
from sklearn.datasets import make_blobs
914
from sklearn.manifold._locally_linear import barycenter_kneighbors_graph
1015
from sklearn.utils._testing import ignore_warnings
1116

@@ -159,3 +164,16 @@ def test_integer_input():
159164
for method in ["standard", "hessian", "modified", "ltsa"]:
160165
clf = manifold.LocallyLinearEmbedding(method=method, n_neighbors=10)
161166
clf.fit(X) # this previously raised a TypeError
167+
168+
169+
def test_get_feature_names_out():
170+
"""Check get_feature_names_out for LocallyLinearEmbedding."""
171+
X, y = make_blobs(random_state=0, n_features=4)
172+
n_components = 2
173+
174+
iso = manifold.LocallyLinearEmbedding(n_components=n_components)
175+
iso.fit(X)
176+
names = iso.get_feature_names_out()
177+
assert_array_equal(
178+
[f"locallylinearembedding{i}" for i in range(n_components)], names
179+
)

sklearn/tests/test_common.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -384,7 +384,6 @@ def test_pandas_column_name_consistency(estimator):
384384
"isotonic",
385385
"kernel_approximation",
386386
"preprocessing",
387-
"manifold",
388387
"neural_network",
389388
]
390389

0 commit comments

Comments
 (0)
0