ENH Preserving dtype for np.float32 in SparsePCA and MiniBatchSparsePCA (#22111)

Co-authored-by: takoika <>
This commit is contained in:
Takeshi Oura 2022-01-05 01:39:14 +09:00 committed by GitHub
parent c398866732
commit cb4688ad15
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 56 additions and 0 deletions

View File

@ -168,6 +168,10 @@ Changelog
and :class:`decomposition.SparseCoder` preserve dtype for `numpy.float32`.
:pr:`22002` by :user:`Takeshi Oura <takoika>`.
- |Enhancement| :class:`decomposition.SparsePCA` and :class:`decomposition.MiniBatchSparsePCA`
preserve dtype for `numpy.float32`.
:pr:`22111` by :user:`Takeshi Oura <takoika>`.
- |API| Adds :term:`get_feature_names_out` to all transformers in the
:mod:`~sklearn.decomposition` module:
:class:`~sklearn.decomposition.DictionaryLearning`,

View File

@ -241,6 +241,11 @@ class SparsePCA(_ClassNamePrefixFeaturesOutMixin, TransformerMixin, BaseEstimato
"""Number of transformed output features."""
return self.components_.shape[0]
def _more_tags(self):
return {
"preserves_dtype": [np.float64, np.float32],
}
class MiniBatchSparsePCA(SparsePCA):
"""Mini-batch Sparse Principal Components Analysis.

View File

@ -206,6 +206,53 @@ def test_spca_n_components_(SPCA, n_components):
assert model.n_components_ == n_features
@pytest.mark.parametrize("SPCA", (SparsePCA, MiniBatchSparsePCA))
@pytest.mark.parametrize("method", ("lars", "cd"))
@pytest.mark.parametrize(
"data_type, expected_type",
(
(np.float32, np.float32),
(np.float64, np.float64),
(np.int32, np.float64),
(np.int64, np.float64),
),
)
def test_sparse_pca_dtype_match(SPCA, method, data_type, expected_type):
# Verify output matrix dtype
n_samples, n_features, n_components = 12, 10, 3
rng = np.random.RandomState(0)
input_array = rng.randn(n_samples, n_features).astype(data_type)
model = SPCA(n_components=n_components, method=method)
transformed = model.fit_transform(input_array)
assert transformed.dtype == expected_type
assert model.components_.dtype == expected_type
@pytest.mark.parametrize("SPCA", (SparsePCA, MiniBatchSparsePCA))
@pytest.mark.parametrize("method", ("lars", "cd"))
def test_sparse_pca_numerical_consistency(SPCA, method):
# Verify numericall consistentency among np.float32 and np.float64
rtol = 1e-3
alpha = 2
n_samples, n_features, n_components = 12, 10, 3
rng = np.random.RandomState(0)
input_array = rng.randn(n_samples, n_features)
model_32 = SPCA(
n_components=n_components, alpha=alpha, method=method, random_state=0
)
transformed_32 = model_32.fit_transform(input_array.astype(np.float32))
model_64 = SPCA(
n_components=n_components, alpha=alpha, method=method, random_state=0
)
transformed_64 = model_64.fit_transform(input_array.astype(np.float64))
assert_allclose(transformed_64, transformed_32, rtol=rtol)
assert_allclose(model_64.components_, model_32.components_, rtol=rtol)
@pytest.mark.parametrize("SPCA", [SparsePCA, MiniBatchSparsePCA])
def test_spca_feature_names_out(SPCA):
"""Check feature names out for *SparsePCA."""