Skip to content

Commit 6e5f948

Browse files
FBruzzesikoaning
andauthored
chore: improve error message for ZeroDivisionError in LowessRegression (#708)
* chore: improve error message for ZeroDivisionError in LowessRegression * comment for future selves --------- Co-authored-by: vincent d warmerdam <[email protected]>
1 parent 3d51e7b commit 6e5f948

File tree

2 files changed

+29
-1
lines changed

2 files changed

+29
-1
lines changed

sklego/linear_model.py

+11-1
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,17 @@ def predict(self, X):
141141
X = check_array(X, estimator=self, dtype=FLOAT_DTYPES)
142142
check_is_fitted(self, ["X_", "y_"])
143143

144-
results = np.stack([np.average(self.y_, weights=self._calc_wts(x_i=x_i)) for x_i in X])
144+
try:
145+
results = np.stack([np.average(self.y_, weights=self._calc_wts(x_i=x_i)) for x_i in X])
146+
except ZeroDivisionError:
147+
msg = (
148+
"Weights, resulting from `np.exp(-(distances**2) / self.sigma)`, are all zero. "
149+
"Try to increase the value of `sigma` or to normalize the input data.\n\n"
150+
"`distances` refer to the distance between each sample `x_i` with all the"
151+
"training samples."
152+
)
153+
raise ValueError(msg)
154+
145155
return results
146156

147157

tests/test_estimators/test_lowess.py

+18
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1+
import re
2+
13
import numpy as np
4+
import pytest
25
from sklearn.utils.estimator_checks import parametrize_with_checks
36

47
from sklego.linear_model import LowessRegression
@@ -15,3 +18,18 @@ def test_obvious_usecase():
1518
y = np.ones(x.shape)
1619
y_pred = LowessRegression().fit(X, y).predict(X)
1720
assert np.isclose(y, y_pred).all()
21+
22+
23+
def test_custom_error_for_zero_division():
24+
x = np.arange(0, 100)
25+
X = x.reshape(-1, 1)
26+
y = np.ones(x.shape)
27+
estimator = LowessRegression(sigma=1e-10).fit(X, y)
28+
29+
with pytest.raises(
30+
ValueError, match=re.escape("Weights, resulting from `np.exp(-(distances**2) / self.sigma)`, are all zero.")
31+
):
32+
# Adding an offset, otherwise X to predict would be the same as X in fit method,
33+
# leading to weight of 1 for the corresponding value.
34+
X_pred = X[:10] + 0.5
35+
estimator.predict(X_pred)

0 commit comments

Comments
 (0)