class_docstr: Splitter of data that provides generator of test-train splits.
  Can provide hold-out validation and k-fold validation.
  
  :param cv_folds: Number of folds on data for cross-validation.
  If provided, then cross validation is used. Otherwise, hold-out validation is used.
  :param validation_blocks: Validation blocks count.
  Applied only for time series data.
  If not provided, then value will be calculated.
  :param split_ratio: Ratio of data for splitting.
  Applied only in case of hold-out split.
  If not provided, then default split ratios will be used.
  :param shuffle: Is shuffling required for data.
  :param stratify: If True then stratification is used for samples
  :param random_seed: Random seed for shuffle.
  :param log: Log for logging.
class_docstr_tok: ["Splitter","of","data","that","provides","generator","of","test-train","splits",".","Can","provide","hold-out","validation","and","k-fold","validation",".",":","param","cv_folds",":","Number","of","folds","on","data","for","cross-validation",".","If","provided",",","then","cross","validation","is","used",".","Otherwise",",","hold-out","validation","is","used",".",":","param","validation_blocks",":","Validation","blocks","count",".","Applied","only","for","time","series","data",".","If","not","provided",",","then","value","will","be","calculated",".",":","param","split_ratio",":","Ratio","of","data","for","splitting",".","Applied","only","in","case","of","hold-out","split",".","If","not","provided",",","then","default","split","ratios","will","be","used",".",":","param","shuffle",":","Is","shuffling","required","for","data",".",":","param","stratify",":","If","True","then","stratification","is","used","for","samples",":","param","random_seed",":","Random","seed","for","shuffle",".",":","param","log",":","Log","for","logging","."]
code: def build(self, data: Union[InputData, MultiModalData]) -> DataSource:
      # define split_ratio
      self.split_ratio = (
          self.split_ratio
          or default_data_split_ratio_by_task[data.task.task_type]
      )
  
      # Check cv_folds
      if self.cv_folds is not None:
          try:
              self.cv_folds = int(self.cv_folds)
          except ValueError:
              raise ValueError(
                  f"cv_folds is not integer: {self.cv_folds}"
              )
          if self.cv_folds < 2:
              self.cv_folds = None
          if self.cv_folds > data.target.shape[0] - 1:
              raise ValueError(
                  (
                      f"cv_folds ({self.cv_folds}) is greater than"
                      f" the maximum allowed count {data.target.shape[0] - 1}"
                  )
              )
  
      # Calculate the number of validation blocks for timeseries forecasting
      if (
          data.task.task_type is TaskTypesEnum.ts_forecasting
          and self.validation_blocks is None
      ):
          self._propose_cv_folds_and_validation_blocks(data)
  
      # Check split_ratio
      if self.cv_folds is None and not (0 < self.split_ratio < 1):
          raise ValueError(
              f"split_ratio is {self.split_ratio} but should be between 0 and 1"
          )
  
      if self.stratify:
          # check that stratification can be done
          # for cross validation split ratio is defined as validation_size / all_data_size
          split_ratio = (
              self.split_ratio
              if self.cv_folds is None
              else (1 - 1 / (self.cv_folds + 1))
          )
          self.stratify = _are_stratification_allowed(data, split_ratio)
          if not self.stratify:
              self.log.info(
                  "Stratificated splitting of data is disabled."
              )
  
      # Stratification can not be done without shuffle
      self.shuffle |= self.stratify
  
      # Random seed depends on shuffle
      self.random_seed = (
          (self.random_seed or 42) if self.shuffle else None
      )
  
      # Split data
      if self.cv_folds is not None:
          self.log.info("K-folds cross validation is applied.")
          data_producer = partial(
              cv_generator,
              data=data,
              shuffle=self.shuffle,
              cv_folds=self.cv_folds,
              random_seed=self.random_seed,
              stratify=self.stratify,
              validation_blocks=self.validation_blocks,
          )
      else:
          self.log.info("Hold out validation is applied.")
          data_producer = self._build_holdout_producer(data)
  
      return data_producer
  
file_path: FEDOT/fedot/core/optimisers/objective/data_source_splitter.py
imports: from functools import partial
  from typing import Optional, Union
  from golem.core.log import default_log
  from fedot.core.constants import default_data_split_ratio_by_task
  from fedot.core.data.data import InputData
  from fedot.core.data.data_split import train_test_data_setup, _are_stratification_allowed
  from fedot.core.data.multi_modal import MultiModalData
  from fedot.core.optimisers.objective.data_objective_eval import DataSource
  from fedot.core.repository.tasks import TaskTypesEnum
  from fedot.remote.remote_evaluator import RemoteEvaluator, init_data_for_remote_execution
  from fedot.core.data.cv_folds import cv_generator
label_desc: Use image node_id 2 for calling the DataSourceSplitter obj's underlying member method code with example usage: obj.build(data) and returns: data_producer