code: def split_dataset(
      df: DataFrame,
      global_preprocessing_parameters: PreprocessingConfigDict,
      backend: Backend,
      random_seed: float = default_random_seed,
  ) -> Tuple[DataFrame, DataFrame, DataFrame]:
      splitter = get_splitter(
          **global_preprocessing_parameters.get(SPLIT, {})
      )
      datasets: Tuple[DataFrame, DataFrame, DataFrame] = splitter.split(
          df, backend, random_seed
      )
      if len(datasets[0].columns) == 0:
          raise ValueError(
              "Encountered an empty training set while splitting data. Please double check the preprocessing split "
              "configuration."
          )
  
      # Remove partitions that are empty after splitting
      datasets = [
          None
          if dataset is None
          else backend.df_engine.remove_empty_partitions(dataset)
          for dataset in datasets
      ]
      return datasets
  
imports: import logging
  from abc import ABC, abstractmethod
  from typing import List, Optional, Tuple, TYPE_CHECKING
  from zlib import crc32
  import numpy
  from sklearn.model_selection import train_test_split
  from ludwig.api_annotations import DeveloperAPI
  from ludwig.backend.base import Backend
  from ludwig.constants import BINARY, CATEGORY, DATE, MIN_DATASET_SPLIT_ROWS, SPLIT
  from ludwig.error import ConfigValidationError
  from ludwig.schema.split import DateTimeSplitConfig, FixedSplitConfig, HashSplitConfig, RandomSplitConfig, StratifySplitConfig
  from ludwig.types import ModelConfigDict, PreprocessingConfigDict
  from ludwig.utils.data_utils import hash_dict, split_dataset_ttv
  from ludwig.utils.defaults import default_random_seed
  from ludwig.utils.registry import Registry
  from ludwig.utils.types import DataFrame
label_desc: Use image node_id 5 for calling a global function with example usage: split_dataset(df, global_preprocessing_parameters, backend, random_seed) and returns: datasets