class_docstr: Data object used for all RasaModels.
  
  It contains all features needed to train the models.
  'data' is a mapping of attribute name, e.g. TEXT, INTENT, etc., and feature name,
  e.g. SENTENCE, SEQUENCE, etc., to a list of feature arrays representing the actual
  features.
  'label_key' and 'label_sub_key' point to the labels inside 'data'. For
  example, if your intent labels are stored under INTENT -> IDS, 'label_key' would
  be "INTENT" and 'label_sub_key' would be "IDS".
class_docstr_tok: ["Data","object","used","for","all","RasaModels",".","It","contains","all","features","needed","to","train","the","models",".","'data","'","is","a","mapping","of","attribute","name",",","e.g",".","TEXT",",","INTENT",",","etc.",",","and","feature","name",",","e.g",".","SENTENCE",",","SEQUENCE",",","etc.",",","to","a","list","of","feature","arrays","representing","the","actual","features",".","'label_key","'","and","'label_sub_key","'","point","to","the","labels","inside","'data","'",".","For","example",",","if","your","intent","labels","are","stored","under","INTENT","-",">","IDS",",","'label_key","'","would","be","``","INTENT","''","and","'label_sub_key","'","would","be","``","IDS","''","."]
docstr: Mix model data to account for class imbalance.
  
  This batching strategy puts rare classes approximately in every other batch,
  by repeating them. Mimics stratified batching, but also takes into account
  that more populated classes should appear more often.
  
  Args:
      data: The data.
      batch_size: The batch size.
      shuffle: Boolean indicating whether to shuffle the data or not.
  
  Returns:
      The balanced data.
docstr_tok: ["Mix","model","data","to","account","for","class","imbalance",".","This","batching","strategy","puts","rare","classes","approximately","in","every","other","batch",",","by","repeating","them",".","Mimics","stratified","batching",",","but","also","takes","into","account","that","more","populated","classes","should","appear","more","often",".","Args",":","data",":","The","data",".","batch_size",":","The","batch","size",".","shuffle",":","Boolean","indicating","whether","to","shuffle","the","data","or","not",".","Returns",":","The","balanced","data","."]
code: def balanced_data(
      self, data: Data, batch_size: int, shuffle: bool
  ) -> Data:
      """Mix model data to account for class imbalance.
  
      This batching strategy puts rare classes approximately in every other batch,
      by repeating them. Mimics stratified batching, but also takes into account
      that more populated classes should appear more often.
  
      Args:
          data: The data.
          batch_size: The batch size.
          shuffle: Boolean indicating whether to shuffle the data or not.
  
      Returns:
          The balanced data.
      """
      self._check_label_key()
  
      # skip balancing if labels are token based
      if (
          self.label_key is None
          or self.label_sub_key is None
          or data[self.label_key][self.label_sub_key][0][0].size > 1
      ):
          return data
  
      label_ids = self._create_label_ids(
          data[self.label_key][self.label_sub_key][0]
      )
  
      unique_label_ids, counts_label_ids = np.unique(
          label_ids, return_counts=True, axis=0
      )
      num_label_ids = len(unique_label_ids)
  
      # group data points by their label
      # need to call every time, so that the data is shuffled inside each class
      data_by_label = self._split_by_label_ids(
          data, label_ids, unique_label_ids
      )
  
      # running index inside each data grouped by labels
      data_idx = [0] * num_label_ids
      # number of cycles each label was passed
      num_data_cycles = [0] * num_label_ids
      # if a label was skipped in current batch
      skipped = [False] * num_label_ids
  
      new_data: DefaultDict[
          Text, DefaultDict[Text, List[List[FeatureArray]]]
      ] = defaultdict(lambda: defaultdict(list))
  
      while min(num_data_cycles) == 0:
          if shuffle:
              indices_of_labels = np.random.permutation(num_label_ids)
          else:
              indices_of_labels = np.asarray(range(num_label_ids))
  
          for index in indices_of_labels:
              if num_data_cycles[index] > 0 and not skipped[index]:
                  skipped[index] = True
                  continue
  
              skipped[index] = False
  
              index_batch_size = (
                  int(
                      counts_label_ids[index]
                      / self.num_examples
                      * batch_size
                  )
                  + 1
              )
  
              for key, attribute_data in data_by_label[index].items():
                  for sub_key, features in attribute_data.items():
                      for i, f in enumerate(features):
                          if len(new_data[key][sub_key]) < i + 1:
                              new_data[key][sub_key].append([])
                          new_data[key][sub_key][i].append(
                              f[
                                  data_idx[index] : data_idx[index]
                                  + index_batch_size
                              ]
                          )
  
              data_idx[index] += index_batch_size
              if data_idx[index] >= counts_label_ids[index]:
                  num_data_cycles[index] += 1
                  data_idx[index] = 0
  
              if min(num_data_cycles) > 0:
                  break
  
      final_data: Data = defaultdict(lambda: defaultdict(list))
      for key, attribute_data in new_data.items():
          for sub_key, features in attribute_data.items():
              for f in features:
                  final_data[key][sub_key].append(
                      FeatureArray(
                          np.concatenate(f),
                          number_of_dimensions=f[
                              0
                          ].number_of_dimensions,
                      )
                  )
  
      return final_data
  
imports: import logging
  from typing import Optional, DefaultDict, Dict, Iterable, Text, List, Tuple, Any, Union, NamedTuple, ItemsView, overload, cast
  from collections import defaultdict, OrderedDict
  import numpy
  import scipy.sparse
  from sklearn.model_selection import train_test_split
label_desc: Use image node_id 24 for calling the RasaModelData obj's underlying member method code with example usage: obj.balanced_data(data, batch_size, shuffle) and returns: final_data, data