class_docstr: Wrap ``VotingClassifier`` and ``VotingRegressor`` from scikit-learn.
  
  Note that this class does not inherit from the ``Learner`` class but rather
  uses different ``Learner`` instances underlyingly.
  
  Parameters
  ----------
  learner_names : List[str]
      List of the learner names that will participate in the voting process.
  voting : Optional[str], default="hard"
      One of "hard" or "soft". If "hard", the predicted class labels
      are used for majority rule voting. If "soft", the predicted class
      label is based on the argmax of the sums of the predicted
      probabilities from each of the underlying learnrs. This parameter
      is only relevant for classification.
  custom_learner_path : Optional[:class:`skll.types.PathOrStr`], default=None
      Path to a Python file containing the definitions of any custom
      learners. Any and all custom learners in ``estimator_names`` must
      be defined in this file. If the custom learner does not inherit
      from an already existing scikit-learn estimator, it must explicitly
      define an `_estimator_type` attribute indicating whether it's a
      "classifier" or a "regressor".
  feature_scaling : str, default="none"
      How to scale the features, if at all for each estimator. Options are
      -  "with_std": scale features using the standard deviation
      -  "with_mean": center features using the mean
      -  "both": do both scaling as well as centering
      -  "none": do neither scaling nor centering
  pos_label : Optional[:class:`skll.types.LabelType`], default=None
      A string denoting the label of the class to be
      treated as the positive class in a binary classification
      setting, for each estimator. If ``None``, the class represented
      by the label that appears second when sorted is chosen as the
      positive class. For example, if the two labels in data are "A"
      and "B" and ``pos_label`` is not specified, "B" will
      be chosen as the positive class.
  min_feature_count : int, default=1
      The minimum number of examples a feature must have a nonzero
      value in to be included, for each estimator.
  model_kwargs_list : Optional[List[Dict[str, Any]]], default=None
      A list of dictionaries of keyword arguments to pass to the
      initializer for each of the estimators. There's a one-to-one
      correspondence between the order of this list and the order
      of the ``learner_names`` list.
  sampler_list : Optional[List[str]], default=None
      The samplers to use for kernel approximation, if desired, for each
      estimator. Valid values are:
      -  "AdditiveChi2Sampler"
      -  "Nystroem"
      -  "RBFSampler"
      -  "SkewedChi2Sampler"
      There's a one-to-one correspondence between the order of this list
      and the order of the ``learner_names`` list.
  sampler_kwargs_list : Optional[List[Dict[str, Any]]], default=None
      A list of dictionaries of keyword arguments to pass to the
      initializer for the specified sampler, one per estimator.
      There's a one-to-one correspondence between the order of this
      list and the order of the ``learner_names`` list.
  logger : Optional[logging.Logger], default=None
      A logging object. If ``None`` is passed, get logger from ``__name__``.
docstr: Generate learning curves for the meta-estimator.
  
  Generate learning curves for the voting meta-estimator on the training
  examples via cross-validation. Adapted from the scikit-learn code for
  learning curve generation (cf.``sklearn.model_selection.learning_curve``).
  
  Parameters
  ----------
  examples : :class:`skll.data.featureset.FeatureSet`
      The ``FeatureSet`` instance to generate the learning curve on.
  metric : str
      The name of the metric function to use
      when computing the train and test scores
      for the learning curve.
  cv_folds : Union[int, :class:`skll.types.FoldMapping`], default=10
      The number of folds to use for cross-validation, or
      a mapping from example IDs to folds.
  train_sizes : :class:`skll.types.LearningCurveSizes`, default= :func:`numpy.linspace` with start=0.1, stop=1.0, num=5
      Relative or absolute numbers of training examples
      that will be used to generate the learning curve.
      If the type is float, it is regarded as a fraction
      of the maximum size of the training set (that is
      determined by the selected validation method),
      i.e. it has to be within (0, 1]. Otherwise it
      is interpreted as absolute sizes of the training
      sets. Note that for classification the number of
      samples usually have to be big enough to contain
      at least one sample from each class.
  override_minimum : bool, default=False
      Learning curves can be unreliable for very small sizes
      esp. for > 2 labels. If this option is set to ``True``, the
      learning curve would be generated even if the number
      of example is less 500 along with a warning. If ``False``,
      the curve is not generated and an exception is raised instead.
  
  Returns
  -------
  train_scores : List[float]
      The scores for the training set.
  test_scores : List[float]
      The scores on the test set.
  fit_times : List[float]
      The average times taken to fit each model.
  num_examples : List[int]
      The numbers of training examples used to generate the curve.
  
  Raises
  ------
  ValueError
      If the number of examples is less than 500.
docstr_tok: ["Generate","learning","curves","for","the","meta-estimator",".","Generate","learning","curves","for","the","voting","meta-estimator","on","the","training","examples","via","cross-validation",".","Adapted","from","the","scikit-learn","code","for","learning","curve","generation","(","cf.","``","sklearn.model_selection.learning_curve","``",")",".","Parameters","--","--","--","--","--","examples",":",":","class",":","`","skll.data.featureset.FeatureSet","`","The","``","FeatureSet","``","instance","to","generate","the","learning","curve","on",".","metric",":","str","The","name","of","the","metric","function","to","use","when","computing","the","train","and","test","scores","for","the","learning","curve",".","cv_folds",":","Union","[","int",",",":","class",":","`","skll.types.FoldMapping","`","]",",","default=10","The","number","of","folds","to","use","for","cross-validation",",","or","a","mapping","from","example","IDs","to","folds",".","train_sizes",":",":","class",":","`","skll.types.LearningCurveSizes","`",",","default=",":","func",":","`","numpy.linspace","`","with","start=0.1",",","stop=1.0",",","num=5","Relative","or","absolute","numbers","of","training","examples","that","will","be","used","to","generate","the","learning","curve",".","If","the","type","is","float",",","it","is","regarded","as","a","fraction","of","the","maximum","size","of","the","training","set","(","that","is","determined","by","the","selected","validation","method",")",",","i.e",".","it","has","to","be","within","(","0",",","1","]",".","Otherwise","it","is","interpreted","as","absolute","sizes","of","the","training","sets",".","Note","that","for","classification","the","number","of","samples","usually","have","to","be","big","enough","to","contain","at","least","one","sample","from","each","class",".","override_minimum",":","bool",",","default=False","Learning","curves","can","be","unreliable","for","very","small","sizes","esp",".","for",">","2","labels",".","If","this","option","is","set","to","``","True","``",",","the","learning","curve","would","be","generated","even","if","the","number","of","example","is","less","500","along","with","a","warning",".","If","``","False","``",",","the","curve","is","not","generated","and","an","exception","is","raised","instead",".","Returns","--","--","--","-","train_scores",":","List","[","float","]","The","scores","for","the","training","set",".","test_scores",":","List","[","float","]","The","scores","on","the","test","set",".","fit_times",":","List","[","float","]","The","average","times","taken","to","fit","each","model",".","num_examples",":","List","[","int","]","The","numbers","of","training","examples","used","to","generate","the","curve",".","Raises","--","--","--","ValueError","If","the","number","of","examples","is","less","than","500","."]
code: def learning_curve(
      self,
      examples: FeatureSet,
      metric: str,
      cv_folds: Union[int, FoldMapping] = 10,
      train_sizes: LearningCurveSizes = np.linspace(0.1, 1.0, 5),
      override_minimum: bool = False,
  ) -> Tuple[List[float], List[float], List[float], List[int]]:
      """
      Generate learning curves for the meta-estimator.
  
      Generate learning curves for the voting meta-estimator on the training
      examples via cross-validation. Adapted from the scikit-learn code for
      learning curve generation (cf.``sklearn.model_selection.learning_curve``).
  
      Parameters
      ----------
      examples : :class:`skll.data.featureset.FeatureSet`
          The ``FeatureSet`` instance to generate the learning curve on.
      metric : str
          The name of the metric function to use
          when computing the train and test scores
          for the learning curve.
      cv_folds : Union[int, :class:`skll.types.FoldMapping`], default=10
          The number of folds to use for cross-validation, or
          a mapping from example IDs to folds.
      train_sizes : :class:`skll.types.LearningCurveSizes`, default= :func:`numpy.linspace` with start=0.1, stop=1.0, num=5
          Relative or absolute numbers of training examples
          that will be used to generate the learning curve.
          If the type is float, it is regarded as a fraction
          of the maximum size of the training set (that is
          determined by the selected validation method),
          i.e. it has to be within (0, 1]. Otherwise it
          is interpreted as absolute sizes of the training
          sets. Note that for classification the number of
          samples usually have to be big enough to contain
          at least one sample from each class.
      override_minimum : bool, default=False
          Learning curves can be unreliable for very small sizes
          esp. for > 2 labels. If this option is set to ``True``, the
          learning curve would be generated even if the number
          of example is less 500 along with a warning. If ``False``,
          the curve is not generated and an exception is raised instead.
  
      Returns
      -------
      train_scores : List[float]
          The scores for the training set.
      test_scores : List[float]
          The scores on the test set.
      fit_times : List[float]
          The average times taken to fit each model.
      num_examples : List[int]
          The numbers of training examples used to generate the curve.
  
      Raises
      ------
      ValueError
          If the number of examples is less than 500.
      """
      # check that the number of training examples is more than the minimum
      # needed for generating a reliable learning curve
      if len(examples) < 500:
          if not override_minimum:
              raise ValueError(
                  f"Number of training examples provided ({len(examples)}) "
                  "is less than the minimum needed (500) for the "
                  "learning curve to be reliable."
              )
          else:
              self.logger.warning(
                  "Learning curves can be unreliable for examples fewer than "
                  f"500. You provided {len(examples)}."
              )
  
      # raise a warning if we are using a probabilistic classifier
      # since that means we cannot use the predictions directly
      if self.voting == "soft":
          self.logger.warning(
              "For soft-voting classifiers, the most likely "
              "class will be computed via an argmax before "
              "computing the curve."
          )
  
      # Call some setup code which will properly initialize the underlying
      # learners before they are eventually trained
      self._setup_underlying_learners(examples)
  
      # set up the CV split iterator over the train/test featuresets
      # which also returns the maximum number of training examples
      (
          featureset_iter,
          n_max_training_samples,
      ) = setup_cv_split_iterator(cv_folds, examples)
  
      # Get the `_translate_train_sizes()` function from scikit-learn
      # since we need it to get the right list of sizes after cross-validation
      _module = import_module("sklearn.model_selection._validation")
      _translate_train_sizes = getattr(
          _module, "_translate_train_sizes"
      )
      train_sizes_abs = _translate_train_sizes(
          train_sizes, n_max_training_samples
      )
      n_unique_ticks = train_sizes_abs.shape[0]
  
      # limit the number of parallel jobs for this to be no higher than
      # MAX_CONCURRENT_PROCESSES or the number of cores, whichever is lower
      n_jobs = min(cpu_count(), MAX_CONCURRENT_PROCESSES)
  
      # Run jobs in parallel that train the model on each subset
      # of the training data and compute train and test scores
      parallel = joblib.Parallel(n_jobs=n_jobs, pre_dispatch=n_jobs)
      out = parallel(
          joblib.delayed(train_and_score)(
              self, train_fs[:n_train_samples], test_fs, metric
          )
          for train_fs, test_fs in featureset_iter
          for n_train_samples in train_sizes_abs
      )
  
      # Reshape the outputs
      out = np.array(out)
      n_cv_folds = out.shape[0] // n_unique_ticks
      out = out.reshape(n_cv_folds, n_unique_ticks, 3)
      out = np.asarray(out).transpose((2, 1, 0))
  
      return (
          list(out[0]),
          list(out[1]),
          list(out[2]),
          list(train_sizes_abs),
      )
  
imports: import copy
  import logging
  from importlib import import_module
  from itertools import zip_longest
  from multiprocessing import cpu_count
  from typing import Any, Dict, List, Optional, Tuple, Union
  import joblib
  import numpy
  from sklearn.ensemble import VotingClassifier, VotingRegressor
  from sklearn.utils import shuffle
  from sklearn.utils.multiclass import type_of_target
  from skll.data import FeatureSet
  from skll.data.dict_vectorizer import DictVectorizer
  from skll.learner import Learner
  from skll.types import EvaluateTaskResults, FoldMapping, LabelType, LearningCurveSizes, PathOrStr, VotingCrossValidateTaskResults
  from skll.utils.constants import MAX_CONCURRENT_PROCESSES
  from .utils import _load_learner_from_disk, _save_learner_to_disk, add_unseen_labels, compute_evaluation_metrics, get_acceptable_classification_metrics, get_acceptable_regression_metrics, get_predictions, setup_cv_fold_iterator, setup_cv_split_iterator, train_and_score, write_predictions
label_desc: Use image node_id 13 for calling the VotingLearner obj's underlying member method code with example usage: obj.learning_curve(examples, metric, cv_folds, train_sizes, override_minimum) and returns: list,  list,  list,  list