class_docstr: Base class for decision trees.
  
  Warning: This class should not be used directly.
  Use derived classes instead.
class_docstr_tok: ["Base","class","for","decision","trees",".","Warning",":","This","class","should","not","be","used","directly",".","Use","derived","classes","instead","."]
code: def fit(
      self,
      X,
      y,
      sample_weight=None,
      check_input=True,
      X_idx_sorted=None,
  ):
      random_state = check_random_state(self.random_state)
      if check_input:
          X = check_array(X, dtype=DTYPE, accept_sparse="csc")
          y = check_array(y, ensure_2d=False, dtype=None)
          if issparse(X):
              X.sort_indices()
  
              if (
                  X.indices.dtype != np.intc
                  or X.indptr.dtype != np.intc
              ):
                  raise ValueError(
                      "No support for np.int64 index based "
                      "sparse matrices"
                  )
  
      # Determine output settings
      n_samples, self.n_features_ = X.shape
      is_classification = isinstance(self, ClassifierMixin)
  
      y = np.atleast_1d(y)
      expanded_class_weight = None
  
      if y.ndim == 1:
          # reshape is necessary to preserve the data contiguity against vs
          # [:, np.newaxis] that does not.
          y = np.reshape(y, (-1, 1))
  
      self.n_outputs_ = y.shape[1]
  
      if is_classification:
          check_classification_targets(y)
          y = np.copy(y)
  
          self.classes_ = []
          self.n_classes_ = []
  
          if self.class_weight is not None:
              y_original = np.copy(y)
  
          y_encoded = np.zeros(y.shape, dtype=np.int)
          for k in range(self.n_outputs_):
              classes_k, y_encoded[:, k] = np.unique(
                  y[:, k], return_inverse=True
              )
              self.classes_.append(classes_k)
              self.n_classes_.append(classes_k.shape[0])
          y = y_encoded
  
          if self.class_weight is not None:
              expanded_class_weight = compute_sample_weight(
                  self.class_weight, y_original
              )
  
      else:
          self.classes_ = [None] * self.n_outputs_
          self.n_classes_ = [1] * self.n_outputs_
  
      self.n_classes_ = np.array(self.n_classes_, dtype=np.intp)
  
      if getattr(y, "dtype", None) != DOUBLE or not y.flags.contiguous:
          y = np.ascontiguousarray(y, dtype=DOUBLE)
  
      # Check parameters
      max_depth = (
          (2**31) - 1 if self.max_depth is None else self.max_depth
      )
      max_leaf_nodes = (
          -1 if self.max_leaf_nodes is None else self.max_leaf_nodes
      )
  
      if isinstance(
          self.min_samples_leaf, (numbers.Integral, np.integer)
      ):
          if not 1 <= self.min_samples_leaf:
              raise ValueError(
                  "min_samples_leaf must be at least 1 "
                  "or in (0, 0.5], got %s" % self.min_samples_leaf
              )
          min_samples_leaf = self.min_samples_leaf
      else:  # float
          if not 0.0 < self.min_samples_leaf <= 0.5:
              raise ValueError(
                  "min_samples_leaf must be at least 1 "
                  "or in (0, 0.5], got %s" % self.min_samples_leaf
              )
          min_samples_leaf = int(
              ceil(self.min_samples_leaf * n_samples)
          )
  
      if isinstance(
          self.min_samples_split, (numbers.Integral, np.integer)
      ):
          if not 2 <= self.min_samples_split:
              raise ValueError(
                  "min_samples_split must be at least 2 "
                  "or in (0, 1], got %s" % self.min_samples_split
              )
          min_samples_split = self.min_samples_split
      else:  # float
          if not 0.0 < self.min_samples_split <= 1.0:
              raise ValueError(
                  "min_samples_split must be at least 2 "
                  "or in (0, 1], got %s" % self.min_samples_split
              )
          min_samples_split = int(
              ceil(self.min_samples_split * n_samples)
          )
          min_samples_split = max(2, min_samples_split)
  
      min_samples_split = max(min_samples_split, 2 * min_samples_leaf)
  
      if isinstance(self.max_features, six.string_types):
          if self.max_features == "auto":
              if is_classification:
                  max_features = max(1, int(np.sqrt(self.n_features_)))
              else:
                  max_features = self.n_features_
          elif self.max_features == "sqrt":
              max_features = max(1, int(np.sqrt(self.n_features_)))
          elif self.max_features == "log2":
              max_features = max(1, int(np.log2(self.n_features_)))
          else:
              raise ValueError(
                  "Invalid value for max_features. Allowed string "
                  'values are "auto", "sqrt" or "log2".'
              )
      elif self.max_features is None:
          max_features = self.n_features_
      elif isinstance(
          self.max_features, (numbers.Integral, np.integer)
      ):
          max_features = self.max_features
      else:  # float
          if self.max_features > 0.0:
              max_features = max(
                  1, int(self.max_features * self.n_features_)
              )
          else:
              max_features = 0
  
      self.max_features_ = max_features
  
      if len(y) != n_samples:
          raise ValueError(
              "Number of labels=%d does not match "
              "number of samples=%d" % (len(y), n_samples)
          )
      if not 0 <= self.min_weight_fraction_leaf <= 0.5:
          raise ValueError("min_weight_fraction_leaf must in [0, 0.5]")
      if max_depth <= 0:
          raise ValueError("max_depth must be greater than zero. ")
      if not (0 < max_features <= self.n_features_):
          raise ValueError("max_features must be in (0, n_features]")
      if not isinstance(max_leaf_nodes, (numbers.Integral, np.integer)):
          raise ValueError(
              "max_leaf_nodes must be integral number but was "
              "%r" % max_leaf_nodes
          )
      if -1 < max_leaf_nodes < 2:
          raise ValueError(
              (
                  "max_leaf_nodes {0} must be either smaller than "
                  "0 or larger than 1"
              ).format(max_leaf_nodes)
          )
  
      if sample_weight is not None:
          if (
              getattr(sample_weight, "dtype", None) != DOUBLE
              or not sample_weight.flags.contiguous
          ):
              sample_weight = np.ascontiguousarray(
                  sample_weight, dtype=DOUBLE
              )
          if len(sample_weight.shape) > 1:
              raise ValueError(
                  "Sample weights array has more "
                  "than one dimension: %d" % len(sample_weight.shape)
              )
          if len(sample_weight) != n_samples:
              raise ValueError(
                  "Number of weights=%d does not match "
                  "number of samples=%d"
                  % (len(sample_weight), n_samples)
              )
  
      if expanded_class_weight is not None:
          if sample_weight is not None:
              sample_weight = sample_weight * expanded_class_weight
          else:
              sample_weight = expanded_class_weight
  
      # Set min_weight_leaf from min_weight_fraction_leaf
      if sample_weight is None:
          min_weight_leaf = self.min_weight_fraction_leaf * n_samples
      else:
          min_weight_leaf = self.min_weight_fraction_leaf * np.sum(
              sample_weight
          )
  
      if self.min_impurity_split < 0.0:
          raise ValueError(
              "min_impurity_split must be greater than " "or equal to 0"
          )
  
      presort = self.presort
      # Allow presort to be 'auto', which means True if the dataset is dense,
      # otherwise it will be False.
      if self.presort == "auto" and issparse(X):
          presort = False
      elif self.presort == "auto":
          presort = True
  
      if presort is True and issparse(X):
          raise ValueError(
              "Presorting is not supported for sparse " "matrices."
          )
  
      # If multiple trees are built on the same dataset, we only want to
      # presort once. Splitters now can accept presorted indices if desired,
      # but do not handle any presorting themselves. Ensemble algorithms
      # which desire presorting must do presorting themselves and pass that
      # matrix into each tree.
      if X_idx_sorted is None and presort:
          X_idx_sorted = np.asfortranarray(
              np.argsort(X, axis=0), dtype=np.int32
          )
  
      if presort and X_idx_sorted.shape != X.shape:
          raise ValueError(
              "The shape of X (X.shape = {}) doesn't match "
              "the shape of X_idx_sorted (X_idx_sorted"
              ".shape = {})".format(X.shape, X_idx_sorted.shape)
          )
  
      # Build tree
      criterion = self.criterion
      if not isinstance(criterion, Criterion):
          if is_classification:
              criterion = CRITERIA_CLF[self.criterion](
                  self.n_outputs_, self.n_classes_
              )
          else:
              criterion = CRITERIA_REG[self.criterion](
                  self.n_outputs_, n_samples
              )
  
      SPLITTERS = SPARSE_SPLITTERS if issparse(X) else DENSE_SPLITTERS
  
      splitter = self.splitter
      if not isinstance(self.splitter, Splitter):
          splitter = SPLITTERS[self.splitter](
              criterion,
              self.max_features_,
              min_samples_leaf,
              min_weight_leaf,
              random_state,
              self.presort,
          )
  
      self.tree_ = Tree(
          self.n_features_, self.n_classes_, self.n_outputs_
      )
  
      # Use BestFirst if max_leaf_nodes given; use DepthFirst otherwise
      if max_leaf_nodes < 0:
          builder = DepthFirstTreeBuilder(
              splitter,
              min_samples_split,
              min_samples_leaf,
              min_weight_leaf,
              max_depth,
              self.min_impurity_split,
          )
      else:
          builder = BestFirstTreeBuilder(
              splitter,
              min_samples_split,
              min_samples_leaf,
              min_weight_leaf,
              max_depth,
              max_leaf_nodes,
              self.min_impurity_split,
          )
  
      builder.build(self.tree_, X, y, sample_weight, X_idx_sorted)
  
      if self.n_outputs_ == 1:
          self.n_classes_ = self.n_classes_[0]
          self.classes_ = self.classes_[0]
  
      return self
  
imports: from __future__ import division
  import numbers
  from abc import ABCMeta
  from abc import abstractmethod
  from math import ceil
  import numpy
  from scipy.sparse import issparse
  from ..base import BaseEstimator
  from ..base import ClassifierMixin
  from ..base import RegressorMixin
  from ..externals import six
  from ..feature_selection.from_model import _LearntSelectorMixin
  from ..utils import check_array
  from ..utils import check_random_state
  from ..utils import compute_sample_weight
  from ..utils.multiclass import check_classification_targets
  from ..exceptions import NotFittedError
  from ._criterion import Criterion
  from ._splitter import Splitter
  from ._tree import DepthFirstTreeBuilder
  from ._tree import BestFirstTreeBuilder
  from ._tree import Tree
  from .None import _tree, _splitter, _criterion
label_desc: Use image node_id 2 for calling the BaseDecisionTree obj's underlying member method code with example usage: obj.fit(X, y, sample_weight, check_input, X_idx_sorted) and returns: self