8000 make check_array convert object to float. · scikit-learn/scikit-learn@8485f77 · GitHub
[go: up one dir, main page]

Skip to content

Commit 8485f77

Browse files
committed
make check_array convert object to float.
fix dtype check, add test. unfriend all multi-output estimators on facebook. try to fix what is happening to y (by doing nothing to y) make test work... Make everything accept object y or say "invalid label" fix multioutput linear models add test for sensible error message.
1 parent bf203de commit 8485f77

File tree

14 files changed

+98
-44
lines changed

14 files changed

+98
-44
lines changed

sklearn/ensemble/gradient_boosting.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
from __future__ import print_function
2424
from __future__ import division
2525
from abc import ABCMeta, abstractmethod
26-
from warnings import warn
2726
from time import time
2827

2928
import numbers
@@ -1143,10 +1142,12 @@ def feature_importances_(self):
11431142

11441143
def _validate_y(self, y):
11451144
self.n_classes_ = 1
1146-
1145+
if y.dtype is np.dtype(object):
1146+
y = y.astype(np.float)
11471147
# Default implementation
11481148
return y
11491149

1150+
11501151
class GradientBoostingClassifier(BaseGradientBoosting, ClassifierMixin):
11511152
"""Gradient Boosting for classification.
11521153

sklearn/gaussian_process/gaussian_process.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@
1111

1212
from ..base import BaseEstimator, RegressorMixin
1313
from ..metrics.pairwise import manhattan_distances
14-
from ..utils import check_random_state, check_array, check_consistent_length
15-
from ..utils.validation import check_is_fitted
14+
from ..utils import check_random_state, check_array, check_X_y
15+
from ..utils.validation import check_is_fitted
1616
from . import regression_models as regression
1717
from . import correlation_models as correlation
1818

@@ -264,12 +264,10 @@ def fit(self, X, y):
264264
self.random_state = check_random_state(self.random_state)
265265

266266
# Force data to 2D numpy.array
267-
X = check_array(X)
268-
y = np.asarray(y)
267+
X, y = check_X_y(X, y, multi_output=True, y_numeric=True)
269268
self.y_ndim_ = y.ndim
270269
if y.ndim == 1:
271270
y = y[:, np.newaxis]
272-
check_consistent_length(X, y)
273271

274272
# Check shapes of DOE & observations
275273
n_samples, n_features = X.shape
@@ -882,7 +880,7 @@ def _check_params(self, n_samples=None):
882880
"or array of length n_samples.")
883881

884882
# Check optimizer
885-
if not self.optimizer in self._optimizer_types:
883+
if self.optimizer not in self._optimizer_types:
886884
raise ValueError("optimizer should be one of %s"
887885
% self._optimizer_types)
888886

sklearn/linear_model/base.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
from ..externals import six
2626
from ..externals.joblib import Parallel, delayed
2727
from ..base import BaseEstimator, ClassifierMixin, RegressorMixin
28-
from ..utils import as_float_array, check_array
28+
from ..utils import as_float_array, check_array, check_X_y
2929
from ..utils.extmath import safe_sparse_dot
3030
from ..utils.sparsefuncs import mean_variance_axis, inplace_column_scale
3131
from ..utils.fixes import sparse_lsqr
@@ -372,8 +372,8 @@ def fit(self, X, y, n_jobs=1):
372372
n_jobs_ = n_jobs
373373
else:
374374
n_jobs_ = self.n_jobs
375-
X = check_array(X, accept_sparse=['csr', 'csc', 'coo'])
376-
y = np.asarray(y)
375+
X, y = check_X_y(X, y, accept_sparse=['csr', 'csc', 'coo'],
376+
y_numeric=True, multi_output=True)
377377

378378
X, y, X_mean, y_mean, X_std = self._center_data(
379379
X, y, self.fit_intercept, self.normalize, self.copy_X)

sklearn/linear_model/bayes.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ def fit(self, X, y):
132132
-------
133133
self : returns an instance of self.
134134
"""
135-
X, y = check_X_y(X, y, dtype=np.float)
135+
X, y = check_X_y(X, y, dtype=np.float, y_numeric=True)
136136
X, y, X_mean, y_mean, X_std = self._center_data(
137137
X, y, self.fit_intercept, self.normalize, self.copy_X)
138138
n_samples, n_features = X.shape
@@ -342,7 +342,7 @@ def fit(self, X, y):
342342
-------
343343
self : returns an instance of self.
344344
"""
345-
X, y = check_X_y(X, y, dtype=np.float)
345+
X, y = check_X_y(X, y, dtype=np.float, y_numeric=True)
346346

347347
n_samples, n_features = X.shape
348348
coef_ = np.zeros(n_features)

sklearn/linear_model/coordinate_descent.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -389,7 +389,6 @@ def enet_path(X, y, l1_ratio=0.5, eps=1e-3, n_alphas=100, alphas=None,
389389
if selection not in ['random', 'cyclic']:
390390
raise ValueError("selection should be either random or cyclic.")
391391
random = (selection == 'random')
392-
models = []
393392

394393
if not multi_output:
395394
coefs = np.empty((n_features, n_alphas), dtype=np.float64)
@@ -618,7 +617,7 @@ def fit(self, X, y):
618617

619618
X, y = check_X_y(X, y, accept_sparse='csc', dtype=np.float64,
620619
order='F', copy=self.copy_X and self.fit_intercept,
621-
multi_output=True)
620+
multi_output=True, y_numeric=True)
622621

623622
X, y, X_mean, y_mean, X_std, precompute, Xy = \
624623
_pre_fit(X, y, None, self.precompute, self.normalize,

sklearn/linear_model/least_angle.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121

2222
from .base import LinearModel
2323
from ..base import RegressorMixin
24-
from ..utils import arrayfuncs, as_float_array, check_array, check_X_y
24+
from ..utils import arrayfuncs, as_float_array, check_X_y
2525
from ..cross_validation import _check_cv as check_cv
2626
from ..utils import ConvergenceWarning
2727
from ..externals.joblib import Parallel, delayed
@@ -422,7 +422,7 @@ def lars_path(X, y, Xy=None, Gram=None, max_iter=500,
422422
for ii in idx:
423423
for i in range(ii, n_active):
424424
indices[i], indices[i + 1] = indices[i + 1], indices[i]
425-
Gram[i], Gram[i + 1] = swap(Gram[i], Gram[i+1])
425+
Gram[i], Gram[i + 1] = swap(Gram[i], Gram[i + 1])
426426
Gram[:, i], Gram[:, i + 1] = swap(Gram[:, i],
427427
Gram[:, i + 1])
428428

@@ -589,8 +589,7 @@ def fit(self, X, y, Xy=None):
589589
self : object
590590
returns an instance of self.
591591
"""
592-
X = check_array(X)
593-
y = np.asarray(y)
592+
X, y = check_X_y(X, y, y_numeric=True, multi_output=True)
594593
n_features = X.shape[1]
595594

596595
X, y, X_mean, y_mean, X_std = self._center_data(X, y,
@@ -1268,8 +1267,7 @@ def fit(self, X, y, copy_X=True):
12681267
returns an instance of self.
12691268
"""
12701269
self.fit_path = True
1271-
X = check_array(X)
1272-
y = np.asarray(y)
1270+
X, y = check_X_y(X, y, multi_output=True, y_numeric=True)
12731271

12741272
X, y, Xmean, ymean, Xstd = LinearModel._center_data(
12751273
X, y, self.fit_intercept, self.normalize, self.copy_X)

sklearn/linear_model/logistic.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -529,7 +529,7 @@ def logistic_regression_path(X, y, pos_class=None, Cs=10, fit_intercept=True,
529529
"dual=False, got dual=%s" % dual)
530530
# Preprocessing.
531531
X = check_array(X, accept_sparse='csr', dtype=np.float64)
532-
y = check_array(y, ensure_2d=False, copy=copy)
532+
y = check_array(y, ensure_2d=False, copy=copy, dtype=None)
533533
_, n_features = X.shape
534534
check_consistent_length(X, y)
535535
classes = np.unique(y)
@@ -1318,7 +1318,7 @@ def fit(self, X, y):
13181318
"the primal form.")
13191319

13201320
X = check_array(X, accept_sparse='csr', dtype=np.float64)
1321-
y = check_array(y, ensure_2d=False)
1321+
y = check_array(y, ensure_2d=False, dtype=None)
13221322

13231323
if self.multi_class not in ['ovr', 'multinomial']:
13241324
raise ValueError("multi_class backend should be either "

sklearn/linear_model/omp.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -609,8 +609,7 @@ def fit(self, X, y):
609609
self : object
610610
returns an instance of self.
611611
"""
612-
X = check_array(X)
613-
y = np.asarray(y)
612+
X, y = check_X_y(X, y, multi_output=True, y_numeric=True)
614613
n_features = X.shape[1]
615614

616615
X, y, X_mean, y_mean, X_std, Gram, Xy = \
@@ -805,7 +804,7 @@ def fit(self, X, y):
805804
self : object
806805
returns an instance of self.
807806
"""
808-
X, y = check_X_y(X, y)
807+
X, y = check_X_y(X, y, y_numeric=True)
809808
cv = check_cv(self.cv, X, y, classifier=False)
810809
max_iter = (min(max(int(0.1 * X.shape[1]), 5), X.shape[1])
811810
if not self.max_iter

sklearn/linear_model/randomized_l1.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ def fit(self, X, y):
8888
self : object
8989
Returns an instance of self.
9090
"""
91-
X, y = check_X_y(X, y, ['csr', 'csc', 'coo'])
91+
X, y = check_X_y(X, y, ['csr', 'csc', 'coo'], y_numeric=True)
9292
X = as_float_array(X, copy=False)
9393
n_samples, n_features = X.shape
9494

sklearn/linear_model/ridge.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -365,7 +365,8 @@ def __init__(self, alpha=1.0, fit_intercept=True, normalize=False,
365365
self.solver = solver
366366

367367
def fit(self, X, y, sample_weight=None):
368-
X, y = check_X_y(X, y, ['csr', 'csc', 'coo'], dtype=np.float, multi_output=True)
368+
X, y = check_X_y(X, y, ['csr', 'csc', 'coo'], dtype=np.float,
369+
multi_output=True, y_numeric=True)
369370

370371
if ((sample_weight is not None) and
371372
np.atleast_1d(sample_weight).ndim > 1):
@@ -732,7 +733,8 @@ def fit(self, X, y, sample_weight=None):
732733
-------
733734
self : Returns self.
734735
"""
735-
X, y = check_X_y(X, y, ['csr', 'csc', 'coo'], dtype=np.float, multi_output=True)
736+
X, y = check_X_y(X, y, ['csr', 'csc', 'coo'], dtype=np.float,
737+
multi_output=True, y_numeric=True)
736738

737739
n_samples, n_features = X.shape
738740

sklearn/preprocessing/label.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -464,7 +464,7 @@ def label_binarize(y, classes, neg_label=0, pos_label=1,
464464
if not isinstance(y, list):
465465
# XXX Workaround that will be removed when list of list format is
466466
# dropped
467-
y = check_array(y, accept_sparse='csr', ensure_2d=False)
467+
y = check_array(y, accept_sparse='csr', ensure_2d=False, dtype=None)
468468
if neg_label >= pos_label:
469469
raise ValueError("neg_label={0} must be strictly less than "
470470
"pos_label={1}.".format(neg_label, pos_label))

sklearn/tests/test_common.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
from sklearn.cross_validation import train_test_split
2929
from sklearn.linear_model.base import LinearClassifierMixin
3030
from sklearn.utils.estimator_checks import (
31+
check_dtype_object,
3132
check_parameters_default_constructible,
3233
check_estimator_sparse_data,
3334
check_transformer,
@@ -87,12 +88,13 @@ def test_non_meta_estimators():
8788
estimators = all_estimators(type_filter=['classifier', 'regressor',
8889
'transformer', 'cluster'])
8990
for name, Estimator in estimators:
91+
if name not in CROSS_DECOMPOSITION:
92+
yield check_dtype_object, name, Estimator
9093
if name not in CROSS_DECOMPOSITION + ['Imputer']:
9194
# Test that all estimators check their input for NaN's and infs
9295
yield check_estimators_nan_inf, name, Estimator
9396

94-
if (name not in ['CCA', '_CCA', 'PLSCanonical', 'PLSRegression',
95-
'PLSSVD', 'GaussianProcess']):
97+
if (name not in CROSS_DECOMPOSITION + ['GaussianProcess']):
9698
# FIXME!
9799
# in particular GaussianProcess!
98100
yield check_estimators_overwrite_params, name, Estimator

sklearn/utils/estimator_checks.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
from sklearn.utils.testing import assert_greater
2323
from sklearn.utils.testing import SkipTest
2424
from sklearn.utils.testing import check_skip_travis
25+
from sklearn.utils.testing import assert_raise_message
2526

2627
from sklearn.base import (clone, ClusterMixin, ClassifierMixin, RegressorMixin,
2728
TransformerMixin)
@@ -153,6 +154,39 @@ def check_estimator_sparse_data(name, Estimator):
153154
raise
154155

155156

157+
def check_dtype_object(name, Estimator):
158+
rng = np.random.RandomState(0)
159+
X = rng.rand(40, 10).astype(object)
160+
y = (X[:, 0] * 4).astype(np.int)
161+
y = multioutput_estimator_convert_y_2d(name, y)
162+
with warnings.catch_warnings():
163+
estimator = Estimator()
164+
set_fast_parameters(estimator)
165+
166+
if is_supervised(estimator):
167+
estimator.fit(X, y)
168+
else:
169+
estimator.fit(X)
170+
if hasattr(estimator, "predict"):
171+
estimator.predict(X)
172+
173+
if hasattr(estimator, "transform"):
174+
estimator.transform(X)
175+
176+
if is_supervised(estimator):
177+
try:
178+
estimator.fit(X, y.astype(object))
179+
except Exception as e:
180+
if "Unknown label type" not in str(e):
181+
raise
182+
183+
X[0, 0] = {'foo': 'bar'}
184+
if is_supervised(estimator):
185+
assert_raise_message(TypeError, "string or a number", estimator.fit, X, y)
186+
else:
187+
assert_raise_message(TypeError, "string or a number", estimator.fit, X)
188+
189+
156190
def check_transformer(name, Transformer):
157191
X, y = make_blobs(n_samples=30, centers=[[0, 0, 0], [1, 1, 1]],
158192
random_state=0, n_features=2, cluster_std=0.1)

0 commit comments

Comments
 (0)
0