code: def stratify_split_dataframe(
      df: DataFrame,
      column: str,
      probabilities: List[float],
      backend: Backend,
      random_seed: float,
  ) -> Tuple[DataFrame, DataFrame, DataFrame]:
      """Splits a dataframe into train, validation, and test sets based on the values of a column.
  
      The column must be categorical (including binary). The split is stratified, meaning that the proportion of each
      category in each split is the same as in the original dataset.
      """
  
      frac_train, frac_val, frac_test = probabilities
  
      def _safe_stratify(df, column, test_size):
          # Get the examples with cardinality of 1
          df_cadinalities = df.groupby(column)[column].size()
          low_cardinality_elems = df_cadinalities.loc[lambda x: x == 1]
          df_low_card = df[df[column].isin(low_cardinality_elems.index)]
          df = df[~df[column].isin(low_cardinality_elems.index)]
          y = df[[column]]
  
          df_train, df_temp, _, _ = train_test_split(
              df,
              y,
              stratify=y,
              test_size=test_size,
              random_state=random_seed,
          )
  
          # concat the examples with cardinality of 1 to the training DF.
          if len(df_low_card.index) > 0:
              df_train = backend.df_engine.concat(
                  [df_train, df_low_card]
              )
  
          return df_train, df_temp
  
      df_train, df_temp = _safe_stratify(df, column, 1.0 - frac_train)
  
      relative_frac_test = frac_test / (frac_val + frac_test)
      df_val, df_test = _safe_stratify(
          df_temp, column, relative_frac_test
      )
  
      return df_train, df_val, df_test
  
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 3 for calling a global function with example usage: stratify_split_dataframe(df, column, probabilities, backend, random_seed) and returns: df_train,  df_val,  df_test, df_train,  df_temp