Skip to content
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

MNT deprecate outputs_2d_ attribute of dummy estimators #14933

Merged
merged 6 commits into from
Sep 15, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
39 changes: 27 additions & 12 deletions sklearn/dummy.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
from .utils.random import random_choice_csc
from .utils.stats import _weighted_percentile
from .utils.multiclass import class_distribution
from .utils import deprecated


class DummyClassifier(MultiOutputMixin, ClassifierMixin, BaseEstimator):
Expand Down Expand Up @@ -120,8 +121,6 @@ def fit(self, X, y, sample_weight=None):
if not self.sparse_output_:
y = np.atleast_1d(y)

self.output_2d_ = y.ndim == 2 and y.shape[1] > 1

if y.ndim == 1:
y = np.reshape(y, (-1, 1))

Expand Down Expand Up @@ -151,7 +150,7 @@ def fit(self, X, y, sample_weight=None):
raise ValueError("The constant target value must be "
"present in training data")

if self.n_outputs_ == 1 and not self.output_2d_:
if self.n_outputs_ == 1:
self.n_classes_ = self.n_classes_[0]
self.classes_ = self.classes_[0]
self.class_prior_ = self.class_prior_[0]
Expand Down Expand Up @@ -182,7 +181,7 @@ def predict(self, X):
classes_ = self.classes_
class_prior_ = self.class_prior_
constant = self.constant
if self.n_outputs_ == 1 and not self.output_2d_:
if self.n_outputs_ == 1:
# Get same type even for self.n_outputs_ == 1
n_classes_ = [n_classes_]
classes_ = [classes_]
Expand All @@ -191,7 +190,7 @@ def predict(self, X):
# Compute probability only once
if self.strategy == "stratified":
proba = self.predict_proba(X)
if self.n_outputs_ == 1 and not self.output_2d_:
if self.n_outputs_ == 1:
proba = [proba]

if self.sparse_output_:
Expand Down Expand Up @@ -228,7 +227,7 @@ def predict(self, X):
elif self.strategy == "constant":
y = np.tile(self.constant, (n_samples, 1))

if self.n_outputs_ == 1 and not self.output_2d_:
if self.n_outputs_ == 1:
y = np.ravel(y)

return y
Expand Down Expand Up @@ -260,7 +259,7 @@ def predict_proba(self, X):
classes_ = self.classes_
class_prior_ = self.class_prior_
constant = self.constant
if self.n_outputs_ == 1 and not self.output_2d_:
if self.n_outputs_ == 1:
# Get same type even for self.n_outputs_ == 1
n_classes_ = [n_classes_]
classes_ = [classes_]
Expand Down Expand Up @@ -291,7 +290,7 @@ def predict_proba(self, X):

P.append(out)

if self.n_outputs_ == 1 and not self.output_2d_:
if self.n_outputs_ == 1:
P = P[0]

return P
Expand Down Expand Up @@ -352,6 +351,15 @@ def score(self, X, y, sample_weight=None):
X = np.zeros(shape=(len(y), 1))
return super().score(X, y, sample_weight)

@deprecated(
"The outputs_2d_ attribute is deprecated in version 0.22 "
"and will be removed in version 0.24. It is equivalent to "
"n_outputs_ != 1."
NicolasHug marked this conversation as resolved.
Show resolved Hide resolved
)
@property
def outputs_2d_(self):
return self.n_outputs_ != 1


class DummyRegressor(MultiOutputMixin, RegressorMixin, BaseEstimator):
"""
Expand Down Expand Up @@ -426,8 +434,6 @@ def fit(self, X, y, sample_weight=None):
if len(y) == 0:
raise ValueError("y must not be empty.")

self.output_2d_ = y.ndim == 2 and y.shape[1] > 1

if y.ndim == 1:
y = np.reshape(y, (-1, 1))
self.n_outputs_ = y.shape[1]
Expand Down Expand Up @@ -467,7 +473,7 @@ def fit(self, X, y, sample_weight=None):
accept_sparse=['csr', 'csc', 'coo'],
ensure_2d=False, ensure_min_samples=0)

if self.output_2d_ and self.constant.shape[0] != y.shape[1]:
if self.n_outputs_ != 1 and self.constant.shape[0] != y.shape[1]:
raise ValueError(
"Constant target value should have "
"shape (%d, 1)." % y.shape[1])
Expand Down Expand Up @@ -505,7 +511,7 @@ def predict(self, X, return_std=False):
dtype=np.array(self.constant_).dtype)
y_std = np.zeros((n_samples, self.n_outputs_))

if self.n_outputs_ == 1 and not self.output_2d_:
if self.n_outputs_ == 1:
y = np.ravel(y)
y_std = np.ravel(y_std)

Expand Down Expand Up @@ -551,3 +557,12 @@ def score(self, X, y, sample_weight=None):
if X is None:
X = np.zeros(shape=(len(y), 1))
return super().score(X, y, sample_weight)

@deprecated(
"The outputs_2d_ attribute is deprecated in version 0.22 "
"and will be removed in version 0.24. It is equivalent to "
"n_outputs_ != 1."
)
@property
def outputs_2d_(self):
return self.n_outputs_ != 1
9 changes: 9 additions & 0 deletions sklearn/tests/test_dummy.py
Original file line number Diff line number Diff line change
Expand Up @@ -737,3 +737,12 @@ def test_dtype_of_classifier_probas(strategy):
probas = model.fit(X, y).predict_proba(X)

assert probas.dtype == np.float64


@pytest.mark.parametrize("Dummy", (DummyRegressor, DummyClassifier))
def test_outputs_2d_deprecation(Dummy):
X = [[1, 2]]
y = [0]
with pytest.warns(DeprecationWarning,
match="will be removed in version 0.24"):
Dummy().fit(X, y).outputs_2d_