class_docstr: Holds loaded intent and entity training data.
class_docstr_tok: ["Holds","loaded","intent","and","entity","training","data","."]
docstr: Split the training data into a train and test set.
  
  Args:
      train_frac: percentage of examples to add to the training set.
      random_seed: random seed used to shuffle examples.
  
  Returns:
      Test and training examples.
docstr_tok: ["Split","the","training","data","into","a","train","and","test","set",".","Args",":","train_frac",":","percentage","of","examples","to","add","to","the","training","set",".","random_seed",":","random","seed","used","to","shuffle","examples",".","Returns",":","Test","and","training","examples","."]
code: def split_nlu_examples(
      self, train_frac: float, random_seed: Optional[int] = None
  ) -> Tuple[list, list]:
      """Split the training data into a train and test set.
  
      Args:
          train_frac: percentage of examples to add to the training set.
          random_seed: random seed used to shuffle examples.
  
      Returns:
          Test and training examples.
      """
      self.validate()
  
      # Stratified split: both test and train should have (approximately) the
      # same class distribution as the original data. We also require that
      # each class is represented in both splits.
  
      # First check that there is enough data to split at the requested
      # rate: we must be able to include one example per class in both
      # test and train, so num_classes is the minimum size of either.
      smaller_split_frac = (
          train_frac if train_frac < 0.5 else (1.0 - train_frac)
      )
      num_classes = (
          len(self.number_of_examples_per_intent.items())
          - len(self.retrieval_intents)
          + len(self.number_of_examples_per_response)
      )
      num_examples = sum(self.number_of_examples_per_intent.values())
  
      if int(smaller_split_frac * num_examples) + 1 < num_classes:
          rasa.shared.utils.io.raise_warning(
              f"There aren't enough intent examples in your data to include "
              f"an example of each class in both test and train splits and "
              f"also reserve {train_frac} of the data for training. "
              f"The output training fraction will differ."
          )
  
      # Now simulate traversing the sorted examples, sampling at a rate
      # of train_frac, so that after traversing k examples (for all k), we
      # have sampled int(k * train_frac) of them for training.
      # Corner case that makes this approximate: we require at least one sample
      # in test, and at least one in train, so proportions will be less exact
      # when classes have few examples, e.g. when a class has only 2 examples
      # but the user requests an 80% / 20% split.
  
      train, test = [], []
  
      # helper to simulate the traversal of all examples in a single class
      def _split_class(
          _examples: List[Message],
          _running_count: int,
          _running_train_count: int,
      ) -> Tuple[int, int]:
          if random_seed is not None:
              random.Random(random_seed).shuffle(_examples)
          else:
              random.shuffle(_examples)
  
          # first determine how many samples we should have in training after
          # traversing the examples in this class, if sampling train_frac of
          # them. Then adjust so there's at least one example in test and train.
          # Adjustment can accumulate until we encounter a frequent class.
          exact_train_count = (
              int((_running_count + len(_examples)) * train_frac)
              - _running_train_count
          )
          approx_train_count = min(
              len(_examples) - 1, max(1, exact_train_count)
          )
  
          train.extend(_examples[:approx_train_count])
          test.extend(_examples[approx_train_count:])
  
          return (
              _running_count + len(_examples),
              _running_train_count + approx_train_count,
          )
  
      training_examples = set(self.training_examples)
      running_count = 0
      running_train_count = 0
  
      # Sort by class frequency so we first handle the tail of the distribution,
      # where the percentages in the split are most approximate. Items from
      # more frequent classes can then be over/ undersampled as needed to
      # meet the requested train_frac. First for responses:
      for response, _ in sorted(
          self.number_of_examples_per_response.items(),
          key=operator.itemgetter(1),
      ):
          examples = [
              e
              for e in training_examples
              if e.get(INTENT_RESPONSE_KEY)
              and e.get(INTENT_RESPONSE_KEY) == response
          ]
          running_count, running_train_count = _split_class(
              examples, running_count, running_train_count
          )
          training_examples = training_examples - set(examples)
  
      # Again for intents:
      for intent, _ in sorted(
          self.number_of_examples_per_intent.items(),
          key=operator.itemgetter(1),
      ):
          examples = [
              e
              for e in training_examples
              if INTENT in e.data and e.data[INTENT] == intent
          ]
          if len(examples) > 0:  # will be 0 for retrieval intents
              running_count, running_train_count = _split_class(
                  examples, running_count, running_train_count
              )
              training_examples = training_examples - set(examples)
  
      return test, train
  
imports: import logging
  import os
  from pathlib import Path
  import random
  from collections import Counter, OrderedDict
  import copy
  from os.path import relpath
  from typing import Any, Dict, List, Optional, Set, Text, Tuple, Callable
  import operator
  import rasa.shared.data
  from rasa.shared.utils.common import lazy_property
  import rasa.shared.utils.io
  from rasa.shared.nlu.constants import RESPONSE, INTENT_RESPONSE_KEY, ENTITY_ATTRIBUTE_TYPE, ENTITY_ATTRIBUTE_GROUP, ENTITY_ATTRIBUTE_ROLE, NO_ENTITY_TAG, INTENT, ENTITIES, TEXT, ACTION_NAME
  from rasa.shared.nlu.training_data.message import Message
  from rasa.shared.nlu.training_data import util
label_desc: Use image node_id 36 for calling the TrainingData obj's underlying member method code with example usage: obj.split_nlu_examples(train_frac, random_seed) and returns: test,  train, unknown,  unknown