8000 [MRG + 1] Fix BayesianRidge() and ARDRegression() for constant target… · maskani-moh/scikit-learn@9302891 · GitHub < 10000 link rel="alternate icon" class="js-site-favicon" type="image/png" href="https://github.githubassets.com/favicons/favicon.png">
[go: up one dir, main page]

Skip to content

Commit 9302891

Browse files
jdoepfertmaskani-moh
authored andcommitted
[MRG + 1] Fix BayesianRidge() and ARDRegression() for constant target vectors (scikit-learn#10095)
* add test for issue scikit-learn#10092 * add comment to test * split into two tests * add tests for scores, alpha and beta * adapt tests: n_samples != n_features * add test when no intercept is fitted * add handling of constant target vector when intercept is fitted * fix typo in comments * fix format issues * replace original fix with simpler fix * add comment * increase upper boundary for test * increase upper boundary for test * merge tests for ARDRegression and BayesianRidge * use random state in tests * decrease upper bound for std * replace np.spacing(1) -> np.finfo(np.float64).eps
1 parent 074b8aa commit 9302891

File tree

2 files changed

+43
-2
lines changed

2 files changed

+43
-2
lines changed

sklearn/linear_model/bayes.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,10 @@ def fit(self, X, y):
162162
n_samples, n_features = X.shape
163163

164164
# Initialization of the values of the parameters
165-
alpha_ = 1. / np.var(y)
165+
eps = np.finfo(np.float64).eps
166+
# Add `eps` in the denominator to omit division by zero if `np.var(y)`
167+
# is zero
168+
alpha_ = 1. / (np.var(y) + eps)
166169
lambda_ = 1.
167170

168171
verbose = self.verbose
@@ -445,7 +448,10 @@ def fit(self, X, y):
445448
verbose = self.verbose
446449

447450
# Initialization of the values of the parameters
448-
alpha_ = 1. / np.var(y)
451+
eps = np.finfo(np.float64).eps
452+
# Add `eps` in the denominator to omit division by zero if `np.var(y)`
453+
# is zero
454+
alpha_ = 1. / (np.var(y) + eps)
449455
lambda_ = np.ones(n_features)
450456

451457
self.scores_ = list()

sklearn/linear_model/tests/test_bayes.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@
88
from sklearn.utils.testing import assert_array_equal
99
from sklearn.utils.testing import assert_array_almost_equal
1010
from sklearn.utils.testing import assert_almost_equal
11+
from sklearn.utils.testing import assert_array_less
1112
from sklearn.utils.testing import SkipTest
13+
from sklearn.utils import check_random_state
1214
from sklearn.linear_model.bayes import BayesianRidge, ARDRegression
1315
from sklearn.linear_model import Ridge
1416
from sklearn import datasets
@@ -60,6 +62,39 @@ def test_toy_bayesian_ridge_object():
6062
assert_array_almost_equal(clf.predict(test), [1, 3, 4], 2)
6163

6264

65+
def test_prediction_bayesian_ridge_ard_with_constant_input():
66+
# Test BayesianRidge and ARDRegression predictions for edge case of
67+
# constant target vectors
68+
n_samples = 4
69+
n_features = 5
70+
random_state = check_random_state(42)
71+
constant_value = random_state.rand()
72+
X = random_state.random_sample((n_samples, n_features))
73+
y = np.full(n_samples, constant_value)
74+
expected = np.full(n_samples, constant_value)
75+
76+
for clf in [BayesianRidge(), ARDRegression()]:
77+
y_pred = clf.fit(X, y).predict(X)
78+
assert_array_almost_equal(y_pred, expected)
79+
80+
81+
def test_std_bayesian_ridge_ard_with_constant_input():
82+
# Test BayesianRidge and ARDRegression standard dev. for edge case of
83+
# constant target vector
84+
# The standard dev. should be relatively small (< 0.01 is tested here)
85+
n_samples = 4
86+
n_features = 5
87+
random_state = check_random_state(42)
88+
constant_value = random_state.rand()
89+
X = random_state.random_sample((n_samples, n_features))
90+
y = np.full(n_samples, constant_value)
91+
expected_upper_boundary = 0.01
92+
93+
for clf in [BayesianRidge(), ARDRegression()]:
94+
_, y_std = clf.fit(X, y).predict(X, return_std=True)
95+
assert_array_less(y_std, expected_upper_boundary)
96+
97+
6398
def test_toy_ard_object():
6499
# Test BayesianRegression ARD classifier
65100
X = np.array([[1], [2], [3]])

0 commit comments

Comments
 (0)
0