-
-
Notifications
You must be signed in to change notification settings - Fork 26k
Adding explained variances to sparse pca #11527
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
Conversation
thanks :) You wanted someone else to pick this up now, right? |
The variances don't match. It's worth reading in more detail. See the gist I've linked above for comparing variances:
thanks! |
ill give it another try. the variances should be easy... |
63ea0b0
to
7c36760
Compare
Added:
Note:
|
sklearn/decomposition/sparse_pca.py
Outdated
# subtract the previous projections | ||
for j in range(i): | ||
vecp = components[j].copy() | ||
vec -= np.dot(unit_vecs[j], vec)*unit_vecs[j] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
note, we dot the vec
with the vec
from the previous iteration (the projections should only get smaller and smaller)
Sparse PCA actually has a horrible bug. #11585 fixes it. I don't know how it will interact with this PR. |
should be okay i think. The function computes The test currently doesn't fit using sparse PCA. It takes in components computed from regular So long as the |
sklearn/decomposition/sparse_pca.py
Outdated
@@ -98,7 +98,7 @@ def __init__(self, n_components=None, alpha=1, ridge_alpha=0.01, | |||
self.verbose = verbose | |||
self.random_state = random_state | |||
|
|||
def fit(self, X, y=None): | |||
def fit(self, X, y=None, variance=False): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The fit
method should not have any other param than X and y (and sometimes sample_weight). You have to make it a class attribute I guess.
edit: my bad, it can. However not in this case. It can only when the parameter's value depends on the data, meaning it can't be set before fitting. Here it should be a class attribute.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok sounds good, moved to __init__
sklearn/decomposition/sparse_pca.py
Outdated
@@ -109,6 +109,9 @@ def fit(self, X, y=None): | |||
|
|||
y : Ignored | |||
|
|||
variance : bool, optional | |||
If true, compute the explained variance | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove, see previous
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
moved this over to __init__
(for both)
sklearn/decomposition/sparse_pca.py
Outdated
@@ -135,6 +138,9 @@ def fit(self, X, y=None): | |||
) | |||
self.components_ = Vt.T | |||
self.error_ = E | |||
if variance: | |||
self.explained_variance_ = \ | |||
self.get_explained_variance(self.components_, X) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if self.variance
I would name it with_explained_variance, although it's a bit long. But if it's a class attribute it should have a more informative name
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I renamed to self.explained_variance_
sklearn/decomposition/sparse_pca.py
Outdated
''' | ||
# requires the mean to be subtracted | ||
X = X - np.mean(X, axis=0) | ||
# the number of samples |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this might not be necessary after #11585 is merged.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds good. I'll leave as is for now and rebase on that PR when merged (looks more important than this one right?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It will probably be merged berfore. You can adapt you PR when it's done. Sounds good.
sklearn/decomposition/sparse_pca.py
Outdated
@@ -185,6 +191,63 @@ def transform(self, X, ridge_alpha='deprecated'): | |||
U /= s | |||
return U | |||
|
|||
def get_explained_variance(self, components, X): | |||
''' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we want this function to be used from outside ?
otherwise I think it should be private: _get_explained_variance
still in the optics to be a private function, you don't need to pass components to the function. You can directly access self.components_ inside the function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
renamed thanks!
sklearn/decomposition/sparse_pca.py
Outdated
n_components = components.shape[0] | ||
unit_vecs = components.copy() | ||
unit_vecs = unit_vecs/np.linalg.norm(components, axis=1)[:, np.newaxis] | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if #11585 is merged, components will be already normalized.
However there will be a deprecation cycle for that, so for a few releases you'll have to check if the attribute introduced in that PR, normalize
, is false before computing it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok, i think id rather wait and rebase, in case anything else changes, can you ping when done? (or feel free to take over if i take too long to respond!)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I checked for normalize_components
and if False
, subtract mean and warn. Would that work?
thanks!
sklearn/decomposition/sparse_pca.py
Outdated
# we subtract the variance from components in the direction of previous | ||
# axes | ||
# the projection corrected vectors | ||
proj_corrected_vecs = np.zeros_like(components) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
too much verbose. I think you can remove first and last lines
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
removed verbosity to all lines mentioned
sklearn/decomposition/sparse_pca.py
Outdated
# just the diagonal of the covariance of X projected to the new | ||
# (component subtracted) basis | ||
# Y in the new basis | ||
Y = np.tensordot(X, proj_corrected_vecs.T, axes=(1, 0)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same, too much verbose
sklearn/decomposition/sparse_pca.py
Outdated
@@ -265,7 +328,7 @@ def __init__(self, n_components=None, alpha=1, ridge_alpha=0.01, | |||
self.batch_size = batch_size | |||
self.shuffle = shuffle | |||
|
|||
def fit(self, X, y=None): | |||
def fit(self, X, y=None, variance=False): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same comments as in SparsePCA
You also have to add |
@@ -77,6 +77,12 @@ class SparsePCA(BaseEstimator, TransformerMixin): | |||
n_iter_ : int | |||
Number of iterations run. | |||
|
|||
variance : bool, optional | |||
If true, compute the explained variance | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sorry for the miss leading. variance should be a parameter (I tend to use the word attribute for both as in C++...)
sklearn/decomposition/sparse_pca.py
Outdated
@@ -135,6 +143,9 @@ def fit(self, X, y=None): | |||
) | |||
self.components_ = Vt.T | |||
self.error_ = E | |||
if self.variance: | |||
self.explained_variance_ = \ | |||
self._get_explained_variance(self.components_, X) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
self._get_explained_variance(X)
sklearn/decomposition/sparse_pca.py
Outdated
if self.variance: | ||
self.explained_variance_ = \ | ||
self._get_explained_variance(self.components_, X) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
self._get_explained_variance(X)
explained_variance = pca.explained_variance_ | ||
spca_lars.components_ = components | ||
explained_variance_sparse = spca_lars.explained_variance_ | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hum, I misunderstood what you're doing.
You just want to assert that your function ̀_get_explained_variance
returns the same result as in PCA if given same X and same components, right ?
Maybe you can add a comment before line 96 explaining that.
And I guess you have to do explained_variance_sparse = spca_lars._get_explained_variance_(Y)
Is it possible to make a test checking that the explained_variance_ computed with the components fitted by SparsePCA are correct ? maybe something like comparing explained_variance_ between PCA and SparsePCA with sparsity=0 ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oops yes, it should be a function call. I also changed Y
to X
. i copied and pasted form a previous test. it could have been Y
because maybe it was copied from another test that compared two feature vectors?
Also, you forgot to add |
lgtm. Now I think we should wait #11585 to be merged. |
sklearn/decomposition/sparse_pca.py
Outdated
@@ -135,6 +143,8 @@ def fit(self, X, y=None): | |||
) | |||
self.components_ = Vt.T | |||
self.error_ = E | |||
if self.variance: | |||
self.explained_variance_ = self._get_explained_variance(X) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sorry one more thing. You should add
else:
self.explained_variance_ = None
otherwise you'd get an attribute error if calling estimator.explained_variance afterwards.
and you can add a test which checks that when variance is False, explained_variance_ is not computed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added thanks! one random question, i see in your PR, you added to "doc/whats_new/v0.20.rst"
should I be adding the same to a similar file? (and which?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes you'll have to add it in the what's new. But I don't know if your PR will be in the 0.20 release. Let it as is for now and we'll fill the right what's new as soon as we know.
@@ -77,6 +80,9 @@ class SparsePCA(BaseEstimator, TransformerMixin): | |||
n_iter_ : int | |||
Number of iterations run. | |||
|
|||
explained_variance_ : array, [n_components] | |||
The explained variance versus component | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add that it's only computed if variance is set to true
When is this expected to be released? :) |
We are waiting for another PR to be merged first. So I can't tell but it will probably not be in the 0.20 release. |
bbd6cc1
to
d6ff98c
Compare
I rebased and force pushed (but kept a local copy of my branch before rebase in case anything went wrong). Let me know what you think thanks! |
sklearn/decomposition/sparse_pca.py
Outdated
if not self.normalize_components: | ||
X = X - np.mean(X, axis=0) | ||
warnings.warn("normalize_components=False is a " | ||
"backward-compatible setting that implements a " |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wouldn't raise a warning here. The reason is that if someone calls SparsePCA with normalize_components=False, he will already get a warning in fit. No need for duplicate warning.
Instead, you could comment that this test should be removed in version 0.22.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sounds good! removed
sklearn/decomposition/sparse_pca.py
Outdated
n_components = components.shape[0] | ||
unit_vecs = components.copy() | ||
unit_vecs = unit_vecs/np.linalg.norm(components, axis=1)[:, np.newaxis] | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correct me if I'm wrong but you should also normalize the components here, depending on normalize_components
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no, and this is tricky now. i will elaborate in a comment further below
sklearn/decomposition/sparse_pca.py
Outdated
@@ -105,8 +112,9 @@ class SparsePCA(BaseEstimator, TransformerMixin): | |||
def __init__(self, n_components=None, alpha=1, ridge_alpha=0.01, | |||
max_iter=1000, tol=1e-8, method='lars', n_jobs=1, U_init=None, | |||
V_init=None, verbose=False, random_state=None, | |||
normalize_components=False): | |||
normalize_components=False, variance=False): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm wondering if we could make it True by default. Is _get_explained_variance
computation intensive ? I mean versus SparsePCA.fit
.
Also, I think variance
is not enough informative. We could think of a better name. If I recall your first idea was with_variance
. I think it's better than this one. Maybe core reviewers will have a better opinion on that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
made to True
, I agree it makes sense
sklearn/decomposition/sparse_pca.py
Outdated
---------- | ||
X : 2D np.ndarray | ||
The feature vector. Must be shape m x n where m is the number | ||
of samples and n is the dimension of the incoming feature |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here I think the common accepted way is
X : ndarray, shape (n_samples, n_features)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done for all i can find, thanks!
@@ -81,6 +81,9 @@ class SparsePCA(BaseEstimator, TransformerMixin): | |||
backward compatibility. It would be set to ``True`` from 0.22 | |||
onwards. | |||
|
|||
variance : bool, optional | |||
If true, this will compute the explained variance versus component. | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please state the default value
variance : boolean, optional (default=False)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done thanks!
@@ -300,6 +365,9 @@ class MiniBatchSparsePCA(SparsePCA): | |||
backward compatibility. It would be set to ``True`` from 0.22 | |||
onwards. | |||
|
|||
variance : bool, optional | |||
If true, this will compute the explained variance versus component. | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
default=
sklearn/decomposition/sparse_pca.py
Outdated
@@ -96,6 +99,10 @@ class SparsePCA(BaseEstimator, TransformerMixin): | |||
Per-feature empirical mean, estimated from the training set. | |||
Equal to ``X.mean(axis=0)``. | |||
|
|||
explained_variance_ : array, [n_components] | |||
The explained variance versus component |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
array, shape (n_components,)
@@ -312,6 +380,10 @@ class MiniBatchSparsePCA(SparsePCA): | |||
Per-feature empirical mean, estimated from the training set. | |||
Equal to ``X.mean(axis=0)``. | |||
|
|||
explained_variance_ : array, [n_components] | |||
The explained variance versus component. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
array, shape (n_components,)
also it might be a good idea to test that explained_variance is the same whether normalize_components is True or False. |
tests are failing because now warnings are raised as errors. |
Thanks @jeremiedbb for the input. I have made the changes, but I have a few questions:
|
I don't understand what you mean. When you compute the explained variance, you begin with normalizing the components.
Actually I think it does. In PCA, the components are computed using svd, which returns a unitary matrix.
Indeed, so I think you should call _get_explained_variance right after the component's normalization. |
sklearn/decomposition/sparse_pca.py
Outdated
self.n_components = n_components | ||
self._compute_variance = compute_variance |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why the underscore ? this is not private.
@jeremiedbb thanks. One way to compute the variance is to extract the diagonal of In SVD, I think it doesn't matter because we use the This is explained on p 273 here. |
Thanks for the clarification. I missed that you needed both components and the corresponding unit vectors. So I think it's fine as it is.
Agreed |
Great thanks! Do we need to ping anyone else to look at it now? |
sklearn/decomposition/sparse_pca.py
Outdated
@@ -361,6 +434,7 @@ def fit(self, X, y=None): | |||
"compatibility mode will be removed in 0.22.", | |||
DeprecationWarning) | |||
|
|||
self.n_samples = X.shape[0] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where does that come from ?
you don't seem to use it anywhere.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oops yes this is vestigial code from a previous attempt
Sure ! |
ok thanks! submitted change, waiting.. |
Looks good ! @GaelVaroquaux @agramfort @glemaitre you might be interested in reviewing this, since you were recently involved in SparsePCA :) |
sklearn/decomposition/sparse_pca.py
Outdated
@@ -81,9 +81,12 @@ class SparsePCA(BaseEstimator, TransformerMixin): | |||
backward compatibility. It would be set to ``True`` from 0.22 | |||
onwards. | |||
|
|||
compute_variance : bool, optional (default=True) | |||
If true, this will compute the explained variance versus component. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
versus -> per
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks, changed
sklearn/decomposition/sparse_pca.py
Outdated
Per-feature empirical mean, estimated from the training set. | ||
Equal to ``X.mean(axis=0)``. | ||
|
||
explained_variance_ : array, shape (n_components, ) | ||
The explained variance versus component |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Versus -> per.
End the line with a full stop, please
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you mean "."? Sorry not familiar with the word, thanks!
sklearn/decomposition/sparse_pca.py
Outdated
@@ -231,6 +245,57 @@ def transform(self, X, ridge_alpha='deprecated'): | |||
|
|||
return U | |||
|
|||
def _get_explained_variance(self, X): | |||
''' | |||
Get the explained variance from the principal components of the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Descent please
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah yes, line too long, following doctstring convention of makinga new line with extra description, thanks
sklearn/decomposition/sparse_pca.py
Outdated
@@ -231,6 +245,57 @@ def transform(self, X, ridge_alpha='deprecated'): | |||
|
|||
return U | |||
|
|||
def _get_explained_variance(self, X): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems to be a generalised approach? Perhaps pull this out into a module-level function taking X and components
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, it should work for PCA as well (although not tested)
made a module, for discussion
sklearn/decomposition/sparse_pca.py
Outdated
n_samples = X.shape[0] | ||
n_components = components.shape[0] | ||
unit_vecs = components.copy() | ||
components_norm = \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We tend to avoid this kind of line continuation and prefer breaking after a comma within parentheses
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
removed these awkward indents, thanks!
@pytest.mark.parametrize("norm_comp", [False, True]) | ||
def test_fit_transform_variance(norm_comp): | ||
''' | ||
This function asserts that the variance computed by SparsePCA is the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We use comments rather than docstrings in tests (although mostly for historical reasons)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
changed to comments, thanks!
sklearn/decomposition/sparse_pca.py
Outdated
@@ -300,18 +365,25 @@ class MiniBatchSparsePCA(SparsePCA): | |||
backward compatibility. It would be set to ``True`` from 0.22 | |||
onwards. | |||
|
|||
compute_variance : bool, optional (default=True) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need this to be a parameter? How costly is it relative to the sparse PCA?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i don't think it is, it's just vectorized products. it could be costly, when maybe running this in a loop though. i have removed it for now. we can perhaps add this in in a future issue if someone is discontent?
@jeremiedbb what about the release notes, should I add some now? |
Well there is no what's new for the 0.21 yet and I'm really not sure it will be reviewed (and approved) before the release. You might have to let it as is until the release and then ping some guys for the review once they have a bit more time... |
ok sounds good thanks! |
e10ee28
to
1a33be6
Compare
rebased. just checking in |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not a full review
explained_variance = pca.explained_variance_ | ||
|
||
# force the components in spca_lars to be the same as in pca | ||
spca_lars.components_ = pca.components_ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about a string version of that test that first applies QR-decomposition on spca_lars.components_ and then computes and compares the explained variances against PCA's output?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I assume by that you mean something like this:
# Force matrix to be orthogonal. sparse PCA must then be the same as PCA.
X_orthogonal, R = np.linalg.qr(X)
spca_lars.fit(X_orthogonal)
pca.fit(X_orthogonal)
explained_variance = pca.explained_variance_
explained_variance_sparse = _get_explained_variance(
X_orthogonal, spca_lars.components_)
I would have assumed this to work but it does not. I will not add it. I don't have time to update it (I'm working in a completely different field). I suggest to either:
- make correction here
- add commit to this PR
- we can close it and someone else continue it
- make an issue to add this test
What do you think? I apologize for my latency. It is very hard for me to step into the open source world right now.
If i have free time I'll try to review and think about this later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, this goes into the direction I had in mind. Would be a nice option for a more careful test if feasible.
8af1aaf
to
583e910
Compare
sklearn/decomposition/sparse_pca.py
Outdated
|
||
References | ||
---------- | ||
[1] Journal of Computational and Graphical Statistics, Volume 15, Number 2, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the rst syntax is .. [1]
8c81f47
to
84d7206
Compare
84d7206
to
0d80178
Compare
@adrinjalali I took a look and it looks like it needed to be rebased. looks like some things changed along the way. |
@jrmlhermitte , it's up to you.... :) ... but it seems to me that with already one approval it is worth to finish it. Would you try to resolve conflicts and sync to master? |
This was taken over by #16255 which was closed because the concept of component-wise explained variance is not well defined when the components are not orthogonal. |
Adding explained variances for sparse PCA during a sprint.
I am unfamiliar with Sparse PCA. Based on conversation with @amueller
Reference Issues/PRs
Issue #11512
The variance computed from sparse PCA should match regular PCA. Printed variances here should match.
What does this implement/fix? Explain your changes.
Any other comments?