# Path: sklearn/utils/validation.py
# def check_array(array, accept_sparse=None, dtype=None, order=None, copy=False,
#                 force_all_finite=True, ensure_2d=True, allow_nd=False):
#     """Input validation on an array, list, sparse matrix or similar.
# 
#     By default, the input is converted to an at least 2nd numpy array.
# 
#     Parameters
#     ----------
#     array : object
#         Input object to check / convert.
# 
#     accept_sparse : string, list of string or None (default=None)
#         String[s] representing allowed sparse matrix formats, such as 'csc',
#         'csr', etc.  None means that sparse matrix input will raise an error.
#         If the input is sparse but not in the allowed format, it will be
#         converted to the first listed format.
# 
#     dtype : string, type or None (default=none)
#         Data type of result. If None, the dtype of the input is preserved.
# 
#     order : 'F', 'C' or None (default=None)
#         Whether an array will be forced to be fortran or c-style.
# 
#     copy : boolean (default=False)
#         Whether a forced copy will be triggered. If copy=False, a copy might
#         be triggered by a conversion.
# 
#     force_all_finite : boolean (default=True)
#         Whether to raise an error on np.inf and np.nan in X.
# 
#     ensure_2d : boolean (default=True)
#         Whether to make X at least 2d.
# 
#     allow_nd : boolean (default=False)
#         Whether to allow X.ndim > 2.
# 
#     Returns
#     -------
#     X_converted : object
#         The converted and validated X.
#     """
#     if isinstance(accept_sparse, str):
#         accept_sparse = [accept_sparse]
# 
#     if sp.issparse(array):
#         array = _ensure_sparse_format(array, accept_sparse, dtype, order,
#                                       copy, force_all_finite)
#     else:
#         if ensure_2d:
#             array = np.atleast_2d(array)
#         array = np.array(array, dtype=dtype, order=order, copy=copy)
#         if not allow_nd and array.ndim >= 3:
#             raise ValueError("Found array with dim %d. Expected <= 2" %
#                              array.ndim)
#         if force_all_finite:
#             _assert_all_finite(array)
# 
#     return array
# 
# Path: sklearn/utils/validation.py
# def check_consistent_length(*arrays):
#     """Check that all arrays have consistent first dimensions.
# 
#     Checks whether all objects in arrays have the same shape or length.
# 
#     Parameters
#     ----------
#     *arrays : list or tuple of input objects.
#         Objects that will be checked for consistent length.
#     """
# 
#     uniques = np.unique([_num_samples(X) for X in arrays if X is not None])
#     if len(uniques) > 1:
#         raise ValueError("Found arrays with inconsistent numbers of samples: %s"
#                          % str(uniques))
# 
# Path: sklearn/utils/validation.py
# def column_or_1d(y, warn=False):
#     """ Ravel column or 1d numpy array, else raises an error
# 
#     Parameters
#     ----------
#     y : array-like
# 
#     warn : boolean, default False
#        To control display of warnings. 
# 
#     Returns
#     -------
#     y : array
# 
#     """
#     shape = np.shape(y)
#     if len(shape) == 1:
#         return np.ravel(y)
#     if len(shape) == 2 and shape[1] == 1:
#         if warn:
#             warnings.warn("A column-vector y was passed when a 1d array was"
#                           " expected. Please change the shape of y to "
#                           "(n_samples, ), for example using ravel().",
#                           DataConversionWarning, stacklevel=2)
#         return np.ravel(y)
# 
#     raise ValueError("bad input shape {0}".format(shape))
# 
# Path: sklearn/utils/validation.py
# def _num_samples(x):
#     """Return number of samples in array-like x."""
#     if not hasattr(x, '__len__') and not hasattr(x, 'shape'):
#         if hasattr(x, '__array__'):
#             x = np.asarray(x)
#         else:
#             raise TypeError("Expected sequence or array-like, got %r" % x)
#     return x.shape[0] if hasattr(x, 'shape') else len(x)


import warnings
import numpy as np
from scipy.sparse import coo_matrix
from scipy.sparse import csr_matrix
from scipy.spatial.distance import hamming as sp_hamming
from ..preprocessing import LabelBinarizer
from ..preprocessing import LabelEncoder
from ..utils import check_array
from ..utils import check_consistent_length
from ..preprocessing import MultiLabelBinarizer
from ..utils import column_or_1d
from ..utils.multiclass import unique_labels
from ..utils.multiclass import type_of_target
from ..utils.validation import _num_samples
from ..utils.sparsefuncs import count_nonzero
from ..utils.fixes import bincount
from .base import UndefinedMetricWarning
         penalty='l2', random_state=None, tol=0.0001, verbose=0)
    >>> pred_decision = est.decision_function([[-1], [2], [3]])
    >>> y_true = [0, 2, 3]
    >>> hinge_loss(y_true, pred_decision, labels)  #doctest: +ELLIPSIS
    0.56...
    """
    check_consistent_length(y_true, pred_decision, sample_weight)
    pred_decision = check_array(pred_decision, ensure_2d=False)
    y_true = column_or_1d(y_true)
    y_true_unique = np.unique(y_true)
    if y_true_unique.size > 2:
        if (labels is None and pred_decision.ndim > 1 and
                (np.size(y_true_unique) != pred_decision.shape[1])):
            raise ValueError("Please include all labels in y_true "
                             "or pass labels as third argument")
        if labels is None:
            labels = y_true_unique
        le = LabelEncoder()
        le.fit(labels)
        y_true = le.transform(y_true)
        mask = np.ones_like(pred_decision, dtype=bool)
        mask[np.arange(y_true.shape[0]), y_true] = False
        margin = pred_decision[~mask]
        margin -= np.max(pred_decision[mask].reshape(y_true.shape[0], -1),
                         axis=1)

    else:
        # Handles binary class case
        # this code assumes that positive and negative labels
        # are encoded as +1 and -1 respectively

# Path: sklearn/utils/validation.py
# def check_array(array, accept_sparse=None, dtype=None, order=None, copy=False,
#                 force_all_finite=True, ensure_2d=True, allow_nd=False):
#     """Input validation on an array, list, sparse matrix or similar.
# 
#     By default, the input is converted to an at least 2nd numpy array.
# 
#     Parameters
#     ----------
#     array : object
#         Input object to check / convert.
# 
#     accept_sparse : string, list of string or None (default=None)
#         String[s] representing allowed sparse matrix formats, such as 'csc',
#         'csr', etc.  None means that sparse matrix input will raise an error.
#         If the input is sparse but not in the allowed format, it will be
#         converted to the first listed format.
# 
#     dtype : string, type or None (default=none)
#         Data type of result. If None, the dtype of the input is preserved.
# 
#     order : 'F', 'C' or None (default=None)
#         Whether an array will be forced to be fortran or c-style.
# 
#     copy : boolean (default=False)
#         Whether a forced copy will be triggered. If copy=False, a copy might
#         be triggered by a conversion.
# 
#     force_all_finite : boolean (default=True)
#         Whether to raise an error on np.inf and np.nan in X.
# 
#     ensure_2d : boolean (default=True)
#         Whether to make X at least 2d.
# 
#     allow_nd : boolean (default=False)
#         Whether to allow X.ndim > 2.
# 
#     Returns
#     -------
#     X_converted : object
#         The converted and validated X.
#     """
#     if isinstance(accept_sparse, str):
#         accept_sparse = [accept_sparse]
# 
#     if sp.issparse(array):
#         array = _ensure_sparse_format(array, accept_sparse, dtype, order,
#                                       copy, force_all_finite)
#     else:
#         if ensure_2d:
#             array = np.atleast_2d(array)
#         array = np.array(array, dtype=dtype, order=order, copy=copy)
#         if not allow_nd and array.ndim >= 3:
#             raise ValueError("Found array with dim %d. Expected <= 2" %
#                              array.ndim)
#         if force_all_finite:
#             _assert_all_finite(array)
# 
#     return array
# 
# Path: sklearn/utils/validation.py
# def check_consistent_length(*arrays):
#     """Check that all arrays have consistent first dimensions.
# 
#     Checks whether all objects in arrays have the same shape or length.
# 
#     Parameters
#     ----------
#     *arrays : list or tuple of input objects.
#         Objects that will be checked for consistent length.
#     """
# 
#     uniques = np.unique([_num_samples(X) for X in arrays if X is not None])
#     if len(uniques) > 1:
#         raise ValueError("Found arrays with inconsistent numbers of samples: %s"
#                          % str(uniques))
# 
# Path: sklearn/utils/validation.py
# def column_or_1d(y, warn=False):
#     """ Ravel column or 1d numpy array, else raises an error
# 
#     Parameters
#     ----------
#     y : array-like
# 
#     warn : boolean, default False
#        To control display of warnings. 
# 
#     Returns
#     -------
#     y : array
# 
#     """
#     shape = np.shape(y)
#     if len(shape) == 1:
#         return np.ravel(y)
#     if len(shape) == 2 and shape[1] == 1:
#         if warn:
#             warnings.warn("A column-vector y was passed when a 1d array was"
#                           " expected. Please change the shape of y to "
#                           "(n_samples, ), for example using ravel().",
#                           DataConversionWarning, stacklevel=2)
#         return np.ravel(y)
# 
#     raise ValueError("bad input shape {0}".format(shape))
# 
# Path: sklearn/utils/validation.py
# def _num_samples(x):
#     """Return number of samples in array-like x."""
#     if not hasattr(x, '__len__') and not hasattr(x, 'shape'):
#         if hasattr(x, '__array__'):
#             x = np.asarray(x)
#         else:
#             raise TypeError("Expected sequence or array-like, got %r" % x)
#     return x.shape[0] if hasattr(x, 'shape') else len(x)


# Path: sklearn/metrics/classification.py
import warnings
import numpy as np
from scipy.sparse import coo_matrix
from scipy.sparse import csr_matrix
from scipy.spatial.distance import hamming as sp_hamming
from ..preprocessing import LabelBinarizer
from ..preprocessing import LabelEncoder
from ..utils import check_array
from ..utils import check_consistent_length
from ..preprocessing import MultiLabelBinarizer
from ..utils import column_or_1d
from ..utils.multiclass import unique_labels
from ..utils.multiclass import type_of_target
from ..utils.validation import _num_samples
from ..utils.sparsefuncs import count_nonzero
from ..utils.fixes import bincount
from .base import UndefinedMetricWarning

         penalty='l2', random_state=None, tol=0.0001, verbose=0)
    >>> pred_decision = est.decision_function([[-1], [2], [3]])
    >>> y_true = [0, 2, 3]
    >>> hinge_loss(y_true, pred_decision, labels)  #doctest: +ELLIPSIS
    0.56...
    """
    check_consistent_length(y_true, pred_decision, sample_weight)
    pred_decision = check_array(pred_decision, ensure_2d=False)
    y_true = column_or_1d(y_true)
    y_true_unique = np.unique(y_true)
    if y_true_unique.size > 2:
        if (labels is None and pred_decision.ndim > 1 and
                (np.size(y_true_unique) != pred_decision.shape[1])):
            raise ValueError("Please include all labels in y_true "
                             "or pass labels as third argument")
        if labels is None:
            labels = y_true_unique
        le = LabelEncoder()
        le.fit(labels)
        y_true = le.transform(y_true)
        mask = np.ones_like(pred_decision, dtype=bool)
        mask[np.arange(y_true.shape[0]), y_true] = False
        margin = pred_decision[~mask]
        margin -= np.max(pred_decision[mask].reshape(y_true.shape[0], -1),
                         axis=1)

    else:
        # Handles binary class case
        # this code assumes that positive and negative labels
        # are encoded as +1 and -1 respectively

        pred_decision = column_or_1d(pred_decision)