code: def stratified_split(
      interactions: BaseInteractions,
      val_p: float = 0.0,
      test_p: float = 0.2,
      processes: int = -1,
      seed: Optional[int] = None,
      force_split: bool = False,
  ) -> Tuple[BaseInteractions, ...]:
      """
      Split an ``Interactions`` instance into train, validate, and test datasets in a stratified
      manner such that each user appears at least once in each of the datasets.
  
      This split guarantees that every user will be represented in the training, validation, and
      testing datasets given they appear in ``interactions`` at least three times. If ``val_p ==
      0``, they will appear in the training and testing datasets given they appear at least two times.
      If a user appears fewer than this number of times, a ``ValueError`` will
      be raised. To filter users with fewer than ``n`` points out, use
      ``collie.utils.remove_users_with_fewer_than_n_interactions``.
  
      This is computationally more complex than ``random_split``, but produces a more representative
      data split. Note that when ``val_p > 0``, the algorithm will perform the data split twice,
      once to create the test set and another to create the validation set, essentially doubling the
      computational time.
  
      Note that this function is not supported for ``HDF5Interactions`` objects, since this data split
      implementation requires all data to fit in memory. A data split for large datasets should be
      done using a big data processing technology, like Spark.
  
      Parameters
      ----------
      interactions: collie.interactions.BaseInteractions
          ``Interactions`` instance containing the data to split
      val_p: float
          Proportion of data used for validation
      test_p: float
          Proportion of data used for testing
      processes: int
          Number of CPUs to use for parallelization. If ``processes == 0``, this will be run
          sequentially in a single list comprehension, else this function uses ``joblib.delayed`` and
          ``joblib.Parallel`` for parallelization. A value of ``-1`` means that all available cores
          will be used
      seed: int
          Random seed for splits
      force_split: bool
          Ignore error raised when a user in the dataset has only a single interaction. Normally,
          a ``ValueError`` is raised when this occurs. When ``force_split=True``, however,
          users with a single interaction will be placed in the training set and an error will NOT be
          raised
  
      Returns
      -------
      train_interactions: collie.interactions.BaseInteractions
          Training data of size proportional to ``1 - val_p - test_p``
      validate_interactions: collie.interactions.BaseInteractions
          Validation data of size proportional to ``val_p``, returned only if ``val_p > 0``
      test_interactions: collie.interactions.BaseInteractions
          Testing data of size proportional to ``test_p``
  
      Examples
      --------
      .. code-block:: python
  
          >>> interactions = Interactions(...)
          >>> len(interactions)
          100000
          >>> train, test = stratified_split(interactions)
          >>> len(train), len(test)
          (80000, 20000)
  
      """
      assert not isinstance(
          interactions, HDF5Interactions
      ), "``HDF5Interactions`` data types not supported in cross validation splits!"
  
      _validate_val_p_and_test_p(val_p=val_p, test_p=test_p)
  
      if seed is None:
          seed = get_random_seed()
  
      train, test = _stratified_split(
          interactions=interactions,
          test_p=test_p,
          processes=processes,
          seed=seed,
          force_split=force_split,
      )
  
      if val_p > 0:
          train, validate = _stratified_split(
              interactions=train,
              test_p=val_p / (1 - test_p),
              processes=processes,
              seed=seed,
              force_split=force_split,
          )
  
          return train, validate, test
      else:
          return train, test
  
file_path: collie/collie/cross_validation.py
imports: from collections import defaultdict
  import functools
  import operator
  from typing import Any, Iterable, Optional, Tuple, Union
  from joblib import delayed, Parallel
  import numpy
  from scipy.sparse import coo_matrix
  from sklearn.model_selection import train_test_split
  from collie.interactions import BaseInteractions, ExplicitInteractions, HDF5Interactions, Interactions
  from collie.utils import get_random_seed
label_desc: Use image node_id 3 for calling a global function with example usage: stratified_split(interactions, val_p, test_p, processes, seed, force_split) and returns: train,  validate,  test, train,  test