34
34
SPARSE_MAX_COMPONENTS = min (SPARSE_M , SPARSE_N )
35
35
36
36
37
- def _check_fitted_pca_close (pca1 , pca2 , rtol ):
38
- assert_allclose (pca1 .components_ , pca2 .components_ , rtol = rtol )
39
- assert_allclose (pca1 .explained_variance_ , pca2 .explained_variance_ , rtol = rtol )
40
- assert_allclose (pca1 .singular_values_ , pca2 .singular_values_ , rtol = rtol )
41
- assert_allclose (pca1 .mean_ , pca2 .mean_ , rtol = rtol )
42
- assert_allclose (pca1 .n_components_ , pca2 .n_components_ , rtol = rtol )
43
- assert_allclose (pca1 .n_samples_ , pca2 .n_samples_ , rtol = rtol )
44
- assert_allclose (pca1 .noise_variance_ , pca2 .noise_variance_ , rtol = rtol )
45
- assert_allclose (pca1 .n_features_in_ , pca2 .n_features_in_ , rtol = rtol )
37
+ def _check_fitted_pca_close (pca1 , pca2 , rtol = 1e-7 , atol = 1e-12 ):
38
+ assert_allclose (pca1 .components_ , pca2 .components_ , rtol = rtol , atol = atol )
39
+ assert_allclose (
40
+ pca1 .explained_variance_ , pca2 .explained_variance_ , rtol = rtol , atol = atol
41
+ )
42
+ assert_allclose (pca1 .singular_values_ , pca2 .singular_values_ , rtol = rtol , atol = atol )
43
+ assert_allclose (pca1 .mean_ , pca2 .mean_ , rtol = rtol , atol = atol )
44
+ assert_allclose (pca1 .noise_variance_ , pca2 .noise_variance_ , rtol = rtol , atol = atol )
45
+
46
+ assert pca1 .n_components_ == pca2 .n_components_
47
+ assert pca1 .n_samples_ == pca2 .n_samples_
48
+ assert pca1 .n_features_in_ == pca2 .n_features_in_
46
49
47
50
48
51
@pytest .mark .parametrize ("svd_solver" , PCA_SOLVERS )
@@ -75,9 +78,12 @@ def test_pca(svd_solver, n_components):
75
78
def test_pca_sparse (
76
79
global_random_seed , svd_solver , sparse_container , n_components , density , scale
77
80
):
78
- # Make sure any tolerance changes pass with SKLEARN_TESTS_GLOBAL_RANDOM_SEED="all"
79
- rtol = 5e-07
80
- transform_rtol = 3e-05
81
+ """Check that the results are the same for sparse and dense input."""
82
+
83
+ # Set atol in addition of the default rtol to account for the very wide range of
84
+ # result values (1e-8 to 1e0).
85
+ atol = 1e-12
86
+ transform_atol = 1e-10
81
87
82
88
random_state = np .random .default_rng (global_random_seed )
83
89
X = sparse_container (
@@ -108,7 +114,7 @@ def test_pca_sparse(
108
114
pcad .fit (Xd )
109
115
110
116
# Fitted attributes equality
111
- _check_fitted_pca_close (pca , pcad , rtol = rtol )
117
+ _check_fitted_pca_close (pca , pcad , atol = atol )
112
118
113
119
# Test transform
114
120
X2 = sparse_container (
@@ -121,8 +127,8 @@ def test_pca_sparse(
121
127
)
122
128
X2d = X2 .toarray ()
123
129
124
- assert_allclose (pca .transform (X2 ), pca .transform (X2d ), rtol = transform_rtol )
125
- assert_allclose (pca .transform (X2 ), pcad .transform (X2d ), rtol = transform_rtol )
130
+ assert_allclose (pca .transform (X2 ), pca .transform (X2d ), atol = transform_atol )
131
+ assert_allclose (pca .transform (X2 ), pcad .transform (X2d ), atol = transform_atol )
126
132
127
133
128
134
@pytest .mark .parametrize ("sparse_container" , CSR_CONTAINERS + CSC_CONTAINERS )
@@ -153,10 +159,10 @@ def test_pca_sparse_fit_transform(global_random_seed, sparse_container):
153
159
pca_fit .fit (X )
154
160
transformed_X = pca_fit_transform .fit_transform (X )
155
161
156
- _check_fitted_pca_close (pca_fit , pca_fit_transform , rtol = 1e-10 )
157
- assert_allclose (transformed_X , pca_fit_transform .transform (X ), rtol = 2e-9 )
158
- assert_allclose (transformed_X , pca_fit .transform (X ), rtol = 2e-9 )
159
- assert_allclose (pca_fit .transform (X2 ), pca_fit_transform .transform (X2 ), rtol = 2e-9 )
162
+ _check_fitted_pca_close (pca_fit , pca_fit_transform )
163
+ assert_allclose (transformed_X , pca_fit_transform .transform (X ))
164
+ assert_allclose (transformed_X , pca_fit .transform (X ))
165
+ assert_allclose (pca_fit .transform (X2 ), pca_fit_transform .transform (X2 ))
160
166
161
167
162
168
@pytest .mark .parametrize ("svd_solver" , ["randomized" , "full" ])
0 commit comments