[MRG] Add jitter to LassoLars#15179
Conversation
|
Addressing MR comments (thanks, @agramfort):
Still pending: 3 tests fail now due to floating point precision stuff. Should I just loosen the precision of those to let things pass? Also: I've moved the |
|
@angelaambroz please do not use a jitter by default. It's working for many people as it is now. Don't affect the behavior of many just for your usecase. thanks |
|
@agramfort Not actually my use case - I was addressing what was discussed in #2746. A default of 10e-5 was discussed there; though I didn't get specific confirmation on that being the agreed-on default value. I can default |
|
yes that would be fine with me. thanks
… |
|
@angelaambroz there are unrelated changes in the diff (in cython files). This needs to be cleaned up. thanks |
|
Ack, unintended! Will fix shortly. |
|
The error message I'm seeing in the Azure pipeline is: I expect this is something orthogonal to my changes - I don't see how my diff could have affected numpy stuff. Help? |
sklearn/linear_model/_least_angle.py
Outdated
| precompute='auto', n_nonzero_coefs=500, | ||
| eps=np.finfo(np.float).eps, copy_X=True, fit_path=True): | ||
| eps=np.finfo(np.float).eps, copy_X=True, fit_path=True, | ||
| jitter=DEFAULT_JITTER): |
There was a problem hiding this comment.
| jitter=DEFAULT_JITTER): | |
| jitter=None): |
sklearn/linear_model/_least_angle.py
Outdated
| from ..exceptions import ConvergenceWarning | ||
|
|
||
| SOLVE_TRIANGULAR_ARGS = {'check_finite': False} | ||
| DEFAULT_JITTER = None |
sklearn/linear_model/_least_angle.py
Outdated
| with a small alpha. | ||
|
|
||
| jitter : float, default=None | ||
| Uniform noise parameter, added to the y values, to satisfy \ |
sklearn/linear_model/_least_angle.py
Outdated
| LassoLars(alpha=0.01) | ||
| >>> print(reg.coef_) | ||
| [ 0. -0.963257...] | ||
| [ 0. -0.9632...] |
There was a problem hiding this comment.
Please revert this, the default shouldn't have changed.
sklearn/linear_model/_least_angle.py
Outdated
| normalize=True, precompute='auto', max_iter=500, | ||
| eps=np.finfo(np.float).eps, copy_X=True, fit_path=True, | ||
| positive=False): | ||
| positive=False, jitter=DEFAULT_JITTER): |
There was a problem hiding this comment.
| positive=False, jitter=DEFAULT_JITTER): | |
| positive=False, jitter=None): |
Yes, merging master in might help. |
sklearn/linear_model/_least_angle.py
Outdated
| else: | ||
| max_iter = self.max_iter | ||
|
|
||
| if self.jitter: |
There was a problem hiding this comment.
| if self.jitter: | |
| if self.jitter is not None: |
| y = np.array(y_list) | ||
| expected_output = np.array(expected_y) | ||
| alpha = 0.001 | ||
| fit_intercept = False |
There was a problem hiding this comment.
why forcing fit_intercept = False?
There was a problem hiding this comment.
This is the at the edge of my stats/linear algebra understanding, but I think we need to force it to be False since the error only occurs for exactly aligned values (e.g. this comment).
There was a problem hiding this comment.
from your comment I understand that the test would not be a non-regression test with fit_intercept=True as you only see an error with fit_intercept. However below the X and y you chose do work too with jitter=None. Did you check that the test still pass with fit_intercept=True?
There was a problem hiding this comment.
Since the target is constant (-2.5, -2.5), fitting with the intercept would mean the coeffs are just all 0 (and the intercept is -2.5).
So I guess it makes sense to leave fit_intercept=False. It properly reproduces the original example from the issue
NicolasHug
left a comment
There was a problem hiding this comment.
Thanks for the PR and for your patience so far @angelaambroz.
Made a few comments. Are you available to make the changes? Otherwise we'll do it.
This also needs an entry in doc/whats_new/v0.23.rst
Thanks!
| y = np.array(y_list) | ||
| expected_output = np.array(expected_y) | ||
| alpha = 0.001 | ||
| fit_intercept = False |
There was a problem hiding this comment.
Since the target is constant (-2.5, -2.5), fitting with the intercept would mean the coeffs are just all 0 (and the intercept is -2.5).
So I guess it makes sense to leave fit_intercept=False. It properly reproduces the original example from the issue
| w_nojitter = lars.coef_ | ||
| w_jitter = lars_with_jitter.coef_ | ||
|
|
||
| assert not np.array_equal(w_jitter, w_nojitter) |
There was a problem hiding this comment.
This is too easy to pass, so maybe instead check the MSD
assert np.mean((w_jitter - w_nojitter)**2) > .1|
@NicolasHug seems like @angelaambroz may not be available for this one. Would you like to take it over? (trying to clean up the milestone and prepare for release). |
|
yup I'll do it. |
sklearn/linear_model/_least_angle.py
Outdated
| normalize=True, precompute='auto', max_iter=500, | ||
| eps=np.finfo(np.float).eps, copy_X=True, positive=False): | ||
| eps=np.finfo(np.float).eps, copy_X=True, positive=False, | ||
| random_state=None): |
There was a problem hiding this comment.
why adding a random_state param here and not jitter?
|
thx @angelaambroz and @NicolasHug ! |
* Adding jitter to LassoLars fit * CircleCI fail * MR comments * Jitter becomes default, added test based on issue description * flake8 fixes * Removing unexpected cython files * Better coverage * PR comments * PR comments * PR comments * PR comments * PR comments * Linting * Apply suggestions from code review * addressed comments * added whatnew entry * test both estimators * update whatsnew * removed random_state for lassolarsIC Co-authored-by: Nicolas Hug <contact@nicolas-hug.com>
* Adding jitter to LassoLars fit * CircleCI fail * MR comments * Jitter becomes default, added test based on issue description * flake8 fixes * Removing unexpected cython files * Better coverage * PR comments * PR comments * PR comments * PR comments * PR comments * Linting * Apply suggestions from code review * addressed comments * added whatnew entry * test both estimators * update whatsnew * removed random_state for lassolarsIC Co-authored-by: Nicolas Hug <contact@nicolas-hug.com>
Reference Issues/PRs
See #2746.
What does this implement/fix? Explain your changes.
Following the discussion in the above issue, this PR adds a
jitterkeyword argument to theLarsandLassoLarsclasses. The argument, defaulted to 0.0001, applies uniformly distributed noise, bounded byjitter, to theyvariable when fitting.Any other comments?
Main question:
test_least_angle.pyfrom differences in floating point estimates for model coefficients. One way to address this would be loosening the precision of theassert_array_almost_equal()statements. Is this how we'd like to proceed?np.random.seed()and "lock in" the noise so that the model gives predictable results once it's been imported, even if the user keeps instantiating and fitting it? I think no, but... I'm not sure.Thanks to all the maintainers of sklearn! It's a great project. Thanks for the contributing guidelines also, those were very helpful.