10000 MAINT Make fastica call FastICA by NicolasHug · Pull Request #14987 · scikit-learn/scikit-learn · GitHub
[go: up one dir, main page]

Skip to content

MAINT Make fastica call FastICA #14987

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 9 commits into from
Sep 26, 2019

Conversation

NicolasHug
Copy link
Member
@NicolasHug NicolasHug commented Sep 15, 2019

NOMRG, I think there's a bug in fastica that needs to be fixed first

Closes #14988

This PR makes fastica call FastICA. Following the discussion in #14988 I have created a private _unmixing attribute and clarified the docstring of the components_ attribute.

@agramfort
Copy link
Member

what bug?

@NicolasHug
Copy link
Member Author
NicolasHug commented Sep 15, 2019

this one #14988

@NicolasHug NicolasHug changed the title [NOMRG] Make fastica call FastICA [MRG] Make fastica call FastICA Sep 18, 2019
@NicolasHug
Copy link
Member Author

Thanks @agramfort I updated the PR according to your suggestions

Copy link
Member
@agramfort agramfort left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also please check that you added the attributes properly + add a test to make sure that we have always components = unmixing * whitener etc. thanks !

The unmixing matrix.
The linear operator to apply to the data to get the independent
sources. This is equal to the unmixing matrix when ``whiten`` is
False, and equal to ``np.dot(unmixing_matrix, whitening_)`` when
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
False, and equal to ``np.dot(unmixing_matrix, whitening_)`` when
False, and equal to ``np.dot(unmixing_matrix_, whitening_)`` when

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The unmixing matrix is a private attribute


alpha = fun_args.get('alpha', 1.0)
if not 1 <= alpha <= 2:
raise ValueError('alpha must be in [1,2]')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you say what value you got?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't touch the code logical at all. Only copy pasted

% self.fun
)

n, p = X.shape
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a good occasion to change this to

n_samples, n_features = X.shape

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK but I'd rather not change to code, this is out of scope for this PR

@NicolasHug
Copy link
Member Author

also please check that you added the attributes properly + add a test to make sure that we have always components = unmixing * whitener etc. thanks !

The current tests would fail if anything went wrong. I'd rather not add new tests here, this is not the goal of the PR.

The linear operator to apply to the data to get the independent
sources. This is equal to the unmixing matrix when ``whiten`` is
False, and equal to ``np.dot(unmixing_matrix, self.whitening_)`` when
``whiten`` is True.

mixing_ : array, shape (n_features, n_components)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you're going to hate me @NicolasHug but now mixing_ is not the inverse of unmixing in your description. unmixing is always square where here mixing_ is not.

also why having mixing_ as public attribute and not unmixing_ ?

Copy link
8000
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How would you fix it? Change the docstring?

This issue is not caused by the changes: mixing_ has never been the inverse of the unmixing matrix.

else:
self.components_ = unmixing
self.components_ = W

self.mixing_ = linalg.pinv(self.components_)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cf here

@NicolasHug
Copy link
Member Author

@agramfort it seems to me that the issues you're pointing out are pre-existing the proposed changes. I'd rather just focus on fixing the calling order.

@NicolasHug
Copy link
Member Author

@adrinjalali @glemaitre @thomasjpfan , easy and boring again?

@agramfort
Copy link
Member

@NicolasHug I pushed to your branch. I am happy now :)

Copy link
Member
@rth rth left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not too familiar with FastICA, but LGTM aside from the following comments.

else:
return None, W, S, None
return None, sources, None
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is changing the number of output arguments, and est._unmixing is missing?

self.mean_ = X_mean
self.whitening_ = whitening
self.whitening_ = K
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe keep previous names as more explicit for W and K? Those are defined just a few lines above.

@NicolasHug
Copy link
Member Author

For some reason I can't comment on the reviews

Maybe keep previous names as more explicit for W and K? Those are defined just a few lines above.

I'd rather not change the original code of fastica.

@agramfort
Copy link
Member

@rth merge if you're happy

@rth rth changed the title [MRG] Make fastica call FastICA MAINT Make fastica call FastICA Sep 26, 2019
@rth rth merged commit c96c73b into scikit-learn:master Sep 26, 2019
@rth
Copy link
Member
rth commented Sep 26, 2019

Thanks @NicolasHug !

@rth
Copy link
Member
rth commented Sep 27, 2019

I merged too fast. The decrease in coverage is genuine and should be addressed IMO in particular for the return_X_mean and return_n_iter parameters in the fastica function: https://codecov.io/gh/scikit-learn/scikit-learn/compare/d92f12a137827b0e6357a133db3de6a3c3f34bf7...8efc49f1f01aaea32d535060986729ca20ec6b9a/src/sklearn/decomposition/fastica_.py

@NicolasHug would be able to make a PR with an additional test?

@NicolasHug
Copy link
Member Author

Sigh...

I'll do it.

There's no decrease in coverage. This is just a side effect of the changes. fastica wasn't properly tested in the first place, the coverage decrease is just showing up now.

@rth
Copy link
Member
rth commented Sep 27, 2019

There's no decrease in coverage. This is just a side effect of the changes.

Thanks! Codecov seems to say that there is on those particular lines,

Before:
Screenshot_2019-09-27

After this PR:
Screenshot_2019-09-27 after

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Inconsistency between fastica and FastICA
3 participants
0