2011-11-30 18:05:10 +08:00
|
|
|
"""
|
2013-06-27 21:09:16 +08:00
|
|
|
The :mod:`sklearn.utils` module includes various utilities.
|
2011-11-30 18:05:10 +08:00
|
|
|
"""
|
2013-03-11 05:14:10 +08:00
|
|
|
from collections import Sequence
|
|
|
|
|
|
2011-01-20 20:47:30 +08:00
|
|
|
import numpy as np
|
2012-08-15 06:33:41 +08:00
|
|
|
from scipy.sparse import issparse
|
2011-07-24 03:10:06 +08:00
|
|
|
import warnings
|
2011-01-20 20:47:30 +08:00
|
|
|
|
2012-01-17 09:30:59 +08:00
|
|
|
from .murmurhash import murmurhash3_32
|
2014-07-20 19:31:45 +08:00
|
|
|
from .validation import (as_float_array,
|
2015-05-01 00:48:52 +08:00
|
|
|
assert_all_finite,
|
2014-07-20 19:31:45 +08:00
|
|
|
check_random_state, column_or_1d, check_array,
|
2014-12-29 13:02:35 +08:00
|
|
|
check_consistent_length, check_X_y, indexable,
|
2015-06-06 02:45:45 +08:00
|
|
|
check_symmetric)
|
2015-10-19 23:31:36 +08:00
|
|
|
from .deprecation import deprecated
|
2015-02-01 10:26:41 +08:00
|
|
|
from .class_weight import compute_class_weight, compute_sample_weight
|
2014-09-06 17:48:48 +08:00
|
|
|
from ..externals.joblib import cpu_count
|
2015-10-20 06:54:35 +08:00
|
|
|
from ..exceptions import ConvergenceWarning as ConvergenceWarning_
|
2015-10-19 23:31:36 +08:00
|
|
|
from ..exceptions import DataConversionWarning as DataConversionWarning_
|
2013-05-23 11:17:18 +08:00
|
|
|
|
2011-08-24 00:28:29 +08:00
|
|
|
|
2015-10-20 06:54:35 +08:00
|
|
|
class ConvergenceWarning(ConvergenceWarning_):
|
|
|
|
|
pass
|
|
|
|
|
|
2015-06-06 02:45:45 +08:00
|
|
|
ConvergenceWarning = deprecated("ConvergenceWarning has been moved "
|
|
|
|
|
"into the sklearn.exceptions module. "
|
|
|
|
|
"It will not be available here from "
|
|
|
|
|
"version 0.19")(ConvergenceWarning)
|
|
|
|
|
|
|
|
|
|
|
2014-07-20 19:31:45 +08:00
|
|
|
__all__ = ["murmurhash3_32", "as_float_array",
|
|
|
|
|
"assert_all_finite", "check_array",
|
2014-04-28 10:17:05 +08:00
|
|
|
"check_random_state",
|
2015-02-01 10:26:41 +08:00
|
|
|
"compute_class_weight", "compute_sample_weight",
|
2014-07-20 19:31:45 +08:00
|
|
|
"column_or_1d", "safe_indexing",
|
2015-02-17 11:19:03 +08:00
|
|
|
"check_consistent_length", "check_X_y", 'indexable',
|
|
|
|
|
"check_symmetric"]
|
2012-12-22 20:02:50 +08:00
|
|
|
|
2013-06-04 01:19:55 +08:00
|
|
|
|
2012-01-13 14:31:45 +08:00
|
|
|
def safe_mask(X, mask):
|
2012-01-13 18:28:55 +08:00
|
|
|
"""Return a mask which is safe to use on X.
|
2012-01-13 14:31:45 +08:00
|
|
|
|
|
|
|
|
Parameters
|
|
|
|
|
----------
|
2012-09-18 17:13:33 +08:00
|
|
|
X : {array-like, sparse matrix}
|
|
|
|
|
Data on which to apply mask.
|
2012-01-13 14:31:45 +08:00
|
|
|
|
2012-09-18 17:13:33 +08:00
|
|
|
mask: array
|
|
|
|
|
Mask to be used on X.
|
2012-01-13 14:31:45 +08:00
|
|
|
|
|
|
|
|
Returns
|
|
|
|
|
-------
|
|
|
|
|
mask
|
|
|
|
|
"""
|
2013-07-11 21:54:13 +08:00
|
|
|
mask = np.asarray(mask)
|
2012-08-27 19:35:17 +08:00
|
|
|
if np.issubdtype(mask.dtype, np.int):
|
|
|
|
|
return mask
|
|
|
|
|
|
2012-01-13 14:31:45 +08:00
|
|
|
if hasattr(X, "toarray"):
|
|
|
|
|
ind = np.arange(mask.shape[0])
|
|
|
|
|
mask = ind[mask]
|
|
|
|
|
return mask
|
|
|
|
|
|
|
|
|
|
|
2014-04-28 10:17:05 +08:00
|
|
|
def safe_indexing(X, indices):
|
|
|
|
|
"""Return items or rows from X using indices.
|
|
|
|
|
|
|
|
|
|
Allows simple indexing of lists or arrays.
|
|
|
|
|
|
|
|
|
|
Parameters
|
|
|
|
|
----------
|
|
|
|
|
X : array-like, sparse-matrix, list.
|
|
|
|
|
Data from which to sample rows or items.
|
|
|
|
|
|
|
|
|
|
indices : array-like, list
|
|
|
|
|
Indices according to which X will be subsampled.
|
|
|
|
|
"""
|
2014-07-18 16:02:14 +08:00
|
|
|
if hasattr(X, "iloc"):
|
|
|
|
|
# Pandas Dataframes and Series
|
2015-05-06 07:26:35 +08:00
|
|
|
try:
|
|
|
|
|
return X.iloc[indices]
|
|
|
|
|
except ValueError:
|
|
|
|
|
# Cython typed memoryviews internally used in pandas do not support
|
|
|
|
|
# readonly buffers.
|
|
|
|
|
warnings.warn("Copying input dataframe for slicing.",
|
2015-06-06 02:45:45 +08:00
|
|
|
DataConversionWarning_)
|
2015-05-06 07:26:35 +08:00
|
|
|
return X.copy().iloc[indices]
|
2014-07-18 16:02:14 +08:00
|
|
|
elif hasattr(X, "shape"):
|
2014-08-07 17:45:21 +08:00
|
|
|
if hasattr(X, 'take') and (hasattr(indices, 'dtype') and
|
|
|
|
|
indices.dtype.kind == 'i'):
|
|
|
|
|
# This is often substantially faster than X[indices]
|
|
|
|
|
return X.take(indices, axis=0)
|
|
|
|
|
else:
|
|
|
|
|
return X[indices]
|
2014-04-28 10:17:05 +08:00
|
|
|
else:
|
|
|
|
|
return [X[idx] for idx in indices]
|
|
|
|
|
|
|
|
|
|
|
2011-05-21 20:32:43 +08:00
|
|
|
def resample(*arrays, **options):
|
2011-05-21 20:46:16 +08:00
|
|
|
"""Resample arrays or sparse matrices in a consistent way
|
2011-05-17 15:49:05 +08:00
|
|
|
|
2011-05-21 20:32:43 +08:00
|
|
|
The default strategy implements one step of the bootstrapping
|
|
|
|
|
procedure.
|
|
|
|
|
|
2011-05-17 15:49:05 +08:00
|
|
|
Parameters
|
|
|
|
|
----------
|
2015-04-10 01:16:59 +08:00
|
|
|
*arrays : sequence of indexable data-structures
|
|
|
|
|
Indexable data-structures can be arrays, lists, dataframes or scipy
|
|
|
|
|
sparse matrices with consistent first dimension.
|
2011-05-17 15:49:05 +08:00
|
|
|
|
2011-05-21 20:32:43 +08:00
|
|
|
replace : boolean, True by default
|
|
|
|
|
Implements resampling with replacement. If False, this will implement
|
|
|
|
|
(sliced) random permutations.
|
|
|
|
|
|
|
|
|
|
n_samples : int, None by default
|
|
|
|
|
Number of samples to generate. If left to None this is
|
|
|
|
|
automatically set to the first dimension of the arrays.
|
|
|
|
|
|
2011-05-17 15:49:05 +08:00
|
|
|
random_state : int or RandomState instance
|
|
|
|
|
Control the shuffling for reproducible behavior.
|
|
|
|
|
|
2011-12-23 02:34:33 +08:00
|
|
|
Returns
|
|
|
|
|
-------
|
2015-04-10 01:16:59 +08:00
|
|
|
resampled_arrays : sequence of indexable data-structures
|
2015-03-19 02:51:37 +08:00
|
|
|
Sequence of resampled views of the collections. The original arrays are
|
2014-12-29 11:18:45 +08:00
|
|
|
not impacted.
|
2011-05-17 15:49:05 +08:00
|
|
|
|
2011-12-23 02:47:49 +08:00
|
|
|
Examples
|
|
|
|
|
--------
|
2011-05-17 15:49:05 +08:00
|
|
|
It is possible to mix sparse and dense arrays in the same run::
|
|
|
|
|
|
2015-04-10 01:16:59 +08:00
|
|
|
>>> X = np.array([[1., 0.], [2., 1.], [0., 0.]])
|
2011-05-17 15:49:05 +08:00
|
|
|
>>> y = np.array([0, 1, 2])
|
|
|
|
|
|
|
|
|
|
>>> from scipy.sparse import coo_matrix
|
|
|
|
|
>>> X_sparse = coo_matrix(X)
|
|
|
|
|
|
2011-09-02 17:00:02 +08:00
|
|
|
>>> from sklearn.utils import resample
|
2011-05-21 20:32:43 +08:00
|
|
|
>>> X, X_sparse, y = resample(X, X_sparse, y, random_state=0)
|
2011-05-17 15:49:05 +08:00
|
|
|
>>> X
|
2011-05-21 20:32:43 +08:00
|
|
|
array([[ 1., 0.],
|
2011-05-17 15:49:05 +08:00
|
|
|
[ 2., 1.],
|
|
|
|
|
[ 1., 0.]])
|
|
|
|
|
|
2012-03-13 03:57:32 +08:00
|
|
|
>>> X_sparse # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
|
|
|
|
|
<3x2 sparse matrix of type '<... 'numpy.float64'>'
|
2011-05-21 20:32:43 +08:00
|
|
|
with 4 stored elements in Compressed Sparse Row format>
|
2011-05-17 15:49:05 +08:00
|
|
|
|
|
|
|
|
>>> X_sparse.toarray()
|
2011-05-21 20:32:43 +08:00
|
|
|
array([[ 1., 0.],
|
2011-05-17 15:49:05 +08:00
|
|
|
[ 2., 1.],
|
|
|
|
|
[ 1., 0.]])
|
|
|
|
|
|
|
|
|
|
>>> y
|
2011-05-21 20:32:43 +08:00
|
|
|
array([0, 1, 0])
|
|
|
|
|
|
|
|
|
|
>>> resample(y, n_samples=2, random_state=0)
|
|
|
|
|
array([0, 1])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
See also
|
|
|
|
|
--------
|
2011-09-02 17:00:02 +08:00
|
|
|
:func:`sklearn.utils.shuffle`
|
2011-05-17 15:49:05 +08:00
|
|
|
"""
|
2011-05-18 00:44:01 +08:00
|
|
|
random_state = check_random_state(options.pop('random_state', None))
|
2011-05-21 20:32:43 +08:00
|
|
|
replace = options.pop('replace', True)
|
|
|
|
|
max_n_samples = options.pop('n_samples', None)
|
2011-05-18 00:44:01 +08:00
|
|
|
if options:
|
|
|
|
|
raise ValueError("Unexpected kw arguments: %r" % options.keys())
|
2011-05-17 15:49:05 +08:00
|
|
|
|
2011-05-18 00:44:01 +08:00
|
|
|
if len(arrays) == 0:
|
2011-05-18 08:15:50 +08:00
|
|
|
return None
|
2011-05-17 15:49:05 +08:00
|
|
|
|
2011-05-18 00:44:01 +08:00
|
|
|
first = arrays[0]
|
2011-05-17 15:49:05 +08:00
|
|
|
n_samples = first.shape[0] if hasattr(first, 'shape') else len(first)
|
|
|
|
|
|
2011-05-21 20:32:43 +08:00
|
|
|
if max_n_samples is None:
|
|
|
|
|
max_n_samples = n_samples
|
|
|
|
|
|
|
|
|
|
if max_n_samples > n_samples:
|
|
|
|
|
raise ValueError("Cannot sample %d out of arrays with dim %d" % (
|
|
|
|
|
max_n_samples, n_samples))
|
|
|
|
|
|
2014-07-20 19:31:45 +08:00
|
|
|
check_consistent_length(*arrays)
|
2011-05-22 06:29:51 +08:00
|
|
|
|
2011-05-21 20:32:43 +08:00
|
|
|
if replace:
|
|
|
|
|
indices = random_state.randint(0, n_samples, size=(max_n_samples,))
|
|
|
|
|
else:
|
2011-05-21 20:46:16 +08:00
|
|
|
indices = np.arange(n_samples)
|
2011-05-21 20:32:43 +08:00
|
|
|
random_state.shuffle(indices)
|
2011-05-21 20:46:16 +08:00
|
|
|
indices = indices[:max_n_samples]
|
2011-05-21 20:32:43 +08:00
|
|
|
|
2015-04-10 01:16:59 +08:00
|
|
|
# convert sparse matrices to CSR for row-based indexing
|
|
|
|
|
arrays = [a.tocsr() if issparse(a) else a for a in arrays]
|
|
|
|
|
resampled_arrays = [safe_indexing(a, indices) for a in arrays]
|
2011-05-21 20:32:43 +08:00
|
|
|
if len(resampled_arrays) == 1:
|
2011-05-18 08:15:50 +08:00
|
|
|
# syntactic sugar for the unit argument case
|
2011-05-21 20:32:43 +08:00
|
|
|
return resampled_arrays[0]
|
2011-05-18 08:15:50 +08:00
|
|
|
else:
|
2011-05-21 20:32:43 +08:00
|
|
|
return resampled_arrays
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def shuffle(*arrays, **options):
|
|
|
|
|
"""Shuffle arrays or sparse matrices in a consistent way
|
|
|
|
|
|
2011-12-21 23:11:16 +08:00
|
|
|
This is a convenience alias to ``resample(*arrays, replace=False)`` to do
|
2011-05-21 20:46:16 +08:00
|
|
|
random permutations of the collections.
|
2011-05-21 20:32:43 +08:00
|
|
|
|
|
|
|
|
Parameters
|
|
|
|
|
----------
|
2015-04-10 01:16:59 +08:00
|
|
|
*arrays : sequence of indexable data-structures
|
|
|
|
|
Indexable data-structures can be arrays, lists, dataframes or scipy
|
|
|
|
|
sparse matrices with consistent first dimension.
|
2011-05-21 20:32:43 +08:00
|
|
|
|
|
|
|
|
random_state : int or RandomState instance
|
|
|
|
|
Control the shuffling for reproducible behavior.
|
|
|
|
|
|
2011-05-21 20:46:16 +08:00
|
|
|
n_samples : int, None by default
|
|
|
|
|
Number of samples to generate. If left to None this is
|
|
|
|
|
automatically set to the first dimension of the arrays.
|
|
|
|
|
|
2011-12-23 02:34:33 +08:00
|
|
|
Returns
|
|
|
|
|
-------
|
2015-04-10 01:16:59 +08:00
|
|
|
shuffled_arrays : sequence of indexable data-structures
|
2014-12-29 11:18:45 +08:00
|
|
|
Sequence of shuffled views of the collections. The original arrays are
|
|
|
|
|
not impacted.
|
2011-05-21 20:32:43 +08:00
|
|
|
|
2011-12-23 02:47:49 +08:00
|
|
|
Examples
|
|
|
|
|
--------
|
2011-05-21 20:32:43 +08:00
|
|
|
It is possible to mix sparse and dense arrays in the same run::
|
|
|
|
|
|
2015-04-10 01:16:59 +08:00
|
|
|
>>> X = np.array([[1., 0.], [2., 1.], [0., 0.]])
|
2011-05-21 20:32:43 +08:00
|
|
|
>>> y = np.array([0, 1, 2])
|
|
|
|
|
|
|
|
|
|
>>> from scipy.sparse import coo_matrix
|
|
|
|
|
>>> X_sparse = coo_matrix(X)
|
|
|
|
|
|
2011-09-02 17:00:02 +08:00
|
|
|
>>> from sklearn.utils import shuffle
|
2011-05-21 20:32:43 +08:00
|
|
|
>>> X, X_sparse, y = shuffle(X, X_sparse, y, random_state=0)
|
|
|
|
|
>>> X
|
|
|
|
|
array([[ 0., 0.],
|
|
|
|
|
[ 2., 1.],
|
|
|
|
|
[ 1., 0.]])
|
|
|
|
|
|
2012-05-16 03:18:30 +08:00
|
|
|
>>> X_sparse # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
|
2012-03-13 03:57:32 +08:00
|
|
|
<3x2 sparse matrix of type '<... 'numpy.float64'>'
|
2011-05-21 20:32:43 +08:00
|
|
|
with 3 stored elements in Compressed Sparse Row format>
|
|
|
|
|
|
|
|
|
|
>>> X_sparse.toarray()
|
|
|
|
|
array([[ 0., 0.],
|
|
|
|
|
[ 2., 1.],
|
|
|
|
|
[ 1., 0.]])
|
|
|
|
|
|
|
|
|
|
>>> y
|
|
|
|
|
array([2, 1, 0])
|
|
|
|
|
|
2011-05-21 20:46:16 +08:00
|
|
|
>>> shuffle(y, n_samples=2, random_state=0)
|
|
|
|
|
array([0, 1])
|
|
|
|
|
|
2011-05-21 20:32:43 +08:00
|
|
|
See also
|
|
|
|
|
--------
|
2011-09-02 17:00:02 +08:00
|
|
|
:func:`sklearn.utils.resample`
|
2011-05-21 20:32:43 +08:00
|
|
|
"""
|
|
|
|
|
options['replace'] = False
|
|
|
|
|
return resample(*arrays, **options)
|
2011-07-17 01:48:08 +08:00
|
|
|
|
|
|
|
|
|
2012-08-15 18:03:59 +08:00
|
|
|
def safe_sqr(X, copy=True):
|
2012-08-15 06:33:41 +08:00
|
|
|
"""Element wise squaring of array-likes and sparse matrices.
|
|
|
|
|
|
|
|
|
|
Parameters
|
|
|
|
|
----------
|
|
|
|
|
X : array like, matrix, sparse matrix
|
|
|
|
|
|
2014-12-29 11:18:45 +08:00
|
|
|
copy : boolean, optional, default True
|
|
|
|
|
Whether to create a copy of X and operate on it or to perform
|
|
|
|
|
inplace computation (default behaviour).
|
|
|
|
|
|
2012-08-15 06:33:41 +08:00
|
|
|
Returns
|
|
|
|
|
-------
|
|
|
|
|
X ** 2 : element wise square
|
|
|
|
|
"""
|
2015-08-25 07:52:40 +08:00
|
|
|
X = check_array(X, accept_sparse=['csr', 'csc', 'coo'], ensure_2d=False)
|
2012-08-15 06:33:41 +08:00
|
|
|
if issparse(X):
|
2012-08-15 18:03:59 +08:00
|
|
|
if copy:
|
|
|
|
|
X = X.copy()
|
|
|
|
|
X.data **= 2
|
2012-08-15 06:33:41 +08:00
|
|
|
else:
|
2012-08-15 18:03:59 +08:00
|
|
|
if copy:
|
|
|
|
|
X = X ** 2
|
|
|
|
|
else:
|
|
|
|
|
X **= 2
|
|
|
|
|
return X
|
2012-08-15 06:33:41 +08:00
|
|
|
|
|
|
|
|
|
2013-07-29 21:04:31 +08:00
|
|
|
def gen_batches(n, batch_size):
|
|
|
|
|
"""Generator to create slices containing batch_size elements, from 0 to n.
|
|
|
|
|
|
|
|
|
|
The last slice may contain less than batch_size elements, when batch_size
|
|
|
|
|
does not divide n.
|
|
|
|
|
|
|
|
|
|
Examples
|
|
|
|
|
--------
|
|
|
|
|
>>> from sklearn.utils import gen_batches
|
|
|
|
|
>>> list(gen_batches(7, 3))
|
|
|
|
|
[slice(0, 3, None), slice(3, 6, None), slice(6, 7, None)]
|
|
|
|
|
>>> list(gen_batches(6, 3))
|
|
|
|
|
[slice(0, 3, None), slice(3, 6, None)]
|
|
|
|
|
>>> list(gen_batches(2, 3))
|
|
|
|
|
[slice(0, 2, None)]
|
|
|
|
|
"""
|
|
|
|
|
start = 0
|
|
|
|
|
for _ in range(int(n // batch_size)):
|
|
|
|
|
end = start + batch_size
|
|
|
|
|
yield slice(start, end)
|
|
|
|
|
start = end
|
|
|
|
|
if start < n:
|
|
|
|
|
yield slice(start, n)
|
|
|
|
|
|
|
|
|
|
|
2013-10-28 00:51:33 +08:00
|
|
|
def gen_even_slices(n, n_packs, n_samples=None):
|
2011-07-17 01:48:08 +08:00
|
|
|
"""Generator to create n_packs slices going up to n.
|
|
|
|
|
|
2013-10-28 00:51:33 +08:00
|
|
|
Pass n_samples when the slices are to be used for sparse matrix indexing;
|
|
|
|
|
slicing off-the-end raises an exception, while it works for NumPy arrays.
|
|
|
|
|
|
2011-07-17 01:48:08 +08:00
|
|
|
Examples
|
2011-07-23 00:28:19 +08:00
|
|
|
--------
|
2011-09-02 17:00:02 +08:00
|
|
|
>>> from sklearn.utils import gen_even_slices
|
2011-07-19 03:48:53 +08:00
|
|
|
>>> list(gen_even_slices(10, 1))
|
2011-07-17 01:48:08 +08:00
|
|
|
[slice(0, 10, None)]
|
2011-07-19 03:48:53 +08:00
|
|
|
>>> list(gen_even_slices(10, 10)) #doctest: +ELLIPSIS
|
|
|
|
|
[slice(0, 1, None), slice(1, 2, None), ..., slice(9, 10, None)]
|
|
|
|
|
>>> list(gen_even_slices(10, 5)) #doctest: +ELLIPSIS
|
|
|
|
|
[slice(0, 2, None), slice(2, 4, None), ..., slice(8, 10, None)]
|
|
|
|
|
>>> list(gen_even_slices(10, 3))
|
2011-07-17 01:48:08 +08:00
|
|
|
[slice(0, 4, None), slice(4, 7, None), slice(7, 10, None)]
|
|
|
|
|
"""
|
|
|
|
|
start = 0
|
2015-05-21 03:29:25 +08:00
|
|
|
if n_packs < 1:
|
2015-10-19 23:31:36 +08:00
|
|
|
raise ValueError("gen_even_slices got n_packs=%s, must be >=1"
|
|
|
|
|
% n_packs)
|
2011-07-17 01:48:08 +08:00
|
|
|
for pack_num in range(n_packs):
|
|
|
|
|
this_n = n // n_packs
|
|
|
|
|
if pack_num < n % n_packs:
|
|
|
|
|
this_n += 1
|
|
|
|
|
if this_n > 0:
|
|
|
|
|
end = start + this_n
|
2013-10-28 00:51:33 +08:00
|
|
|
if n_samples is not None:
|
|
|
|
|
end = min(n_samples, end)
|
2011-07-17 01:48:08 +08:00
|
|
|
yield slice(start, end, None)
|
|
|
|
|
start = end
|
2011-11-09 17:35:52 +08:00
|
|
|
|
|
|
|
|
|
2014-09-25 01:52:54 +08:00
|
|
|
def _get_n_jobs(n_jobs):
|
2014-09-06 17:48:48 +08:00
|
|
|
"""Get number of jobs for the computation.
|
|
|
|
|
|
|
|
|
|
This function reimplements the logic of joblib to determine the actual
|
|
|
|
|
number of jobs depending on the cpu count. If -1 all CPUs are used.
|
|
|
|
|
If 1 is given, no parallel computing code is used at all, which is useful
|
|
|
|
|
for debugging. For n_jobs below -1, (n_cpus + 1 + n_jobs) are used.
|
|
|
|
|
Thus for n_jobs = -2, all CPUs but one are used.
|
|
|
|
|
|
|
|
|
|
Parameters
|
|
|
|
|
----------
|
|
|
|
|
n_jobs : int
|
|
|
|
|
Number of jobs stated in joblib convention.
|
|
|
|
|
|
|
|
|
|
Returns
|
|
|
|
|
-------
|
|
|
|
|
n_jobs : int
|
|
|
|
|
The actual number of jobs as positive integer.
|
|
|
|
|
|
|
|
|
|
Examples
|
|
|
|
|
--------
|
2014-09-25 01:52:54 +08:00
|
|
|
>>> from sklearn.utils import _get_n_jobs
|
|
|
|
|
>>> _get_n_jobs(4)
|
2014-09-06 18:06:48 +08:00
|
|
|
4
|
2014-09-25 01:52:54 +08:00
|
|
|
>>> jobs = _get_n_jobs(-2)
|
2014-09-06 17:48:48 +08:00
|
|
|
>>> assert jobs == max(cpu_count() - 1, 1)
|
2014-09-25 01:52:54 +08:00
|
|
|
>>> _get_n_jobs(0)
|
2014-09-06 17:48:48 +08:00
|
|
|
Traceback (most recent call last):
|
|
|
|
|
...
|
|
|
|
|
ValueError: Parameter n_jobs == 0 has no meaning.
|
|
|
|
|
"""
|
|
|
|
|
if n_jobs < 0:
|
|
|
|
|
return max(cpu_count() + 1 + n_jobs, 1)
|
|
|
|
|
elif n_jobs == 0:
|
|
|
|
|
raise ValueError('Parameter n_jobs == 0 has no meaning.')
|
|
|
|
|
else:
|
|
|
|
|
return n_jobs
|
|
|
|
|
|
|
|
|
|
|
2013-03-11 05:14:10 +08:00
|
|
|
def tosequence(x):
|
|
|
|
|
"""Cast iterable x to a Sequence, avoiding a copy if possible."""
|
|
|
|
|
if isinstance(x, np.ndarray):
|
|
|
|
|
return np.asarray(x)
|
|
|
|
|
elif isinstance(x, Sequence):
|
|
|
|
|
return x
|
|
|
|
|
else:
|
|
|
|
|
return list(x)
|