class_docstr: Generates trackers from training data.
class_docstr_tok: ["Generates","trackers","from","training","data","."]
docstr: Removes trackers that create equal featurizations
      for current story step.
  
  From multiple trackers that create equal featurizations
  we only need to keep one. Because as we continue processing
  events and story steps, all trackers that created the
  same featurization once will do so in the future (as we
  feed the same events to all trackers).
docstr_tok: ["Removes","trackers","that","create","equal","featurizations","for","current","story","step",".","From","multiple","trackers","that","create","equal","featurizations","we","only","need","to","keep","one",".","Because","as","we","continue","processing","events","and","story","steps",",","all","trackers","that","created","the","same","featurization","once","will","do","so","in","the","future","(","as","we","feed","the","same","events","to","all","trackers",")","."]
code: def _remove_duplicate_trackers(
      self, trackers: List[TrackerWithCachedStates]
  ) -> TrackersTuple:
      """Removes trackers that create equal featurizations
          for current story step.
  
      From multiple trackers that create equal featurizations
      we only need to keep one. Because as we continue processing
      events and story steps, all trackers that created the
      same featurization once will do so in the future (as we
      feed the same events to all trackers).
      """
      step_hashed_featurizations = set()
  
      # collected trackers that created different featurizations
      unique_trackers = []  # for current step
      end_trackers = []  # for all steps
  
      for tracker in trackers:
          states_for_hashing = tuple(
              tracker.past_states_for_hashing(self.domain)
          )
          hashed = hash(states_for_hashing)
  
          # only continue with trackers that created a
          # hashed_featurization we haven't observed
          if hashed not in step_hashed_featurizations:
              if self.config.unique_last_num_states:
                  last_states = states_for_hashing[
                      -self.config.unique_last_num_states :
                  ]
                  last_hashed = hash(last_states)
  
                  if last_hashed not in step_hashed_featurizations:
                      step_hashed_featurizations.add(last_hashed)
                      unique_trackers.append(tracker)
                  elif (
                      len(states_for_hashing) > len(last_states)
                      and hashed not in self.hashed_featurizations
                  ):
                      self.hashed_featurizations.add(hashed)
                      end_trackers.append(tracker)
              else:
                  unique_trackers.append(tracker)
  
              step_hashed_featurizations.add(hashed)
  
      return unique_trackers, end_trackers
  
imports: from collections import defaultdict, namedtuple, deque
  import copy
  import logging
  import random
  from contextlib import contextmanager
  from tqdm import tqdm
  from typing import Optional, List, Text, Set, Dict, Tuple, Deque, DefaultDict, Any, Iterable, Generator
  from rasa.shared.constants import DOCS_URL_STORIES
  from rasa.shared.core.constants import SHOULD_NOT_BE_SET
  from rasa.shared.core.domain import Domain, State
  from rasa.shared.core.events import ActionExecuted, UserUttered, ActionReverted, UserUtteranceReverted, Restarted, Event, SlotSet, ActiveLoop
  from rasa.shared.core.trackers import DialogueStateTracker, FrozenState
  from rasa.shared.core.slots import Slot
  from rasa.shared.core.training_data.structures import StoryGraph, STORY_START, StoryStep, RuleStep, GENERATED_CHECKPOINT_PREFIX
  from rasa.shared.utils.io import is_logging_disabled
  import rasa.shared.utils.io
label_desc: Use image node_id 14 for calling the TrainingDataGenerator obj's underlying member method code with example usage: obj._remove_duplicate_trackers(trackers) and returns: unique_trackers,  end_trackers