-
-
Notifications
You must be signed in to change notification settings - Fork 26k
[MRG + 1] FIX Calculation of standard deviation of predictions in ARDRegression #10153
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
@@ -110,6 +111,22 @@ def test_std_bayesian_ridge_ard_with_constant_input(): | |||
assert_array_less(y_std, expected_upper_boundary) | |||
|
|||
|
|||
def test_regression_issue_10128(): | |||
# this ARDRegression test throws a `ValueError` on master, commit 5963fd2 | |||
np.random.seed(752) |
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 that we don't have to rely on a random seed and we can create a deterministic toy example.
We should check the data (specifically the unique value) and create such a matrix as input
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.
still haven't succeeded in coming up with a smaller example.
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 came up with a better example! Will push it 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.
done
@@ -110,6 +111,22 @@ def test_std_bayesian_ridge_ard_with_constant_input(): | |||
assert_array_less(y_std, expected_upper_boundary) | |||
|
|||
|
|||
def test_regression_issue_10128(): | |||
# this ARDRegression test throws a `ValueError` on master, commit 5963fd2 |
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.
Maybe a succinct description will be better. you can also put the issue number instead of the commit
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
clf = ARDRegression() | ||
clf.fit(X_train, y_train) | ||
clf.predict(X_test, return_std=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.
Maybe checking the value of the coef would be meaningful in this case
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
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 check for the correct shape of sigma_
now
for iter_ in range(self.n_iter): | ||
# Compute mu and sigma (using Woodbury matrix identity) | ||
# Compute sigma and mu (using Woodbury matrix identity) | ||
def update_sigma(X, alpha_, lambda_, keep_lambda, n_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.
i am not sure what is the best: keep the function here or make a private method.
@jnothman WDYT?
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 am fine leaving it here if the object still pickles
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.
Is this tested somewhere?
Codecov Report
@@ Coverage Diff @@
## master #10153 +/- ##
==========================================
- Coverage 96.21% 96.13% -0.08%
==========================================
Files 337 337
Lines 62891 62942 +51
==========================================
Hits 60508 60508
- Misses 2383 2434 +51
Continue to review full report at Codecov.
|
Any idea why appveyor fails? EDIT: appveyor now passes again |
LGTM ping @agramfort @jnothman (you might want to give your opinion regarding private methods/locally defined function) |
@jdoepfert please document the bug fix in what's new page. |
# Conflicts: # doc/whats_new/v0.20.rst
@agramfort I updated what's new. Hopefully correctly, I am not sure about the format. |
Ok so that's a MRG+2. thanks @jdoepfert |
@glemaitre thx for reviewing! |
Reference Issues/PRs
Fixes #10128
What does this implement/fix? Explain your changes.
This resolves the issue that a
ValueError
is thrown upon callingpredict()
withreturn_std=True
after fittingARDRegression()
with particular inputsX
:I think this PR actually resolves the following bug in the algorithm:
sigma_
andcoef_
are updated, using the parameter estimates from the previous iteration (e.g.keep_lambda
)keep_lambda
is updated according tolambda_ < self.threshold_lambda
)At prediction stage, a kind of
keep_lambda
comparison is again performed, usingself.lambda_ < self.threshold_lambda
(L551), to adapt the shape ofX
to the shape ofself.sigma_
.However, due to the algorithm's structure outlined above, this
self.lambda_ < self.threshold_lambda
is not identical to thekeep_lambda
used for calculating thesigma_
, sincekeep_lambda
andlambda_
are updated aftersigma_
. Therefore, in rare occasions, whenkeep_lambda
changes during the last iteration of the algorithm, the shapes of the adaptedX
andself.sigma_
in L552 will not match.The fix consists of applying the updates for
sigma_
andcoef_
one more time after the last iteration of the algorithm. This way, the updated parameter estimates are used to calculate the finalsigma_
andcoef_
. This is also in line with this publication, see discussion in #10128.