Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[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

Merged
merged 12 commits into from
Nov 22, 2017

Conversation

jdoepfert
Copy link
Contributor

@jdoepfert jdoepfert commented Nov 16, 2017

Reference Issues/PRs

Fixes #10128

What does this implement/fix? Explain your changes.

This resolves the issue that a ValueError is thrown upon calling predict() with return_std=True after fitting ARDRegression() with particular inputs X:

    X = np.array([[1, 0],
                  [0, 0]])
    y = np.array([0, 0])
    clf = ARDRegression(n_iter=1)
    clf.fit(X, y)
    clf.predict(X, return_std=True)
ValueError: shapes (2,1) and (2,2) not aligned: 1 (dim 1) != 2 (dim 0)

I think this PR actually resolves the following bug in the algorithm:

  1. In the algorithm's fitting iteration loop (L473), first sigma_ and coef_ are updated, using the parameter estimates from the previous iteration (e.g. keep_lambda)
  2. Then, the parameters are updated (e.g. keep_lambda is updated according to lambda_ < self.threshold_lambda)

At prediction stage, a kind of keep_lambda comparison is again performed, using self.lambda_ < self.threshold_lambda (L551), to adapt the shape of X to the shape of self.sigma_.
However, due to the algorithm's structure outlined above, this self.lambda_ < self.threshold_lambda is not identical to the keep_lambda used for calculating the sigma_, since keep_lambda and lambda_ are updated after sigma_. Therefore, in rare occasions, when keep_lambda changes during the last iteration of the algorithm, the shapes of the adapted X and self.sigma_ in L552 will not match.

The fix consists of applying the updates for sigma_ and coef_ one more time after the last iteration of the algorithm. This way, the updated parameter estimates are used to calculate the final sigma_ and coef_. This is also in line with this publication, see discussion in #10128.

@@ -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)
Copy link
Member

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

Copy link
Contributor Author

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.

Copy link
Contributor Author

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

Copy link
Contributor Author

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
Copy link
Member

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

Copy link
Contributor Author

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)

Copy link
Member

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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

Copy link
Contributor Author

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):
Copy link
Member

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?

Copy link
Member

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

Copy link
Contributor Author

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
Copy link

codecov bot commented Nov 17, 2017

Codecov Report

Merging #10153 into master will decrease coverage by 0.07%.
The diff coverage is 100%.

Impacted file tree graph

@@            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
Impacted Files Coverage Δ
sklearn/linear_model/bayes.py 95.67% <100%> (+0.22%) ⬆️
sklearn/linear_model/tests/test_bayes.py 91.66% <100%> (+1.24%) ⬆️
sklearn/svm/bounds.py 94.73% <0%> (-5.27%) ⬇️
sklearn/model_selection/tests/test_split.py 92.29% <0%> (-4.15%) ⬇️
sklearn/tests/test_cross_validation.py 97.76% <0%> (-1.97%) ⬇️
sklearn/utils/testing.py 76.48% <0%> (-0.52%) ⬇️
sklearn/model_selection/_validation.py 96.91% <0%> (-0.02%) ⬇️
sklearn/cross_validation.py 98.59% <0%> (-0.01%) ⬇️
sklearn/model_selection/_split.py 99.13% <0%> (-0.01%) ⬇️
sklearn/linear_model/tests/test_omp.py 100% <0%> (ø) ⬆️
... and 6 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 5963fd2...7741afc. Read the comment docs.

@jdoepfert
Copy link
Contributor Author

jdoepfert commented Nov 17, 2017

Any idea why appveyor fails? def test_predict_proba_binary() in sklearn/neural_network/tests/test_mlp.py fails, if I interpret the huge log correctly. On my machine, the tests run without problems.

EDIT: appveyor now passes again

@jdoepfert jdoepfert changed the title [WIP] Fix bug in ARDRegression: Calculation of standard deviation of predictions [MRG] Fix bug in ARDRegression: Calculation of standard deviation of predictions Nov 18, 2017
@glemaitre
Copy link
Member

LGTM

ping @agramfort @jnothman (you might want to give your opinion regarding private methods/locally defined function)

@glemaitre glemaitre changed the title [MRG] Fix bug in ARDRegression: Calculation of standard deviation of predictions [MRG + 1] FIX Calculation of standard deviation of predictions in ARDRegression Nov 18, 2017
@agramfort
Copy link
Member

@jdoepfert please document the bug fix in what's new page.

@jdoepfert
Copy link
Contributor Author

@agramfort I updated what's new. Hopefully correctly, I am not sure about the format.

@glemaitre glemaitre merged commit 7ffad2c into scikit-learn:master Nov 22, 2017
@glemaitre
Copy link
Member

Ok so that's a MRG+2. thanks @jdoepfert

@jdoepfert
Copy link
Contributor Author

@glemaitre thx for reviewing!

jwjohnson314 pushed a commit to jwjohnson314/scikit-learn that referenced this pull request Dec 18, 2017
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.

ARDRegression still crashes when trained on some constant y
3 participants